aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c73
-rw-r--r--sound/soc/cirrus/Kconfig (renamed from sound/soc/ep93xx/Kconfig)0
-rw-r--r--sound/soc/cirrus/Makefile (renamed from sound/soc/ep93xx/Makefile)0
-rw-r--r--sound/soc/cirrus/edb93xx.c (renamed from sound/soc/ep93xx/edb93xx.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c (renamed from sound/soc/ep93xx/ep93xx-ac97.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c (renamed from sound/soc/ep93xx/ep93xx-i2s.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.c (renamed from sound/soc/ep93xx/ep93xx-pcm.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.h (renamed from sound/soc/ep93xx/ep93xx-pcm.h)0
-rw-r--r--sound/soc/cirrus/simone.c (renamed from sound/soc/ep93xx/simone.c)0
-rw-r--r--sound/soc/cirrus/snappercl15.c (renamed from sound/soc/ep93xx/snappercl15.c)0
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ab8500-codec.c6
-rw-r--r--sound/soc/codecs/ad1836.c12
-rw-r--r--sound/soc/codecs/adau1373.c12
-rw-r--r--sound/soc/codecs/adau1701.c12
-rw-r--r--sound/soc/codecs/ak4671.c12
-rw-r--r--sound/soc/codecs/arizona.c66
-rw-r--r--sound/soc/codecs/arizona.h6
-rw-r--r--sound/soc/codecs/cs4270.c40
-rw-r--r--sound/soc/codecs/cs42l51.c19
-rw-r--r--sound/soc/codecs/cs42l52.c1
-rw-r--r--sound/soc/codecs/isabelle.c1
-rw-r--r--sound/soc/codecs/lm4857.c12
-rw-r--r--sound/soc/codecs/max98088.c18
-rw-r--r--sound/soc/codecs/max98095.c18
-rw-r--r--sound/soc/codecs/max9850.c12
-rw-r--r--sound/soc/codecs/max9877.c12
-rw-r--r--sound/soc/codecs/sta32x.c12
-rw-r--r--sound/soc/codecs/sta529.c2
-rw-r--r--sound/soc/codecs/tlv320aic26.c12
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c19
-rw-r--r--sound/soc/codecs/tlv320aic3x.c49
-rw-r--r--sound/soc/codecs/tlv320dac33.c19
-rw-r--r--sound/soc/codecs/tpa6130a2.c13
-rw-r--r--sound/soc/codecs/wm0010.c942
-rw-r--r--sound/soc/codecs/wm2000.c12
-rw-r--r--sound/soc/codecs/wm2200.c12
-rw-r--r--sound/soc/codecs/wm5102.c38
-rw-r--r--sound/soc/codecs/wm5110.c4
-rw-r--r--sound/soc/codecs/wm8770.c19
-rw-r--r--sound/soc/codecs/wm8903.c18
-rw-r--r--sound/soc/codecs/wm8940.c18
-rw-r--r--sound/soc/codecs/wm8955.c18
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c28
-rw-r--r--sound/soc/codecs/wm8960.c18
-rw-r--r--sound/soc/codecs/wm8961.c18
-rw-r--r--sound/soc/codecs/wm8971.c18
-rw-r--r--sound/soc/codecs/wm8974.c18
-rw-r--r--sound/soc/codecs/wm8978.c18
-rw-r--r--sound/soc/codecs/wm8991.c18
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994.c132
-rw-r--r--sound/soc/codecs/wm8994.h12
-rw-r--r--sound/soc/codecs/wm9090.c12
-rw-r--r--sound/soc/codecs/wm9712.c11
-rw-r--r--sound/soc/codecs/wm_hubs.c114
-rw-r--r--sound/soc/codecs/wm_hubs.h6
-rw-r--r--sound/soc/davinci/davinci-evm.c19
-rw-r--r--sound/soc/davinci/davinci-i2s.c13
-rw-r--r--sound/soc/davinci/davinci-mcasp.c174
-rw-r--r--sound/soc/davinci/davinci-mcasp.h6
-rw-r--r--sound/soc/davinci/davinci-pcm.c24
-rw-r--r--sound/soc/davinci/davinci-pcm.h6
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c2
-rw-r--r--sound/soc/davinci/davinci-vcif.c8
-rw-r--r--sound/soc/fsl/imx-ssi.c25
-rw-r--r--sound/soc/mid-x86/mfld_machine.c9
-rw-r--r--sound/soc/mid-x86/sst_dsp.h134
-rw-r--r--sound/soc/mid-x86/sst_platform.c204
-rw-r--r--sound/soc/mid-x86/sst_platform.h26
-rw-r--r--sound/soc/mxs/mxs-saif.c20
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c145
-rw-r--r--sound/soc/omap/omap-mcpdm.c52
-rw-r--r--sound/soc/samsung/Kconfig11
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/bells.c346
-rw-r--r--sound/soc/samsung/speyside.c42
-rw-r--r--sound/soc/soc-compress.c294
-rw-r--r--sound/soc/soc-core.c72
-rw-r--r--sound/soc/soc-jack.c6
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c3
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c2
85 files changed, 2856 insertions, 766 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index c5de0a84566f..5da8ca7aee05 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -9,6 +9,7 @@ menuconfig SND_SOC
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK if INPUT=y || INPUT=SND
10 select REGMAP_I2C if I2C 10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER 11 select REGMAP_SPI if SPI_MASTER
12 select SND_COMPRESS_OFFLOAD
12 ---help--- 13 ---help---
13 14
14 If you want ASoC support, you should say Y here and also to the 15 If you want ASoC support, you should say Y here and also to the
@@ -32,9 +33,9 @@ config SND_SOC_DMAENGINE_PCM
32source "sound/soc/atmel/Kconfig" 33source "sound/soc/atmel/Kconfig"
33source "sound/soc/au1x/Kconfig" 34source "sound/soc/au1x/Kconfig"
34source "sound/soc/blackfin/Kconfig" 35source "sound/soc/blackfin/Kconfig"
36source "sound/soc/cirrus/Kconfig"
35source "sound/soc/davinci/Kconfig" 37source "sound/soc/davinci/Kconfig"
36source "sound/soc/dwc/Kconfig" 38source "sound/soc/dwc/Kconfig"
37source "sound/soc/ep93xx/Kconfig"
38source "sound/soc/fsl/Kconfig" 39source "sound/soc/fsl/Kconfig"
39source "sound/soc/jz4740/Kconfig" 40source "sound/soc/jz4740/Kconfig"
40source "sound/soc/nuc900/Kconfig" 41source "sound/soc/nuc900/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 00a555a743b6..bcbf1d00aa85 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,5 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2snd-soc-core-objs += soc-pcm.o soc-io.o 2snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o
3 3
4snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o 4snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
5obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o 5obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
@@ -10,9 +10,9 @@ obj-$(CONFIG_SND_SOC) += generic/
10obj-$(CONFIG_SND_SOC) += atmel/ 10obj-$(CONFIG_SND_SOC) += atmel/
11obj-$(CONFIG_SND_SOC) += au1x/ 11obj-$(CONFIG_SND_SOC) += au1x/
12obj-$(CONFIG_SND_SOC) += blackfin/ 12obj-$(CONFIG_SND_SOC) += blackfin/
13obj-$(CONFIG_SND_SOC) += cirrus/
13obj-$(CONFIG_SND_SOC) += davinci/ 14obj-$(CONFIG_SND_SOC) += davinci/
14obj-$(CONFIG_SND_SOC) += dwc/ 15obj-$(CONFIG_SND_SOC) += dwc/
15obj-$(CONFIG_SND_SOC) += ep93xx/
16obj-$(CONFIG_SND_SOC) += fsl/ 16obj-$(CONFIG_SND_SOC) += fsl/
17obj-$(CONFIG_SND_SOC) += jz4740/ 17obj-$(CONFIG_SND_SOC) += jz4740/
18obj-$(CONFIG_SND_SOC) += mid-x86/ 18obj-$(CONFIG_SND_SOC) += mid-x86/
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index d542d4063771..16b9c9efd19a 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -59,62 +59,63 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
59#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ 59#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
60 SND_SOC_DAIFMT_CBM_CFM) 60 SND_SOC_DAIFMT_CBM_CFM)
61 61
62static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { 62static struct snd_soc_dai_link bf5xx_ad1836_dai = {
63 { 63 .name = "ad1836",
64 .name = "ad1836", 64 .stream_name = "AD1836",
65 .stream_name = "AD1836", 65 .codec_dai_name = "ad1836-hifi",
66 .cpu_dai_name = "bfin-tdm.0", 66 .platform_name = "bfin-tdm-pcm-audio",
67 .codec_dai_name = "ad1836-hifi", 67 .ops = &bf5xx_ad1836_ops,
68 .platform_name = "bfin-tdm-pcm-audio", 68 .dai_fmt = BF5XX_AD1836_DAIFMT,
69 .codec_name = "spi0.4",
70 .ops = &bf5xx_ad1836_ops,
71 .dai_fmt = BF5XX_AD1836_DAIFMT,
72 },
73 {
74 .name = "ad1836",
75 .stream_name = "AD1836",
76 .cpu_dai_name = "bfin-tdm.1",
77 .codec_dai_name = "ad1836-hifi",
78 .platform_name = "bfin-tdm-pcm-audio",
79 .codec_name = "spi0.4",
80 .ops = &bf5xx_ad1836_ops,
81 .dai_fmt = BF5XX_AD1836_DAIFMT,
82 },
83}; 69};
84 70
85static struct snd_soc_card bf5xx_ad1836 = { 71static struct snd_soc_card bf5xx_ad1836 = {
86 .name = "bfin-ad1836", 72 .name = "bfin-ad1836",
87 .owner = THIS_MODULE, 73 .owner = THIS_MODULE,
88 .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM], 74 .dai_link = &bf5xx_ad1836_dai,
89 .num_links = 1, 75 .num_links = 1,
90}; 76};
91 77
92static struct platform_device *bfxx_ad1836_snd_device; 78static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
93
94static int __init bf5xx_ad1836_init(void)
95{ 79{
80 struct snd_soc_card *card = &bf5xx_ad1836;
81 const char **link_name;
96 int ret; 82 int ret;
97 83
98 bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1); 84 link_name = pdev->dev.platform_data;
99 if (!bfxx_ad1836_snd_device) 85 if (!link_name) {
100 return -ENOMEM; 86 dev_err(&pdev->dev, "No platform data supplied\n");
87 return -EINVAL;
88 }
89 bf5xx_ad1836_dai.cpu_dai_name = link_name[0];
90 bf5xx_ad1836_dai.codec_name = link_name[1];
101 91
102 platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836); 92 card->dev = &pdev->dev;
103 ret = platform_device_add(bfxx_ad1836_snd_device); 93 platform_set_drvdata(pdev, card);
104 94
95 ret = snd_soc_register_card(card);
105 if (ret) 96 if (ret)
106 platform_device_put(bfxx_ad1836_snd_device); 97 dev_err(&pdev->dev, "Failed to register card\n");
107
108 return ret; 98 return ret;
109} 99}
110 100
111static void __exit bf5xx_ad1836_exit(void) 101static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev)
112{ 102{
113 platform_device_unregister(bfxx_ad1836_snd_device); 103 struct snd_soc_card *card = platform_get_drvdata(pdev);
104
105 snd_soc_unregister_card(card);
106 return 0;
114} 107}
115 108
116module_init(bf5xx_ad1836_init); 109static struct platform_driver bf5xx_ad1836_driver = {
117module_exit(bf5xx_ad1836_exit); 110 .driver = {
111 .name = "bfin-snd-ad1836",
112 .owner = THIS_MODULE,
113 .pm = &snd_soc_pm_ops,
114 },
115 .probe = bf5xx_ad1836_driver_probe,
116 .remove = __devexit_p(bf5xx_ad1836_driver_remove),
117};
118module_platform_driver(bf5xx_ad1836_driver);
118 119
119/* Module information */ 120/* Module information */
120MODULE_AUTHOR("Barry Song"); 121MODULE_AUTHOR("Barry Song");
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/cirrus/Kconfig
index 88143db7e753..88143db7e753 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/cirrus/Kconfig
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/cirrus/Makefile
index 5514146cbdf0..5514146cbdf0 100644
--- a/sound/soc/ep93xx/Makefile
+++ b/sound/soc/cirrus/Makefile
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index e01cb02abd3a..e01cb02abd3a 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index bdffab33e160..bdffab33e160 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 8df8f6dc474f..8df8f6dc474f 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
index 4eea98b42bc8..4eea98b42bc8 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/cirrus/ep93xx-pcm.c
diff --git a/sound/soc/ep93xx/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h
index 111e1121ecb8..111e1121ecb8 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.h
+++ b/sound/soc/cirrus/ep93xx-pcm.h
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/cirrus/simone.c
index dd997094eb30..dd997094eb30 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/cirrus/simone.c
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index a193cea3cf3c..a193cea3cf3c 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9f8e8594aeb9..3684255e5fba 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -70,6 +70,7 @@ config SND_SOC_ALL_CODECS
70 select SND_SOC_UDA134X 70 select SND_SOC_UDA134X
71 select SND_SOC_UDA1380 if I2C 71 select SND_SOC_UDA1380 if I2C
72 select SND_SOC_WL1273 if MFD_WL1273_CORE 72 select SND_SOC_WL1273 if MFD_WL1273_CORE
73 select SND_SOC_WM0010 if SPI_MASTER
73 select SND_SOC_WM1250_EV1 if I2C 74 select SND_SOC_WM1250_EV1 if I2C
74 select SND_SOC_WM2000 if I2C 75 select SND_SOC_WM2000 if I2C
75 select SND_SOC_WM2200 if I2C 76 select SND_SOC_WM2200 if I2C
@@ -326,6 +327,9 @@ config SND_SOC_UDA1380
326config SND_SOC_WL1273 327config SND_SOC_WL1273
327 tristate 328 tristate
328 329
330config SND_SOC_WM0010
331 tristate
332
329config SND_SOC_WM1250_EV1 333config SND_SOC_WM1250_EV1
330 tristate 334 tristate
331 335
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 34148bb59c68..ca508b251df7 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -61,6 +61,7 @@ snd-soc-twl6040-objs := twl6040.o
61snd-soc-uda134x-objs := uda134x.o 61snd-soc-uda134x-objs := uda134x.o
62snd-soc-uda1380-objs := uda1380.o 62snd-soc-uda1380-objs := uda1380.o
63snd-soc-wl1273-objs := wl1273.o 63snd-soc-wl1273-objs := wl1273.o
64snd-soc-wm0010-objs := wm0010.o
64snd-soc-wm1250-ev1-objs := wm1250-ev1.o 65snd-soc-wm1250-ev1-objs := wm1250-ev1.o
65snd-soc-wm2000-objs := wm2000.o 66snd-soc-wm2000-objs := wm2000.o
66snd-soc-wm2200-objs := wm2200.o 67snd-soc-wm2200-objs := wm2200.o
@@ -177,6 +178,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
177obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 178obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
178obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 179obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
179obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 180obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
181obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
180obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o 182obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
181obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 183obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
182obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o 184obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 23b40186f9b8..b7836503dc69 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2404,12 +2404,12 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
2404 2404
2405 dev_dbg(dev, "%s: Enter.\n", __func__); 2405 dev_dbg(dev, "%s: Enter.\n", __func__);
2406 2406
2407 /* Setup AB8500 according to board-settings */
2408 pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent);
2409
2410 /* Inform SoC Core that we have our own I/O arrangements. */ 2407 /* Inform SoC Core that we have our own I/O arrangements. */
2411 codec->control_data = (void *)true; 2408 codec->control_data = (void *)true;
2412 2409
2410 /* Setup AB8500 according to board-settings */
2411 pdata = dev_get_platdata(dev->parent);
2412
2413 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); 2413 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
2414 if (status < 0) { 2414 if (status < 0) {
2415 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); 2415 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c67b50d8b317..ae1eb51bc9da 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -379,17 +379,7 @@ static struct spi_driver ad1836_spi_driver = {
379 .id_table = ad1836_ids, 379 .id_table = ad1836_ids,
380}; 380};
381 381
382static int __init ad1836_init(void) 382module_spi_driver(ad1836_spi_driver);
383{
384 return spi_register_driver(&ad1836_spi_driver);
385}
386module_init(ad1836_init);
387
388static void __exit ad1836_exit(void)
389{
390 spi_unregister_driver(&ad1836_spi_driver);
391}
392module_exit(ad1836_exit);
393 383
394MODULE_DESCRIPTION("ASoC ad1836 driver"); 384MODULE_DESCRIPTION("ASoC ad1836 driver");
395MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 385MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 44f59064d8de..704544bfc90d 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1392,17 +1392,7 @@ static struct i2c_driver adau1373_i2c_driver = {
1392 .id_table = adau1373_i2c_id, 1392 .id_table = adau1373_i2c_id,
1393}; 1393};
1394 1394
1395static int __init adau1373_init(void) 1395module_i2c_driver(adau1373_i2c_driver);
1396{
1397 return i2c_add_driver(&adau1373_i2c_driver);
1398}
1399module_init(adau1373_init);
1400
1401static void __exit adau1373_exit(void)
1402{
1403 i2c_del_driver(&adau1373_i2c_driver);
1404}
1405module_exit(adau1373_exit);
1406 1396
1407MODULE_DESCRIPTION("ASoC ADAU1373 driver"); 1397MODULE_DESCRIPTION("ASoC ADAU1373 driver");
1408MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 1398MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 3d50fc8646b6..51f2f3cd8136 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -527,17 +527,7 @@ static struct i2c_driver adau1701_i2c_driver = {
527 .id_table = adau1701_i2c_id, 527 .id_table = adau1701_i2c_id,
528}; 528};
529 529
530static int __init adau1701_init(void) 530module_i2c_driver(adau1701_i2c_driver);
531{
532 return i2c_add_driver(&adau1701_i2c_driver);
533}
534module_init(adau1701_init);
535
536static void __exit adau1701_exit(void)
537{
538 i2c_del_driver(&adau1701_i2c_driver);
539}
540module_exit(adau1701_exit);
541 531
542MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver"); 532MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
543MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>"); 533MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>");
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 5fb7c2a80e6d..2b457976a7bf 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -696,17 +696,7 @@ static struct i2c_driver ak4671_i2c_driver = {
696 .id_table = ak4671_i2c_id, 696 .id_table = ak4671_i2c_id,
697}; 697};
698 698
699static int __init ak4671_modinit(void) 699module_i2c_driver(ak4671_i2c_driver);
700{
701 return i2c_add_driver(&ak4671_i2c_driver);
702}
703module_init(ak4671_modinit);
704
705static void __exit ak4671_exit(void)
706{
707 i2c_del_driver(&ak4671_i2c_driver);
708}
709module_exit(ak4671_exit);
710 700
711MODULE_DESCRIPTION("ASoC AK4671 codec driver"); 701MODULE_DESCRIPTION("ASoC AK4671 codec driver");
712MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 702MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 5c9cacaf2d52..5e96a0a1669c 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -229,6 +229,69 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
229} 229}
230EXPORT_SYMBOL_GPL(arizona_out_ev); 230EXPORT_SYMBOL_GPL(arizona_out_ev);
231 231
232static unsigned int arizona_sysclk_48k_rates[] = {
233 6144000,
234 12288000,
235 22579200,
236 49152000,
237};
238
239static unsigned int arizona_sysclk_44k1_rates[] = {
240 5644800,
241 11289600,
242 24576000,
243 45158400,
244};
245
246static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
247 unsigned int freq)
248{
249 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
250 unsigned int reg;
251 unsigned int *rates;
252 int ref, div, refclk;
253
254 switch (clk) {
255 case ARIZONA_CLK_OPCLK:
256 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
257 refclk = priv->sysclk;
258 break;
259 case ARIZONA_CLK_ASYNC_OPCLK:
260 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
261 refclk = priv->asyncclk;
262 break;
263 default:
264 return -EINVAL;
265 }
266
267 if (refclk % 8000)
268 rates = arizona_sysclk_44k1_rates;
269 else
270 rates = arizona_sysclk_48k_rates;
271
272 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
273 rates[ref] <= refclk; ref++) {
274 div = 1;
275 while (rates[ref] / div >= freq && div < 32) {
276 if (rates[ref] / div == freq) {
277 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
278 freq);
279 snd_soc_update_bits(codec, reg,
280 ARIZONA_OPCLK_DIV_MASK |
281 ARIZONA_OPCLK_SEL_MASK,
282 (div <<
283 ARIZONA_OPCLK_DIV_SHIFT) |
284 ref);
285 return 0;
286 }
287 div++;
288 }
289 }
290
291 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
292 return -EINVAL;
293}
294
232int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, 295int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
233 int source, unsigned int freq, int dir) 296 int source, unsigned int freq, int dir)
234{ 297{
@@ -252,6 +315,9 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
252 reg = ARIZONA_ASYNC_CLOCK_1; 315 reg = ARIZONA_ASYNC_CLOCK_1;
253 clk = &priv->asyncclk; 316 clk = &priv->asyncclk;
254 break; 317 break;
318 case ARIZONA_CLK_OPCLK:
319 case ARIZONA_CLK_ASYNC_OPCLK:
320 return arizona_set_opclk(codec, clk_id, freq);
255 default: 321 default:
256 return -EINVAL; 322 return -EINVAL;
257 } 323 }
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 59caca8865e8..eb66b52777c9 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -17,8 +17,10 @@
17 17
18#include <sound/soc.h> 18#include <sound/soc.h>
19 19
20#define ARIZONA_CLK_SYSCLK 1 20#define ARIZONA_CLK_SYSCLK 1
21#define ARIZONA_CLK_ASYNCCLK 2 21#define ARIZONA_CLK_ASYNCCLK 2
22#define ARIZONA_CLK_OPCLK 3
23#define ARIZONA_CLK_ASYNC_OPCLK 4
22 24
23#define ARIZONA_CLK_SRC_MCLK1 0x0 25#define ARIZONA_CLK_SRC_MCLK1 0x0
24#define ARIZONA_CLK_SRC_MCLK2 0x1 26#define ARIZONA_CLK_SRC_MCLK2 0x1
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 047917f0b8ae..44a176f74170 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -29,6 +29,8 @@
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32#include <linux/of_device.h>
33#include <linux/of_gpio.h>
32 34
33/* 35/*
34 * The codec isn't really big-endian or little-endian, since the I2S 36 * The codec isn't really big-endian or little-endian, since the I2S
@@ -639,6 +641,15 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
639 .reg_cache_default = cs4270_default_reg_cache, 641 .reg_cache_default = cs4270_default_reg_cache,
640}; 642};
641 643
644/*
645 * cs4270_of_match - the device tree bindings
646 */
647static const struct of_device_id cs4270_of_match[] = {
648 { .compatible = "cirrus,cs4270", },
649 { }
650};
651MODULE_DEVICE_TABLE(of, cs4270_of_match);
652
642/** 653/**
643 * cs4270_i2c_probe - initialize the I2C interface of the CS4270 654 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
644 * @i2c_client: the I2C client object 655 * @i2c_client: the I2C client object
@@ -650,9 +661,25 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
650static int cs4270_i2c_probe(struct i2c_client *i2c_client, 661static int cs4270_i2c_probe(struct i2c_client *i2c_client,
651 const struct i2c_device_id *id) 662 const struct i2c_device_id *id)
652{ 663{
664 struct device_node *np = i2c_client->dev.of_node;
653 struct cs4270_private *cs4270; 665 struct cs4270_private *cs4270;
654 int ret; 666 int ret;
655 667
668 /* See if we have a way to bring the codec out of reset */
669 if (np) {
670 enum of_gpio_flags flags;
671 int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
672
673 if (gpio_is_valid(gpio)) {
674 ret = devm_gpio_request_one(&i2c_client->dev, gpio,
675 flags & OF_GPIO_ACTIVE_LOW ?
676 GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
677 "cs4270 reset");
678 if (ret < 0)
679 return ret;
680 }
681 }
682
656 /* Verify that we have a CS4270 */ 683 /* Verify that we have a CS4270 */
657 684
658 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 685 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -718,23 +745,14 @@ static struct i2c_driver cs4270_i2c_driver = {
718 .driver = { 745 .driver = {
719 .name = "cs4270", 746 .name = "cs4270",
720 .owner = THIS_MODULE, 747 .owner = THIS_MODULE,
748 .of_match_table = cs4270_of_match,
721 }, 749 },
722 .id_table = cs4270_id, 750 .id_table = cs4270_id,
723 .probe = cs4270_i2c_probe, 751 .probe = cs4270_i2c_probe,
724 .remove = cs4270_i2c_remove, 752 .remove = cs4270_i2c_remove,
725}; 753};
726 754
727static int __init cs4270_init(void) 755module_i2c_driver(cs4270_i2c_driver);
728{
729 return i2c_add_driver(&cs4270_i2c_driver);
730}
731module_init(cs4270_init);
732
733static void __exit cs4270_exit(void)
734{
735 i2c_del_driver(&cs4270_i2c_driver);
736}
737module_exit(cs4270_exit);
738 756
739MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 757MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
740MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); 758MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 091d0193f507..1e0fa3b5f79a 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -614,24 +614,7 @@ static struct i2c_driver cs42l51_i2c_driver = {
614 .remove = cs42l51_i2c_remove, 614 .remove = cs42l51_i2c_remove,
615}; 615};
616 616
617static int __init cs42l51_init(void) 617module_i2c_driver(cs42l51_i2c_driver);
618{
619 int ret;
620
621 ret = i2c_add_driver(&cs42l51_i2c_driver);
622 if (ret != 0) {
623 printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
624 return ret;
625 }
626 return 0;
627}
628module_init(cs42l51_init);
629
630static void __exit cs42l51_exit(void)
631{
632 i2c_del_driver(&cs42l51_i2c_driver);
633}
634module_exit(cs42l51_exit);
635 618
636MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 619MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
637MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); 620MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 628daf6a1d97..61599298fb26 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -24,7 +24,6 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/slab.h>
28#include <sound/core.h> 27#include <sound/core.h>
29#include <sound/pcm.h> 28#include <sound/pcm.h>
30#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 5d8f39e32978..1bf55602c9eb 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -13,7 +13,6 @@
13 */ 13 */
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index ba4fafb93e56..81a328c78838 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -250,17 +250,7 @@ static struct i2c_driver lm4857_i2c_driver = {
250 .id_table = lm4857_i2c_id, 250 .id_table = lm4857_i2c_id,
251}; 251};
252 252
253static int __init lm4857_init(void) 253module_i2c_driver(lm4857_i2c_driver);
254{
255 return i2c_add_driver(&lm4857_i2c_driver);
256}
257module_init(lm4857_init);
258
259static void __exit lm4857_exit(void)
260{
261 i2c_del_driver(&lm4857_i2c_driver);
262}
263module_exit(lm4857_exit);
264 254
265MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 255MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
266MODULE_DESCRIPTION("LM4857 amplifier driver"); 256MODULE_DESCRIPTION("LM4857 amplifier driver");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index af7324b79dd0..3264a5169306 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -2107,23 +2107,7 @@ static struct i2c_driver max98088_i2c_driver = {
2107 .id_table = max98088_i2c_id, 2107 .id_table = max98088_i2c_id,
2108}; 2108};
2109 2109
2110static int __init max98088_init(void) 2110module_i2c_driver(max98088_i2c_driver);
2111{
2112 int ret;
2113
2114 ret = i2c_add_driver(&max98088_i2c_driver);
2115 if (ret)
2116 pr_err("Failed to register max98088 I2C driver: %d\n", ret);
2117
2118 return ret;
2119}
2120module_init(max98088_init);
2121
2122static void __exit max98088_exit(void)
2123{
2124 i2c_del_driver(&max98088_i2c_driver);
2125}
2126module_exit(max98088_exit);
2127 2111
2128MODULE_DESCRIPTION("ALSA SoC MAX98088 driver"); 2112MODULE_DESCRIPTION("ALSA SoC MAX98088 driver");
2129MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin"); 2113MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin");
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 7cd508e16a5c..38d43c59d3f4 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2533,23 +2533,7 @@ static struct i2c_driver max98095_i2c_driver = {
2533 .id_table = max98095_i2c_id, 2533 .id_table = max98095_i2c_id,
2534}; 2534};
2535 2535
2536static int __init max98095_init(void) 2536module_i2c_driver(max98095_i2c_driver);
2537{
2538 int ret;
2539
2540 ret = i2c_add_driver(&max98095_i2c_driver);
2541 if (ret)
2542 pr_err("Failed to register max98095 I2C driver: %d\n", ret);
2543
2544 return ret;
2545}
2546module_init(max98095_init);
2547
2548static void __exit max98095_exit(void)
2549{
2550 i2c_del_driver(&max98095_i2c_driver);
2551}
2552module_exit(max98095_exit);
2553 2537
2554MODULE_DESCRIPTION("ALSA SoC MAX98095 driver"); 2538MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
2555MODULE_AUTHOR("Peter Hsiang"); 2539MODULE_AUTHOR("Peter Hsiang");
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index a1913091f56c..efe535c37b39 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -369,17 +369,7 @@ static struct i2c_driver max9850_i2c_driver = {
369 .id_table = max9850_i2c_id, 369 .id_table = max9850_i2c_id,
370}; 370};
371 371
372static int __init max9850_init(void) 372module_i2c_driver(max9850_i2c_driver);
373{
374 return i2c_add_driver(&max9850_i2c_driver);
375}
376module_init(max9850_init);
377
378static void __exit max9850_exit(void)
379{
380 i2c_del_driver(&max9850_i2c_driver);
381}
382module_exit(max9850_exit);
383 373
384MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>"); 374MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
385MODULE_DESCRIPTION("ASoC MAX9850 codec driver"); 375MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index 3a2ba3d8fd6d..d15e5943c85e 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -291,17 +291,7 @@ static struct i2c_driver max9877_i2c_driver = {
291 .id_table = max9877_i2c_id, 291 .id_table = max9877_i2c_id,
292}; 292};
293 293
294static int __init max9877_init(void) 294module_i2c_driver(max9877_i2c_driver);
295{
296 return i2c_add_driver(&max9877_i2c_driver);
297}
298module_init(max9877_init);
299
300static void __exit max9877_exit(void)
301{
302 i2c_del_driver(&max9877_i2c_driver);
303}
304module_exit(max9877_exit);
305 295
306MODULE_DESCRIPTION("ASoC MAX9877 amp driver"); 296MODULE_DESCRIPTION("ASoC MAX9877 amp driver");
307MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 297MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 8d717f4b5a87..51b7313a4c14 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -1006,17 +1006,7 @@ static struct i2c_driver sta32x_i2c_driver = {
1006 .id_table = sta32x_i2c_id, 1006 .id_table = sta32x_i2c_id,
1007}; 1007};
1008 1008
1009static int __init sta32x_init(void) 1009module_i2c_driver(sta32x_i2c_driver);
1010{
1011 return i2c_add_driver(&sta32x_i2c_driver);
1012}
1013module_init(sta32x_init);
1014
1015static void __exit sta32x_exit(void)
1016{
1017 i2c_del_driver(&sta32x_i2c_driver);
1018}
1019module_exit(sta32x_exit);
1020 1010
1021MODULE_DESCRIPTION("ASoC STA32X driver"); 1011MODULE_DESCRIPTION("ASoC STA32X driver");
1022MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>"); 1012MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 0c225cd569d2..9e3144862386 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -358,7 +358,7 @@ static int sta529_resume(struct snd_soc_codec *codec)
358 return 0; 358 return 0;
359} 359}
360 360
361struct snd_soc_codec_driver sta529_codec_driver = { 361static const struct snd_soc_codec_driver sta529_codec_driver = {
362 .probe = sta529_probe, 362 .probe = sta529_probe,
363 .remove = sta529_remove, 363 .remove = sta529_remove,
364 .set_bias_level = sta529_set_bias_level, 364 .set_bias_level = sta529_set_bias_level,
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 85944e953578..b1f6982c7c9c 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -444,14 +444,4 @@ static struct spi_driver aic26_spi = {
444 .remove = aic26_spi_remove, 444 .remove = aic26_spi_remove,
445}; 445};
446 446
447static int __init aic26_init(void) 447module_spi_driver(aic26_spi);
448{
449 return spi_register_driver(&aic26_spi);
450}
451module_init(aic26_init);
452
453static void __exit aic26_exit(void)
454{
455 spi_unregister_driver(&aic26_spi);
456}
457module_exit(aic26_exit);
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index b0a73d37ed52..f230292ba96b 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -746,24 +746,7 @@ static struct i2c_driver aic32x4_i2c_driver = {
746 .id_table = aic32x4_i2c_id, 746 .id_table = aic32x4_i2c_id,
747}; 747};
748 748
749static int __init aic32x4_modinit(void) 749module_i2c_driver(aic32x4_i2c_driver);
750{
751 int ret = 0;
752
753 ret = i2c_add_driver(&aic32x4_i2c_driver);
754 if (ret != 0) {
755 printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
756 ret);
757 }
758 return ret;
759}
760module_init(aic32x4_modinit);
761
762static void __exit aic32x4_exit(void)
763{
764 i2c_del_driver(&aic32x4_i2c_driver);
765}
766module_exit(aic32x4_exit);
767 750
768MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver"); 751MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
769MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); 752MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index dc78f5a4bcbf..5708a973a776 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -40,6 +40,7 @@
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/gpio.h> 41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h> 42#include <linux/regulator/consumer.h>
43#include <linux/of_gpio.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/pcm.h> 46#include <sound/pcm.h>
@@ -1457,6 +1458,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1457{ 1458{
1458 struct aic3x_pdata *pdata = i2c->dev.platform_data; 1459 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1459 struct aic3x_priv *aic3x; 1460 struct aic3x_priv *aic3x;
1461 struct aic3x_setup_data *ai3x_setup;
1462 struct device_node *np = i2c->dev.of_node;
1460 int ret; 1463 int ret;
1461 1464
1462 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); 1465 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1471,6 +1474,25 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1471 if (pdata) { 1474 if (pdata) {
1472 aic3x->gpio_reset = pdata->gpio_reset; 1475 aic3x->gpio_reset = pdata->gpio_reset;
1473 aic3x->setup = pdata->setup; 1476 aic3x->setup = pdata->setup;
1477 } else if (np) {
1478 ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup),
1479 GFP_KERNEL);
1480 if (ai3x_setup == NULL) {
1481 dev_err(&i2c->dev, "failed to create private data\n");
1482 return -ENOMEM;
1483 }
1484
1485 ret = of_get_named_gpio(np, "gpio-reset", 0);
1486 if (ret >= 0)
1487 aic3x->gpio_reset = ret;
1488 else
1489 aic3x->gpio_reset = -1;
1490
1491 if (of_property_read_u32_array(np, "ai3x-gpio-func",
1492 ai3x_setup->gpio_func, 2) >= 0) {
1493 aic3x->setup = ai3x_setup;
1494 }
1495
1474 } else { 1496 } else {
1475 aic3x->gpio_reset = -1; 1497 aic3x->gpio_reset = -1;
1476 } 1498 }
@@ -1488,34 +1510,27 @@ static int aic3x_i2c_remove(struct i2c_client *client)
1488 return 0; 1510 return 0;
1489} 1511}
1490 1512
1513#if defined(CONFIG_OF)
1514static const struct of_device_id tlv320aic3x_of_match[] = {
1515 { .compatible = "ti,tlv320aic3x", },
1516 {},
1517};
1518MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);
1519#endif
1520
1491/* machine i2c codec control layer */ 1521/* machine i2c codec control layer */
1492static struct i2c_driver aic3x_i2c_driver = { 1522static struct i2c_driver aic3x_i2c_driver = {
1493 .driver = { 1523 .driver = {
1494 .name = "tlv320aic3x-codec", 1524 .name = "tlv320aic3x-codec",
1495 .owner = THIS_MODULE, 1525 .owner = THIS_MODULE,
1526 .of_match_table = of_match_ptr(tlv320aic3x_of_match),
1496 }, 1527 },
1497 .probe = aic3x_i2c_probe, 1528 .probe = aic3x_i2c_probe,
1498 .remove = aic3x_i2c_remove, 1529 .remove = aic3x_i2c_remove,
1499 .id_table = aic3x_i2c_id, 1530 .id_table = aic3x_i2c_id,
1500}; 1531};
1501 1532
1502static int __init aic3x_modinit(void) 1533module_i2c_driver(aic3x_i2c_driver);
1503{
1504 int ret = 0;
1505 ret = i2c_add_driver(&aic3x_i2c_driver);
1506 if (ret != 0) {
1507 printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
1508 ret);
1509 }
1510 return ret;
1511}
1512module_init(aic3x_modinit);
1513
1514static void __exit aic3x_exit(void)
1515{
1516 i2c_del_driver(&aic3x_i2c_driver);
1517}
1518module_exit(aic3x_exit);
1519 1534
1520MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); 1535MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
1521MODULE_AUTHOR("Vladimir Barinov"); 1536MODULE_AUTHOR("Vladimir Barinov");
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 0dd41077ab79..d2e16c5d7d1f 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1621,24 +1621,7 @@ static struct i2c_driver tlv320dac33_i2c_driver = {
1621 .id_table = tlv320dac33_i2c_id, 1621 .id_table = tlv320dac33_i2c_id,
1622}; 1622};
1623 1623
1624static int __init dac33_module_init(void) 1624module_i2c_driver(tlv320dac33_i2c_driver);
1625{
1626 int r;
1627 r = i2c_add_driver(&tlv320dac33_i2c_driver);
1628 if (r < 0) {
1629 printk(KERN_ERR "DAC33: driver registration failed\n");
1630 return r;
1631 }
1632 return 0;
1633}
1634module_init(dac33_module_init);
1635
1636static void __exit dac33_module_exit(void)
1637{
1638 i2c_del_driver(&tlv320dac33_i2c_driver);
1639}
1640module_exit(dac33_module_exit);
1641
1642 1625
1643MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); 1626MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1644MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 1627MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 6fe4aa3ac544..565ff39ad3a3 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -487,19 +487,8 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
487 .id_table = tpa6130a2_id, 487 .id_table = tpa6130a2_id,
488}; 488};
489 489
490static int __init tpa6130a2_init(void) 490module_i2c_driver(tpa6130a2_i2c_driver);
491{
492 return i2c_add_driver(&tpa6130a2_i2c_driver);
493}
494
495static void __exit tpa6130a2_exit(void)
496{
497 i2c_del_driver(&tpa6130a2_i2c_driver);
498}
499 491
500MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 492MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
501MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); 493MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
502MODULE_LICENSE("GPL"); 494MODULE_LICENSE("GPL");
503
504module_init(tpa6130a2_init);
505module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
new file mode 100644
index 000000000000..5f99148447e1
--- /dev/null
+++ b/sound/soc/codecs/wm0010.c
@@ -0,0 +1,942 @@
1/*
2 * wm0010.c -- WM0010 DSP Driver
3 *
4 * Copyright 2012 Wolfson Microelectronics PLC.
5 *
6 * Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
8 * Scott Ling <sl@opensource.wolfsonmicro.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/irqreturn.h>
18#include <linux/init.h>
19#include <linux/spi/spi.h>
20#include <linux/firmware.h>
21#include <linux/delay.h>
22#include <linux/fs.h>
23#include <linux/miscdevice.h>
24#include <linux/gpio.h>
25#include <linux/regulator/consumer.h>
26#include <linux/mutex.h>
27#include <linux/workqueue.h>
28
29#include <sound/soc.h>
30#include <sound/wm0010.h>
31
32#define DEVICE_ID_WM0010 10
33
34enum dfw_cmd {
35 DFW_CMD_FUSE = 0x01,
36 DFW_CMD_CODE_HDR,
37 DFW_CMD_CODE_DATA,
38 DFW_CMD_PLL,
39 DFW_CMD_INFO = 0xff
40};
41
42struct dfw_binrec {
43 u8 command;
44 u32 length:24;
45 u32 address;
46 uint8_t data[0];
47} __packed;
48
49struct dfw_pllrec {
50 u8 command;
51 u32 length:24;
52 u32 address;
53 u32 clkctrl1;
54 u32 clkctrl2;
55 u32 clkctrl3;
56 u32 ldetctrl;
57 u32 uart_div;
58 u32 spi_div;
59} __packed;
60
61static struct pll_clock_map {
62 int max_sysclk;
63 int max_pll_spi_speed;
64 u32 pll_clkctrl1;
65} pll_clock_map[] = { /* Dividers */
66 { 22000000, 26000000, 0x00201f11 }, /* 2,32,2 */
67 { 18000000, 26000000, 0x00203f21 }, /* 2,64,4 */
68 { 14000000, 26000000, 0x00202620 }, /* 1,39,4 */
69 { 10000000, 22000000, 0x00203120 }, /* 1,50,4 */
70 { 6500000, 22000000, 0x00204520 }, /* 1,70,4 */
71 { 5500000, 22000000, 0x00103f10 }, /* 1,64,2 */
72};
73
74enum wm0010_state {
75 WM0010_POWER_OFF,
76 WM0010_OUT_OF_RESET,
77 WM0010_BOOTROM,
78 WM0010_STAGE2,
79 WM0010_FIRMWARE,
80};
81
82struct wm0010_priv {
83 struct snd_soc_codec *codec;
84
85 struct mutex lock;
86 struct device *dev;
87
88 struct wm0010_pdata pdata;
89
90 int gpio_reset;
91 int gpio_reset_value;
92
93 struct regulator_bulk_data core_supplies[2];
94 struct regulator *dbvdd;
95
96 int sysclk;
97
98 enum wm0010_state state;
99 bool boot_failed;
100 int boot_done;
101 bool ready;
102 bool pll_running;
103 int max_spi_freq;
104 int board_max_spi_speed;
105 u32 pll_clkctrl1;
106
107 spinlock_t irq_lock;
108 int irq;
109
110 struct completion boot_completion;
111};
112
113struct wm0010_spi_msg {
114 struct spi_message m;
115 struct spi_transfer t;
116 u8 *tx_buf;
117 u8 *rx_buf;
118 size_t len;
119};
120
121static const struct snd_soc_dapm_widget wm0010_dapm_widgets[] = {
122SND_SOC_DAPM_SUPPLY("CLKIN", SND_SOC_NOPM, 0, 0, NULL, 0),
123};
124
125static const struct snd_soc_dapm_route wm0010_dapm_routes[] = {
126 { "SDI2 Capture", NULL, "SDI1 Playback" },
127 { "SDI1 Capture", NULL, "SDI2 Playback" },
128
129 { "SDI1 Capture", NULL, "CLKIN" },
130 { "SDI2 Capture", NULL, "CLKIN" },
131 { "SDI1 Playback", NULL, "CLKIN" },
132 { "SDI2 Playback", NULL, "CLKIN" },
133};
134
135static const char *wm0010_state_to_str(enum wm0010_state state)
136{
137 const char *state_to_str[] = {
138 "Power off",
139 "Out of reset",
140 "Boot ROM",
141 "Stage2",
142 "Firmware"
143 };
144
145 if (state < 0 || state >= ARRAY_SIZE(state_to_str))
146 return "null";
147 return state_to_str[state];
148}
149
150/* Called with wm0010->lock held */
151static void wm0010_halt(struct snd_soc_codec *codec)
152{
153 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
154 unsigned long flags;
155 enum wm0010_state state;
156
157 /* Fetch the wm0010 state */
158 spin_lock_irqsave(&wm0010->irq_lock, flags);
159 state = wm0010->state;
160 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
161
162 switch (state) {
163 case WM0010_POWER_OFF:
164 /* If there's nothing to do, bail out */
165 return;
166 case WM0010_OUT_OF_RESET:
167 case WM0010_BOOTROM:
168 case WM0010_STAGE2:
169 case WM0010_FIRMWARE:
170 /* Remember to put chip back into reset */
171 gpio_set_value(wm0010->gpio_reset, wm0010->gpio_reset_value);
172 /* Disable the regulators */
173 regulator_disable(wm0010->dbvdd);
174 regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
175 wm0010->core_supplies);
176 break;
177 }
178
179 spin_lock_irqsave(&wm0010->irq_lock, flags);
180 wm0010->state = WM0010_POWER_OFF;
181 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
182}
183
184struct wm0010_boot_xfer {
185 struct list_head list;
186 struct snd_soc_codec *codec;
187 struct completion *done;
188 struct spi_message m;
189 struct spi_transfer t;
190};
191
192/* Called with wm0010->lock held */
193static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010)
194{
195 enum wm0010_state state;
196 unsigned long flags;
197
198 spin_lock_irqsave(&wm0010->irq_lock, flags);
199 state = wm0010->state;
200 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
201
202 dev_err(wm0010->dev, "Failed to transition from `%s' state to `%s' state\n",
203 wm0010_state_to_str(state), wm0010_state_to_str(state + 1));
204
205 wm0010->boot_failed = true;
206}
207
208static void wm0010_boot_xfer_complete(void *data)
209{
210 struct wm0010_boot_xfer *xfer = data;
211 struct snd_soc_codec *codec = xfer->codec;
212 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
213 u32 *out32 = xfer->t.rx_buf;
214 int i;
215
216 if (xfer->m.status != 0) {
217 dev_err(codec->dev, "SPI transfer failed: %d\n",
218 xfer->m.status);
219 wm0010_mark_boot_failure(wm0010);
220 if (xfer->done)
221 complete(xfer->done);
222 return;
223 }
224
225 for (i = 0; i < xfer->t.len / 4; i++) {
226 dev_dbg(codec->dev, "%d: %04x\n", i, out32[i]);
227
228 switch (be32_to_cpu(out32[i])) {
229 case 0xe0e0e0e0:
230 dev_err(codec->dev,
231 "%d: ROM error reported in stage 2\n", i);
232 wm0010_mark_boot_failure(wm0010);
233 break;
234
235 case 0x55555555:
236 if (wm0010->boot_done == 0)
237 break;
238 dev_err(codec->dev,
239 "%d: ROM bootloader running in stage 2\n", i);
240 wm0010_mark_boot_failure(wm0010);
241 break;
242
243 case 0x0fed0000:
244 dev_dbg(codec->dev, "Stage2 loader running\n");
245 break;
246
247 case 0x0fed0007:
248 dev_dbg(codec->dev, "CODE_HDR packet received\n");
249 break;
250
251 case 0x0fed0008:
252 dev_dbg(codec->dev, "CODE_DATA packet received\n");
253 break;
254
255 case 0x0fed0009:
256 dev_dbg(codec->dev, "Download complete\n");
257 break;
258
259 case 0x0fed000c:
260 dev_dbg(codec->dev, "Application start\n");
261 break;
262
263 case 0x0fed000e:
264 dev_dbg(codec->dev, "PLL packet received\n");
265 wm0010->pll_running = true;
266 break;
267
268 case 0x0fed0025:
269 dev_err(codec->dev, "Device reports image too long\n");
270 wm0010_mark_boot_failure(wm0010);
271 break;
272
273 case 0x0fed002c:
274 dev_err(codec->dev, "Device reports bad SPI packet\n");
275 wm0010_mark_boot_failure(wm0010);
276 break;
277
278 case 0x0fed0031:
279 dev_err(codec->dev, "Device reports SPI read overflow\n");
280 wm0010_mark_boot_failure(wm0010);
281 break;
282
283 case 0x0fed0032:
284 dev_err(codec->dev, "Device reports SPI underclock\n");
285 wm0010_mark_boot_failure(wm0010);
286 break;
287
288 case 0x0fed0033:
289 dev_err(codec->dev, "Device reports bad header packet\n");
290 wm0010_mark_boot_failure(wm0010);
291 break;
292
293 case 0x0fed0034:
294 dev_err(codec->dev, "Device reports invalid packet type\n");
295 wm0010_mark_boot_failure(wm0010);
296 break;
297
298 case 0x0fed0035:
299 dev_err(codec->dev, "Device reports data before header error\n");
300 wm0010_mark_boot_failure(wm0010);
301 break;
302
303 case 0x0fed0038:
304 dev_err(codec->dev, "Device reports invalid PLL packet\n");
305 break;
306
307 case 0x0fed003a:
308 dev_err(codec->dev, "Device reports packet alignment error\n");
309 wm0010_mark_boot_failure(wm0010);
310 break;
311
312 default:
313 dev_err(codec->dev, "Unrecognised return 0x%x\n",
314 be32_to_cpu(out32[i]));
315 wm0010_mark_boot_failure(wm0010);
316 break;
317 }
318
319 if (wm0010->boot_failed)
320 break;
321 }
322
323 wm0010->boot_done++;
324 if (xfer->done)
325 complete(xfer->done);
326}
327
328static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
329{
330 int i;
331
332 for (i = 0; i < len / 8; i++)
333 data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
334}
335
336static int wm0010_boot(struct snd_soc_codec *codec)
337{
338 struct spi_device *spi = to_spi_device(codec->dev);
339 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
340 unsigned long flags;
341 struct list_head xfer_list;
342 struct wm0010_boot_xfer *xfer;
343 int ret;
344 struct completion done;
345 const struct firmware *fw;
346 const struct dfw_binrec *rec;
347 struct spi_message m;
348 struct spi_transfer t;
349 struct dfw_pllrec pll_rec;
350 u32 *img, *p;
351 u64 *img_swap;
352 u8 *out;
353 u32 len, offset;
354 int i;
355
356 spin_lock_irqsave(&wm0010->irq_lock, flags);
357 if (wm0010->state != WM0010_POWER_OFF)
358 dev_warn(wm0010->dev, "DSP already powered up!\n");
359 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
360
361 if (wm0010->sysclk > 26000000) {
362 dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
363 ret = -ECANCELED;
364 goto err;
365 }
366
367 INIT_LIST_HEAD(&xfer_list);
368
369 mutex_lock(&wm0010->lock);
370 wm0010->pll_running = false;
371
372 dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
373
374 ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
375 wm0010->core_supplies);
376 if (ret != 0) {
377 dev_err(&spi->dev, "Failed to enable core supplies: %d\n",
378 ret);
379 mutex_unlock(&wm0010->lock);
380 goto err;
381 }
382
383 ret = regulator_enable(wm0010->dbvdd);
384 if (ret != 0) {
385 dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret);
386 goto err_core;
387 }
388
389 /* Release reset */
390 gpio_set_value(wm0010->gpio_reset, !wm0010->gpio_reset_value);
391 spin_lock_irqsave(&wm0010->irq_lock, flags);
392 wm0010->state = WM0010_OUT_OF_RESET;
393 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
394
395 /* First the bootloader */
396 ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
397 if (ret != 0) {
398 dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
399 ret);
400 goto abort;
401 }
402
403 if (!wait_for_completion_timeout(&wm0010->boot_completion,
404 msecs_to_jiffies(10)))
405 dev_err(codec->dev, "Failed to get interrupt from DSP\n");
406
407 spin_lock_irqsave(&wm0010->irq_lock, flags);
408 wm0010->state = WM0010_BOOTROM;
409 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
410
411 dev_dbg(codec->dev, "Downloading %d byte stage 2 loader\n", fw->size);
412
413 /* Copy to local buffer first as vmalloc causes problems for dma */
414 img = kzalloc(fw->size, GFP_KERNEL);
415 if (!img) {
416 dev_err(codec->dev, "Failed to allocate image buffer\n");
417 goto abort;
418 }
419
420 out = kzalloc(fw->size, GFP_KERNEL);
421 if (!out) {
422 dev_err(codec->dev, "Failed to allocate output buffer\n");
423 goto abort;
424 }
425
426 memcpy(img, &fw->data[0], fw->size);
427
428 spi_message_init(&m);
429 memset(&t, 0, sizeof(t));
430 t.rx_buf = out;
431 t.tx_buf = img;
432 t.len = fw->size;
433 t.bits_per_word = 8;
434 t.speed_hz = wm0010->sysclk / 10;
435 spi_message_add_tail(&t, &m);
436
437 dev_dbg(codec->dev, "Starting initial download at %dHz\n",
438 t.speed_hz);
439
440 ret = spi_sync(spi, &m);
441 if (ret != 0) {
442 dev_err(codec->dev, "Initial download failed: %d\n", ret);
443 goto abort;
444 }
445
446 /* Look for errors from the boot ROM */
447 for (i = 0; i < fw->size; i++) {
448 if (out[i] != 0x55) {
449 ret = -EBUSY;
450 dev_err(codec->dev, "Boot ROM error: %x in %d\n",
451 out[i], i);
452 wm0010_mark_boot_failure(wm0010);
453 goto abort;
454 }
455 }
456
457 release_firmware(fw);
458 kfree(img);
459 kfree(out);
460
461 if (!wait_for_completion_timeout(&wm0010->boot_completion,
462 msecs_to_jiffies(10)))
463 dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
464
465 spin_lock_irqsave(&wm0010->irq_lock, flags);
466 wm0010->state = WM0010_STAGE2;
467 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
468
469 /* Only initialise PLL if max_spi_freq initialised */
470 if (wm0010->max_spi_freq) {
471
472 /* Initialise a PLL record */
473 memset(&pll_rec, 0, sizeof(pll_rec));
474 pll_rec.command = DFW_CMD_PLL;
475 pll_rec.length = (sizeof(pll_rec) - 8);
476
477 /* On wm0010 only the CLKCTRL1 value is used */
478 pll_rec.clkctrl1 = wm0010->pll_clkctrl1;
479
480 len = pll_rec.length + 8;
481 out = kzalloc(len, GFP_KERNEL);
482 if (!out) {
483 dev_err(codec->dev,
484 "Failed to allocate RX buffer\n");
485 goto abort;
486 }
487
488 img_swap = kzalloc(len, GFP_KERNEL);
489 if (!img_swap) {
490 dev_err(codec->dev,
491 "Failed to allocate image buffer\n");
492 goto abort;
493 }
494
495 /* We need to re-order for 0010 */
496 byte_swap_64((u64 *)&pll_rec, img_swap, len);
497
498 spi_message_init(&m);
499 memset(&t, 0, sizeof(t));
500 t.rx_buf = out;
501 t.tx_buf = img_swap;
502 t.len = len;
503 t.bits_per_word = 8;
504 t.speed_hz = wm0010->sysclk / 6;
505 spi_message_add_tail(&t, &m);
506
507 ret = spi_sync(spi, &m);
508 if (ret != 0) {
509 dev_err(codec->dev, "First PLL write failed: %d\n", ret);
510 goto abort;
511 }
512
513 /* Use a second send of the message to get the return status */
514 ret = spi_sync(spi, &m);
515 if (ret != 0) {
516 dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
517 goto abort;
518 }
519
520 p = (u32 *)out;
521
522 /* Look for PLL active code from the DSP */
523 for (i = 0; i < len / 4; i++) {
524 if (*p == 0x0e00ed0f) {
525 dev_dbg(codec->dev, "PLL packet received\n");
526 wm0010->pll_running = true;
527 break;
528 }
529 p++;
530 }
531
532 kfree(img_swap);
533 kfree(out);
534 } else
535 dev_dbg(codec->dev, "Not enabling DSP PLL.");
536
537 ret = request_firmware(&fw, "wm0010.dfw", codec->dev);
538 if (ret != 0) {
539 dev_err(codec->dev, "Failed to request application: %d\n",
540 ret);
541 goto abort;
542 }
543
544 rec = (const struct dfw_binrec *)fw->data;
545 offset = 0;
546 wm0010->boot_done = 0;
547 wm0010->boot_failed = false;
548 BUG_ON(!list_empty(&xfer_list));
549 init_completion(&done);
550
551 /* First record should be INFO */
552 if (rec->command != DFW_CMD_INFO) {
553 dev_err(codec->dev, "First record not INFO\r\n");
554 goto abort;
555 }
556
557 /* Check it's a 0010 file */
558 if (rec->data[0] != DEVICE_ID_WM0010) {
559 dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
560 goto abort;
561 }
562
563 /* Skip the info record as we don't need to send it */
564 offset += ((rec->length) + 8);
565 rec = (void *)&rec->data[rec->length];
566
567 while (offset < fw->size) {
568 dev_dbg(codec->dev,
569 "Packet: command %d, data length = 0x%x\r\n",
570 rec->command, rec->length);
571 len = rec->length + 8;
572
573 out = kzalloc(len, GFP_KERNEL);
574 if (!out) {
575 dev_err(codec->dev,
576 "Failed to allocate RX buffer\n");
577 goto abort;
578 }
579
580 img_swap = kzalloc(len, GFP_KERNEL);
581 if (!img_swap) {
582 dev_err(codec->dev,
583 "Failed to allocate image buffer\n");
584 goto abort;
585 }
586
587 /* We need to re-order for 0010 */
588 byte_swap_64((u64 *)&rec->command, img_swap, len);
589
590 xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
591 if (!xfer) {
592 dev_err(codec->dev, "Failed to allocate xfer\n");
593 goto abort;
594 }
595
596 xfer->codec = codec;
597 list_add_tail(&xfer->list, &xfer_list);
598
599 spi_message_init(&xfer->m);
600 xfer->m.complete = wm0010_boot_xfer_complete;
601 xfer->m.context = xfer;
602 xfer->t.tx_buf = img_swap;
603 xfer->t.rx_buf = out;
604 xfer->t.len = len;
605 xfer->t.bits_per_word = 8;
606
607 if (!wm0010->pll_running) {
608 xfer->t.speed_hz = wm0010->sysclk / 6;
609 } else {
610 xfer->t.speed_hz = wm0010->max_spi_freq;
611
612 if (wm0010->board_max_spi_speed &&
613 (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
614 xfer->t.speed_hz = wm0010->board_max_spi_speed;
615 }
616
617 /* Store max usable spi frequency for later use */
618 wm0010->max_spi_freq = xfer->t.speed_hz;
619
620 spi_message_add_tail(&xfer->t, &xfer->m);
621
622 offset += ((rec->length) + 8);
623 rec = (void *)&rec->data[rec->length];
624
625 if (offset >= fw->size) {
626 dev_dbg(codec->dev, "All transfers scheduled\n");
627 xfer->done = &done;
628 }
629
630 ret = spi_async(spi, &xfer->m);
631 if (ret != 0) {
632 dev_err(codec->dev, "Write failed: %d\n", ret);
633 goto abort;
634 }
635
636 if (wm0010->boot_failed)
637 goto abort;
638 }
639
640 wait_for_completion(&done);
641
642 spin_lock_irqsave(&wm0010->irq_lock, flags);
643 wm0010->state = WM0010_FIRMWARE;
644 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
645
646 mutex_unlock(&wm0010->lock);
647
648 release_firmware(fw);
649
650 while (!list_empty(&xfer_list)) {
651 xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
652 list);
653 kfree(xfer->t.rx_buf);
654 kfree(xfer->t.tx_buf);
655 list_del(&xfer->list);
656 kfree(xfer);
657 }
658
659 return 0;
660
661abort:
662 /* Put the chip back into reset */
663 wm0010_halt(codec);
664 mutex_unlock(&wm0010->lock);
665 return ret;
666err_core:
667 regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
668 wm0010->core_supplies);
669err:
670 return ret;
671}
672
673static int wm0010_set_bias_level(struct snd_soc_codec *codec,
674 enum snd_soc_bias_level level)
675{
676 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
677
678 switch (level) {
679 case SND_SOC_BIAS_ON:
680 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
681 wm0010_boot(codec);
682 break;
683 case SND_SOC_BIAS_PREPARE:
684 break;
685 case SND_SOC_BIAS_STANDBY:
686 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
687 mutex_lock(&wm0010->lock);
688 wm0010_halt(codec);
689 mutex_unlock(&wm0010->lock);
690 }
691 break;
692 case SND_SOC_BIAS_OFF:
693 break;
694 }
695
696 codec->dapm.bias_level = level;
697
698 return 0;
699}
700
701static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
702 int clk_id, unsigned int freq, int dir)
703{
704 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
705 unsigned int i;
706
707 wm0010->sysclk = freq;
708
709 if (freq < pll_clock_map[ARRAY_SIZE(pll_clock_map)-1].max_sysclk) {
710 wm0010->max_spi_freq = 0;
711 } else {
712 for (i = 0; i < ARRAY_SIZE(pll_clock_map); i++)
713 if (freq >= pll_clock_map[i].max_sysclk)
714 break;
715
716 wm0010->max_spi_freq = pll_clock_map[i].max_pll_spi_speed;
717 wm0010->pll_clkctrl1 = pll_clock_map[i].pll_clkctrl1;
718 }
719
720 return 0;
721}
722
723static int wm0010_probe(struct snd_soc_codec *codec);
724
725static struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
726 .probe = wm0010_probe,
727 .set_bias_level = wm0010_set_bias_level,
728 .set_sysclk = wm0010_set_sysclk,
729 .idle_bias_off = true,
730
731 .dapm_widgets = wm0010_dapm_widgets,
732 .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets),
733 .dapm_routes = wm0010_dapm_routes,
734 .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes),
735};
736
737#define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
738#define WM0010_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
739 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
740 SNDRV_PCM_FMTBIT_S32_LE)
741
742static struct snd_soc_dai_driver wm0010_dai[] = {
743 {
744 .name = "wm0010-sdi1",
745 .playback = {
746 .stream_name = "SDI1 Playback",
747 .channels_min = 1,
748 .channels_max = 2,
749 .rates = WM0010_RATES,
750 .formats = WM0010_FORMATS,
751 },
752 .capture = {
753 .stream_name = "SDI1 Capture",
754 .channels_min = 1,
755 .channels_max = 2,
756 .rates = WM0010_RATES,
757 .formats = WM0010_FORMATS,
758 },
759 },
760 {
761 .name = "wm0010-sdi2",
762 .playback = {
763 .stream_name = "SDI2 Playback",
764 .channels_min = 1,
765 .channels_max = 2,
766 .rates = WM0010_RATES,
767 .formats = WM0010_FORMATS,
768 },
769 .capture = {
770 .stream_name = "SDI2 Capture",
771 .channels_min = 1,
772 .channels_max = 2,
773 .rates = WM0010_RATES,
774 .formats = WM0010_FORMATS,
775 },
776 },
777};
778
779static irqreturn_t wm0010_irq(int irq, void *data)
780{
781 struct wm0010_priv *wm0010 = data;
782
783 switch (wm0010->state) {
784 case WM0010_POWER_OFF:
785 case WM0010_OUT_OF_RESET:
786 case WM0010_BOOTROM:
787 case WM0010_STAGE2:
788 spin_lock(&wm0010->irq_lock);
789 complete(&wm0010->boot_completion);
790 spin_unlock(&wm0010->irq_lock);
791 return IRQ_HANDLED;
792 default:
793 return IRQ_NONE;
794 }
795
796 return IRQ_NONE;
797}
798
799static int wm0010_probe(struct snd_soc_codec *codec)
800{
801 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
802
803 wm0010->codec = codec;
804
805 return 0;
806}
807
808static int __devinit wm0010_spi_probe(struct spi_device *spi)
809{
810 unsigned long flags;
811 unsigned long gpio_flags;
812 int ret;
813 int trigger;
814 int irq;
815 struct wm0010_priv *wm0010;
816
817 wm0010 = devm_kzalloc(&spi->dev, sizeof(*wm0010),
818 GFP_KERNEL);
819 if (!wm0010)
820 return -ENOMEM;
821
822 mutex_init(&wm0010->lock);
823 spin_lock_init(&wm0010->irq_lock);
824
825 spi_set_drvdata(spi, wm0010);
826 wm0010->dev = &spi->dev;
827
828 if (dev_get_platdata(&spi->dev))
829 memcpy(&wm0010->pdata, dev_get_platdata(&spi->dev),
830 sizeof(wm0010->pdata));
831
832 init_completion(&wm0010->boot_completion);
833
834 wm0010->core_supplies[0].supply = "AVDD";
835 wm0010->core_supplies[1].supply = "DCVDD";
836 ret = devm_regulator_bulk_get(wm0010->dev, ARRAY_SIZE(wm0010->core_supplies),
837 wm0010->core_supplies);
838 if (ret != 0) {
839 dev_err(wm0010->dev, "Failed to obtain core supplies: %d\n",
840 ret);
841 return ret;
842 }
843
844 wm0010->dbvdd = devm_regulator_get(wm0010->dev, "DBVDD");
845 if (IS_ERR(wm0010->dbvdd)) {
846 ret = PTR_ERR(wm0010->dbvdd);
847 dev_err(wm0010->dev, "Failed to obtain DBVDD: %d\n", ret);
848 return ret;
849 }
850
851 if (wm0010->pdata.gpio_reset) {
852 wm0010->gpio_reset = wm0010->pdata.gpio_reset;
853
854 if (wm0010->pdata.reset_active_high)
855 wm0010->gpio_reset_value = 1;
856 else
857 wm0010->gpio_reset_value = 0;
858
859 if (wm0010->gpio_reset_value)
860 gpio_flags = GPIOF_OUT_INIT_HIGH;
861 else
862 gpio_flags = GPIOF_OUT_INIT_LOW;
863
864 ret = devm_gpio_request_one(wm0010->dev, wm0010->gpio_reset,
865 gpio_flags, "wm0010 reset");
866 if (ret < 0) {
867 dev_err(wm0010->dev,
868 "Failed to request GPIO for DSP reset: %d\n",
869 ret);
870 return ret;
871 }
872 } else {
873 dev_err(wm0010->dev, "No reset GPIO configured\n");
874 return -EINVAL;
875 }
876
877 irq = spi->irq;
878 if (wm0010->pdata.irq_flags)
879 trigger = wm0010->pdata.irq_flags;
880 else
881 trigger = IRQF_TRIGGER_FALLING;
882 trigger |= IRQF_ONESHOT;
883
884 ret = request_threaded_irq(irq, NULL, wm0010_irq, trigger,
885 "wm0010", wm0010);
886 if (ret) {
887 dev_err(wm0010->dev, "Failed to request IRQ %d: %d\n",
888 irq, ret);
889 return ret;
890 }
891 wm0010->irq = irq;
892
893 if (spi->max_speed_hz)
894 wm0010->board_max_spi_speed = spi->max_speed_hz;
895 else
896 wm0010->board_max_spi_speed = 0;
897
898 spin_lock_irqsave(&wm0010->irq_lock, flags);
899 wm0010->state = WM0010_POWER_OFF;
900 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
901
902 ret = snd_soc_register_codec(&spi->dev,
903 &soc_codec_dev_wm0010, wm0010_dai,
904 ARRAY_SIZE(wm0010_dai));
905 if (ret < 0)
906 return ret;
907
908 return 0;
909}
910
911static int __devexit wm0010_spi_remove(struct spi_device *spi)
912{
913 struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
914
915 snd_soc_unregister_codec(&spi->dev);
916
917 if (wm0010->gpio_reset) {
918 /* Remember to put chip back into reset */
919 gpio_set_value(wm0010->gpio_reset, wm0010->gpio_reset_value);
920 }
921
922 if (wm0010->irq)
923 free_irq(wm0010->irq, wm0010);
924
925 return 0;
926}
927
928static struct spi_driver wm0010_spi_driver = {
929 .driver = {
930 .name = "wm0010",
931 .bus = &spi_bus_type,
932 .owner = THIS_MODULE,
933 },
934 .probe = wm0010_spi_probe,
935 .remove = __devexit_p(wm0010_spi_remove),
936};
937
938module_spi_driver(wm0010_spi_driver);
939
940MODULE_DESCRIPTION("ASoC WM0010 driver");
941MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
942MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 3fd5b29dc933..89cd6fcad015 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -858,17 +858,7 @@ static struct i2c_driver wm2000_i2c_driver = {
858 .id_table = wm2000_i2c_id, 858 .id_table = wm2000_i2c_id,
859}; 859};
860 860
861static int __init wm2000_init(void) 861module_i2c_driver(wm2000_i2c_driver);
862{
863 return i2c_add_driver(&wm2000_i2c_driver);
864}
865module_init(wm2000_init);
866
867static void __exit wm2000_exit(void)
868{
869 i2c_del_driver(&wm2000_i2c_driver);
870}
871module_exit(wm2000_exit);
872 862
873MODULE_DESCRIPTION("ASoC WM2000 driver"); 863MODULE_DESCRIPTION("ASoC WM2000 driver");
874MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); 864MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 32682c1b7cde..71debd0a3822 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -2270,17 +2270,7 @@ static struct i2c_driver wm2200_i2c_driver = {
2270 .id_table = wm2200_i2c_id, 2270 .id_table = wm2200_i2c_id,
2271}; 2271};
2272 2272
2273static int __init wm2200_modinit(void) 2273module_i2c_driver(wm2200_i2c_driver);
2274{
2275 return i2c_add_driver(&wm2200_i2c_driver);
2276}
2277module_init(wm2200_modinit);
2278
2279static void __exit wm2200_exit(void)
2280{
2281 i2c_del_driver(&wm2200_i2c_driver);
2282}
2283module_exit(wm2200_exit);
2284 2274
2285MODULE_DESCRIPTION("ASoC WM2200 driver"); 2275MODULE_DESCRIPTION("ASoC WM2200 driver");
2286MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2276MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index e33d327396ad..e2fb07ee68a7 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -274,11 +274,36 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
274ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); 274ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
275ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); 275ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
276 276
277
278static const char *wm5102_aec_loopback_texts[] = {
279 "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
280 "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R",
281};
282
283static const unsigned int wm5102_aec_loopback_values[] = {
284 0, 1, 2, 3, 4, 6, 7, 8, 9,
285};
286
287static const struct soc_enum wm5102_aec_loopback =
288 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
289 ARIZONA_AEC_LOOPBACK_SRC_SHIFT,
290 ARIZONA_AEC_LOOPBACK_SRC_MASK,
291 ARRAY_SIZE(wm5102_aec_loopback_texts),
292 wm5102_aec_loopback_texts,
293 wm5102_aec_loopback_values);
294
295static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
296 SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback);
297
277static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { 298static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
278SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, 299SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
279 0, NULL, 0), 300 0, NULL, 0),
280SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, 301SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
281 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), 302 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
303SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
304 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
305SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
306 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
282 307
283SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), 308SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
284SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), 309SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
@@ -421,6 +446,9 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
421SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, 446SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
422 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), 447 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
423 448
449SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
450 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
451
424SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 452SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
425 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 453 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
426 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 454 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -516,6 +544,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
516 { name, "Noise Generator", "Noise Generator" }, \ 544 { name, "Noise Generator", "Noise Generator" }, \
517 { name, "Tone Generator 1", "Tone Generator 1" }, \ 545 { name, "Tone Generator 1", "Tone Generator 1" }, \
518 { name, "Tone Generator 2", "Tone Generator 2" }, \ 546 { name, "Tone Generator 2", "Tone Generator 2" }, \
547 { name, "AEC", "AEC Loopback" }, \
519 { name, "IN1L", "IN1L PGA" }, \ 548 { name, "IN1L", "IN1L PGA" }, \
520 { name, "IN1R", "IN1R PGA" }, \ 549 { name, "IN1R", "IN1R PGA" }, \
521 { name, "IN2L", "IN2L PGA" }, \ 550 { name, "IN2L", "IN2L PGA" }, \
@@ -681,21 +710,30 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
681 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), 710 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
682 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), 711 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
683 712
713 { "AEC Loopback", "HPOUT1L", "OUT1L" },
714 { "AEC Loopback", "HPOUT1R", "OUT1R" },
684 { "HPOUT1L", NULL, "OUT1L" }, 715 { "HPOUT1L", NULL, "OUT1L" },
685 { "HPOUT1R", NULL, "OUT1R" }, 716 { "HPOUT1R", NULL, "OUT1R" },
686 717
718 { "AEC Loopback", "HPOUT2L", "OUT2L" },
719 { "AEC Loopback", "HPOUT2R", "OUT2R" },
687 { "HPOUT2L", NULL, "OUT2L" }, 720 { "HPOUT2L", NULL, "OUT2L" },
688 { "HPOUT2R", NULL, "OUT2R" }, 721 { "HPOUT2R", NULL, "OUT2R" },
689 722
723 { "AEC Loopback", "EPOUT", "OUT3L" },
690 { "EPOUTN", NULL, "OUT3L" }, 724 { "EPOUTN", NULL, "OUT3L" },
691 { "EPOUTP", NULL, "OUT3L" }, 725 { "EPOUTP", NULL, "OUT3L" },
692 726
727 { "AEC Loopback", "SPKOUTL", "OUT4L" },
693 { "SPKOUTLN", NULL, "OUT4L" }, 728 { "SPKOUTLN", NULL, "OUT4L" },
694 { "SPKOUTLP", NULL, "OUT4L" }, 729 { "SPKOUTLP", NULL, "OUT4L" },
695 730
731 { "AEC Loopback", "SPKOUTR", "OUT4R" },
696 { "SPKOUTRN", NULL, "OUT4R" }, 732 { "SPKOUTRN", NULL, "OUT4R" },
697 { "SPKOUTRP", NULL, "OUT4R" }, 733 { "SPKOUTRP", NULL, "OUT4R" },
698 734
735 { "AEC Loopback", "SPKDAT1L", "OUT5L" },
736 { "AEC Loopback", "SPKDAT1R", "OUT5R" },
699 { "SPKDAT1L", NULL, "OUT5L" }, 737 { "SPKDAT1L", NULL, "OUT5L" },
700 { "SPKDAT1R", NULL, "OUT5R" }, 738 { "SPKDAT1R", NULL, "OUT5R" },
701}; 739};
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 01ebbcc5c6a4..57c7d9c0aadb 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -305,6 +305,10 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
305 0, NULL, 0), 305 0, NULL, 0),
306SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, 306SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
307 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), 307 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
308SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
309 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
310SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
311 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
308 312
309SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), 313SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
310SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), 314SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index a5127b4ff9e1..c7c0034d3966 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -724,24 +724,7 @@ static struct spi_driver wm8770_spi_driver = {
724 .remove = __devexit_p(wm8770_spi_remove) 724 .remove = __devexit_p(wm8770_spi_remove)
725}; 725};
726 726
727static int __init wm8770_modinit(void) 727module_spi_driver(wm8770_spi_driver);
728{
729 int ret = 0;
730
731 ret = spi_register_driver(&wm8770_spi_driver);
732 if (ret) {
733 printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
734 ret);
735 }
736 return ret;
737}
738module_init(wm8770_modinit);
739
740static void __exit wm8770_exit(void)
741{
742 spi_unregister_driver(&wm8770_spi_driver);
743}
744module_exit(wm8770_exit);
745 728
746MODULE_DESCRIPTION("ASoC WM8770 driver"); 729MODULE_DESCRIPTION("ASoC WM8770 driver");
747MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 730MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 73f1c8d7bafb..839414f9e2ed 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2241,23 +2241,7 @@ static struct i2c_driver wm8903_i2c_driver = {
2241 .id_table = wm8903_i2c_id, 2241 .id_table = wm8903_i2c_id,
2242}; 2242};
2243 2243
2244static int __init wm8903_modinit(void) 2244module_i2c_driver(wm8903_i2c_driver);
2245{
2246 int ret = 0;
2247 ret = i2c_add_driver(&wm8903_i2c_driver);
2248 if (ret != 0) {
2249 printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
2250 ret);
2251 }
2252 return ret;
2253}
2254module_init(wm8903_modinit);
2255
2256static void __exit wm8903_exit(void)
2257{
2258 i2c_del_driver(&wm8903_i2c_driver);
2259}
2260module_exit(wm8903_exit);
2261 2245
2262MODULE_DESCRIPTION("ASoC WM8903 driver"); 2246MODULE_DESCRIPTION("ASoC WM8903 driver");
2263MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); 2247MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 481a3d9cfe48..b20aa4e7c3f9 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -785,23 +785,7 @@ static struct i2c_driver wm8940_i2c_driver = {
785 .id_table = wm8940_i2c_id, 785 .id_table = wm8940_i2c_id,
786}; 786};
787 787
788static int __init wm8940_modinit(void) 788module_i2c_driver(wm8940_i2c_driver);
789{
790 int ret = 0;
791 ret = i2c_add_driver(&wm8940_i2c_driver);
792 if (ret != 0) {
793 printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
794 ret);
795 }
796 return ret;
797}
798module_init(wm8940_modinit);
799
800static void __exit wm8940_exit(void)
801{
802 i2c_del_driver(&wm8940_i2c_driver);
803}
804module_exit(wm8940_exit);
805 789
806MODULE_DESCRIPTION("ASoC WM8940 driver"); 790MODULE_DESCRIPTION("ASoC WM8940 driver");
807MODULE_AUTHOR("Jonathan Cameron"); 791MODULE_AUTHOR("Jonathan Cameron");
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 61fe97433e73..2f1c075755b1 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -1071,23 +1071,7 @@ static struct i2c_driver wm8955_i2c_driver = {
1071 .id_table = wm8955_i2c_id, 1071 .id_table = wm8955_i2c_id,
1072}; 1072};
1073 1073
1074static int __init wm8955_modinit(void) 1074module_i2c_driver(wm8955_i2c_driver);
1075{
1076 int ret = 0;
1077 ret = i2c_add_driver(&wm8955_i2c_driver);
1078 if (ret != 0) {
1079 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1080 ret);
1081 }
1082 return ret;
1083}
1084module_init(wm8955_modinit);
1085
1086static void __exit wm8955_exit(void)
1087{
1088 i2c_del_driver(&wm8955_i2c_driver);
1089}
1090module_exit(wm8955_exit);
1091 1075
1092MODULE_DESCRIPTION("ASoC WM8955 driver"); 1076MODULE_DESCRIPTION("ASoC WM8955 driver");
1093MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1077MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 1332692ef81b..00121ba36597 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -946,7 +946,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
946 wm8994->mbc_texts = kmalloc(sizeof(char *) 946 wm8994->mbc_texts = kmalloc(sizeof(char *)
947 * pdata->num_mbc_cfgs, GFP_KERNEL); 947 * pdata->num_mbc_cfgs, GFP_KERNEL);
948 if (!wm8994->mbc_texts) { 948 if (!wm8994->mbc_texts) {
949 dev_err(wm8994->codec->dev, 949 dev_err(wm8994->hubs.codec->dev,
950 "Failed to allocate %d MBC config texts\n", 950 "Failed to allocate %d MBC config texts\n",
951 pdata->num_mbc_cfgs); 951 pdata->num_mbc_cfgs);
952 return; 952 return;
@@ -958,9 +958,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
958 wm8994->mbc_enum.max = pdata->num_mbc_cfgs; 958 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
959 wm8994->mbc_enum.texts = wm8994->mbc_texts; 959 wm8994->mbc_enum.texts = wm8994->mbc_texts;
960 960
961 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); 961 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
962 control, 1);
962 if (ret != 0) 963 if (ret != 0)
963 dev_err(wm8994->codec->dev, 964 dev_err(wm8994->hubs.codec->dev,
964 "Failed to add MBC mode controls: %d\n", ret); 965 "Failed to add MBC mode controls: %d\n", ret);
965 } 966 }
966 967
@@ -974,7 +975,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
974 wm8994->vss_texts = kmalloc(sizeof(char *) 975 wm8994->vss_texts = kmalloc(sizeof(char *)
975 * pdata->num_vss_cfgs, GFP_KERNEL); 976 * pdata->num_vss_cfgs, GFP_KERNEL);
976 if (!wm8994->vss_texts) { 977 if (!wm8994->vss_texts) {
977 dev_err(wm8994->codec->dev, 978 dev_err(wm8994->hubs.codec->dev,
978 "Failed to allocate %d VSS config texts\n", 979 "Failed to allocate %d VSS config texts\n",
979 pdata->num_vss_cfgs); 980 pdata->num_vss_cfgs);
980 return; 981 return;
@@ -986,9 +987,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
986 wm8994->vss_enum.max = pdata->num_vss_cfgs; 987 wm8994->vss_enum.max = pdata->num_vss_cfgs;
987 wm8994->vss_enum.texts = wm8994->vss_texts; 988 wm8994->vss_enum.texts = wm8994->vss_texts;
988 989
989 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); 990 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
991 control, 1);
990 if (ret != 0) 992 if (ret != 0)
991 dev_err(wm8994->codec->dev, 993 dev_err(wm8994->hubs.codec->dev,
992 "Failed to add VSS mode controls: %d\n", ret); 994 "Failed to add VSS mode controls: %d\n", ret);
993 } 995 }
994 996
@@ -1003,7 +1005,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1003 wm8994->vss_hpf_texts = kmalloc(sizeof(char *) 1005 wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
1004 * pdata->num_vss_hpf_cfgs, GFP_KERNEL); 1006 * pdata->num_vss_hpf_cfgs, GFP_KERNEL);
1005 if (!wm8994->vss_hpf_texts) { 1007 if (!wm8994->vss_hpf_texts) {
1006 dev_err(wm8994->codec->dev, 1008 dev_err(wm8994->hubs.codec->dev,
1007 "Failed to allocate %d VSS HPF config texts\n", 1009 "Failed to allocate %d VSS HPF config texts\n",
1008 pdata->num_vss_hpf_cfgs); 1010 pdata->num_vss_hpf_cfgs);
1009 return; 1011 return;
@@ -1015,9 +1017,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1015 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; 1017 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
1016 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; 1018 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1017 1019
1018 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); 1020 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
1021 control, 1);
1019 if (ret != 0) 1022 if (ret != 0)
1020 dev_err(wm8994->codec->dev, 1023 dev_err(wm8994->hubs.codec->dev,
1021 "Failed to add VSS HPFmode controls: %d\n", 1024 "Failed to add VSS HPFmode controls: %d\n",
1022 ret); 1025 ret);
1023 } 1026 }
@@ -1033,7 +1036,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1033 wm8994->enh_eq_texts = kmalloc(sizeof(char *) 1036 wm8994->enh_eq_texts = kmalloc(sizeof(char *)
1034 * pdata->num_enh_eq_cfgs, GFP_KERNEL); 1037 * pdata->num_enh_eq_cfgs, GFP_KERNEL);
1035 if (!wm8994->enh_eq_texts) { 1038 if (!wm8994->enh_eq_texts) {
1036 dev_err(wm8994->codec->dev, 1039 dev_err(wm8994->hubs.codec->dev,
1037 "Failed to allocate %d enhanced EQ config texts\n", 1040 "Failed to allocate %d enhanced EQ config texts\n",
1038 pdata->num_enh_eq_cfgs); 1041 pdata->num_enh_eq_cfgs);
1039 return; 1042 return;
@@ -1045,9 +1048,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1045 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; 1048 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1046 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; 1049 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1047 1050
1048 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); 1051 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
1052 control, 1);
1049 if (ret != 0) 1053 if (ret != 0)
1050 dev_err(wm8994->codec->dev, 1054 dev_err(wm8994->hubs.codec->dev,
1051 "Failed to add enhanced EQ controls: %d\n", 1055 "Failed to add enhanced EQ controls: %d\n",
1052 ret); 1056 ret);
1053 } 1057 }
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 96518ac8e24c..804f4116912f 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -1010,23 +1010,7 @@ static struct i2c_driver wm8960_i2c_driver = {
1010 .id_table = wm8960_i2c_id, 1010 .id_table = wm8960_i2c_id,
1011}; 1011};
1012 1012
1013static int __init wm8960_modinit(void) 1013module_i2c_driver(wm8960_i2c_driver);
1014{
1015 int ret = 0;
1016 ret = i2c_add_driver(&wm8960_i2c_driver);
1017 if (ret != 0) {
1018 printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
1019 ret);
1020 }
1021 return ret;
1022}
1023module_init(wm8960_modinit);
1024
1025static void __exit wm8960_exit(void)
1026{
1027 i2c_del_driver(&wm8960_i2c_driver);
1028}
1029module_exit(wm8960_exit);
1030 1014
1031MODULE_DESCRIPTION("ASoC WM8960 driver"); 1015MODULE_DESCRIPTION("ASoC WM8960 driver");
1032MODULE_AUTHOR("Liam Girdwood"); 1016MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 01edbcc754d2..719fb69a17c8 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1114,23 +1114,7 @@ static struct i2c_driver wm8961_i2c_driver = {
1114 .id_table = wm8961_i2c_id, 1114 .id_table = wm8961_i2c_id,
1115}; 1115};
1116 1116
1117static int __init wm8961_modinit(void) 1117module_i2c_driver(wm8961_i2c_driver);
1118{
1119 int ret = 0;
1120 ret = i2c_add_driver(&wm8961_i2c_driver);
1121 if (ret != 0) {
1122 printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
1123 ret);
1124 }
1125 return ret;
1126}
1127module_init(wm8961_modinit);
1128
1129static void __exit wm8961_exit(void)
1130{
1131 i2c_del_driver(&wm8961_i2c_driver);
1132}
1133module_exit(wm8961_exit);
1134 1118
1135MODULE_DESCRIPTION("ASoC WM8961 driver"); 1119MODULE_DESCRIPTION("ASoC WM8961 driver");
1136MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1120MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index eef783f6b6d6..5ce647758443 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -721,23 +721,7 @@ static struct i2c_driver wm8971_i2c_driver = {
721 .id_table = wm8971_i2c_id, 721 .id_table = wm8971_i2c_id,
722}; 722};
723 723
724static int __init wm8971_modinit(void) 724module_i2c_driver(wm8971_i2c_driver);
725{
726 int ret = 0;
727 ret = i2c_add_driver(&wm8971_i2c_driver);
728 if (ret != 0) {
729 printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
730 ret);
731 }
732 return ret;
733}
734module_init(wm8971_modinit);
735
736static void __exit wm8971_exit(void)
737{
738 i2c_del_driver(&wm8971_i2c_driver);
739}
740module_exit(wm8971_exit);
741 725
742MODULE_DESCRIPTION("ASoC WM8971 driver"); 726MODULE_DESCRIPTION("ASoC WM8971 driver");
743MODULE_AUTHOR("Lab126"); 727MODULE_AUTHOR("Lab126");
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index d93c03f820c9..9a39511af52a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -659,23 +659,7 @@ static struct i2c_driver wm8974_i2c_driver = {
659 .id_table = wm8974_i2c_id, 659 .id_table = wm8974_i2c_id,
660}; 660};
661 661
662static int __init wm8974_modinit(void) 662module_i2c_driver(wm8974_i2c_driver);
663{
664 int ret = 0;
665 ret = i2c_add_driver(&wm8974_i2c_driver);
666 if (ret != 0) {
667 printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
668 ret);
669 }
670 return ret;
671}
672module_init(wm8974_modinit);
673
674static void __exit wm8974_exit(void)
675{
676 i2c_del_driver(&wm8974_i2c_driver);
677}
678module_exit(wm8974_exit);
679 663
680MODULE_DESCRIPTION("ASoC WM8974 driver"); 664MODULE_DESCRIPTION("ASoC WM8974 driver");
681MODULE_AUTHOR("Liam Girdwood"); 665MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index a5be3adecf75..5421fd9fbcb5 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1105,23 +1105,7 @@ static struct i2c_driver wm8978_i2c_driver = {
1105 .id_table = wm8978_i2c_id, 1105 .id_table = wm8978_i2c_id,
1106}; 1106};
1107 1107
1108static int __init wm8978_modinit(void) 1108module_i2c_driver(wm8978_i2c_driver);
1109{
1110 int ret = 0;
1111 ret = i2c_add_driver(&wm8978_i2c_driver);
1112 if (ret != 0) {
1113 printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
1114 ret);
1115 }
1116 return ret;
1117}
1118module_init(wm8978_modinit);
1119
1120static void __exit wm8978_exit(void)
1121{
1122 i2c_del_driver(&wm8978_i2c_driver);
1123}
1124module_exit(wm8978_exit);
1125 1109
1126MODULE_DESCRIPTION("ASoC WM8978 codec driver"); 1110MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1127MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); 1111MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 9ac31ba9b82e..b9dbfebbda13 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1400,23 +1400,7 @@ static struct i2c_driver wm8991_i2c_driver = {
1400 .id_table = wm8991_i2c_id, 1400 .id_table = wm8991_i2c_id,
1401}; 1401};
1402 1402
1403static int __init wm8991_modinit(void) 1403module_i2c_driver(wm8991_i2c_driver);
1404{
1405 int ret;
1406 ret = i2c_add_driver(&wm8991_i2c_driver);
1407 if (ret != 0) {
1408 printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
1409 ret);
1410 }
1411 return 0;
1412}
1413module_init(wm8991_modinit);
1414
1415static void __exit wm8991_exit(void)
1416{
1417 i2c_del_driver(&wm8991_i2c_driver);
1418}
1419module_exit(wm8991_exit);
1420 1404
1421MODULE_DESCRIPTION("ASoC WM8991 driver"); 1405MODULE_DESCRIPTION("ASoC WM8991 driver");
1422MODULE_AUTHOR("Graeme Gregory"); 1406MODULE_AUTHOR("Graeme Gregory");
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 9fd80d688979..94737a30716b 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1520,6 +1520,8 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1520 wm8993->pdata.lineout2fb, 1520 wm8993->pdata.lineout2fb,
1521 wm8993->pdata.jd_scthr, 1521 wm8993->pdata.jd_scthr,
1522 wm8993->pdata.jd_thr, 1522 wm8993->pdata.jd_thr,
1523 wm8993->pdata.micbias1_delay,
1524 wm8993->pdata.micbias2_delay,
1523 wm8993->pdata.micbias1_lvl, 1525 wm8993->pdata.micbias1_lvl,
1524 wm8993->pdata.micbias2_lvl); 1526 wm8993->pdata.micbias2_lvl);
1525 1527
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 6c9eeca85b95..2b2dadc54dac 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -671,6 +671,18 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
671 eq_tlv), 671 eq_tlv),
672}; 672};
673 673
674static const struct snd_kcontrol_new wm8994_drc_controls[] = {
675SND_SOC_BYTES_MASK("AIF1.1 DRC", WM8994_AIF1_DRC1_1, 5,
676 WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
677 WM8994_AIF1ADC1R_DRC_ENA),
678SND_SOC_BYTES_MASK("AIF1.2 DRC", WM8994_AIF1_DRC2_1, 5,
679 WM8994_AIF1DAC2_DRC_ENA | WM8994_AIF1ADC2L_DRC_ENA |
680 WM8994_AIF1ADC2R_DRC_ENA),
681SND_SOC_BYTES_MASK("AIF2 DRC", WM8994_AIF2_DRC_1, 5,
682 WM8994_AIF2DAC_DRC_ENA | WM8994_AIF2ADCL_DRC_ENA |
683 WM8994_AIF2ADCR_DRC_ENA),
684};
685
674static const char *wm8958_ng_text[] = { 686static const char *wm8958_ng_text[] = {
675 "30ms", "125ms", "250ms", "500ms", 687 "30ms", "125ms", "250ms", "500ms",
676}; 688};
@@ -789,11 +801,27 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
789 struct snd_kcontrol *kcontrol, int event) 801 struct snd_kcontrol *kcontrol, int event)
790{ 802{
791 struct snd_soc_codec *codec = w->codec; 803 struct snd_soc_codec *codec = w->codec;
804 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
792 805
793 switch (event) { 806 switch (event) {
794 case SND_SOC_DAPM_PRE_PMU: 807 case SND_SOC_DAPM_PRE_PMU:
795 return configure_clock(codec); 808 return configure_clock(codec);
796 809
810 case SND_SOC_DAPM_POST_PMU:
811 /*
812 * JACKDET won't run until we start the clock and it
813 * only reports deltas, make sure we notify the state
814 * up the stack on startup. Use a *very* generous
815 * timeout for paranoia, there's no urgency and we
816 * don't want false reports.
817 */
818 if (wm8994->jackdet && !wm8994->clk_has_run) {
819 schedule_delayed_work(&wm8994->jackdet_bootstrap,
820 msecs_to_jiffies(1000));
821 wm8994->clk_has_run = true;
822 }
823 break;
824
797 case SND_SOC_DAPM_POST_PMD: 825 case SND_SOC_DAPM_POST_PMD:
798 configure_clock(codec); 826 configure_clock(codec);
799 break; 827 break;
@@ -1632,7 +1660,8 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
1632 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1660 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1633 1661
1634SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1662SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1635 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1663 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1664 SND_SOC_DAPM_PRE_PMD),
1636 1665
1637SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), 1666SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
1638SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), 1667SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
@@ -2102,6 +2131,10 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2102 case WM8994_FLL_SRC_LRCLK: 2131 case WM8994_FLL_SRC_LRCLK:
2103 case WM8994_FLL_SRC_BCLK: 2132 case WM8994_FLL_SRC_BCLK:
2104 break; 2133 break;
2134 case WM8994_FLL_SRC_INTERNAL:
2135 freq_in = 12000000;
2136 freq_out = 12000000;
2137 break;
2105 default: 2138 default:
2106 return -EINVAL; 2139 return -EINVAL;
2107 } 2140 }
@@ -2161,12 +2194,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2161 2194
2162 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, 2195 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
2163 WM8994_FLL1_N_MASK, 2196 WM8994_FLL1_N_MASK,
2164 fll.n << WM8994_FLL1_N_SHIFT); 2197 fll.n << WM8994_FLL1_N_SHIFT);
2165 2198
2166 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, 2199 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2167 WM8958_FLL1_BYP | 2200 WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP |
2168 WM8994_FLL1_REFCLK_DIV_MASK | 2201 WM8994_FLL1_REFCLK_DIV_MASK |
2169 WM8994_FLL1_REFCLK_SRC_MASK, 2202 WM8994_FLL1_REFCLK_SRC_MASK,
2203 ((src == WM8994_FLL_SRC_INTERNAL)
2204 << WM8994_FLL1_FRC_NCO_SHIFT) |
2170 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | 2205 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
2171 (src - 1)); 2206 (src - 1));
2172 2207
@@ -2192,13 +2227,16 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2192 } 2227 }
2193 } 2228 }
2194 2229
2230 reg = WM8994_FLL1_ENA;
2231
2195 if (fll.k) 2232 if (fll.k)
2196 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; 2233 reg |= WM8994_FLL1_FRAC;
2197 else 2234 if (src == WM8994_FLL_SRC_INTERNAL)
2198 reg = WM8994_FLL1_ENA; 2235 reg |= WM8994_FLL1_OSC_ENA;
2236
2199 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, 2237 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2200 WM8994_FLL1_ENA | WM8994_FLL1_FRAC, 2238 WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA |
2201 reg); 2239 WM8994_FLL1_FRAC, reg);
2202 2240
2203 if (wm8994->fll_locked_irq) { 2241 if (wm8994->fll_locked_irq) {
2204 timeout = wait_for_completion_timeout(&wm8994->fll_locked[id], 2242 timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
@@ -3027,7 +3065,7 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec)
3027 3065
3028static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) 3066static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3029{ 3067{
3030 struct snd_soc_codec *codec = wm8994->codec; 3068 struct snd_soc_codec *codec = wm8994->hubs.codec;
3031 struct wm8994_pdata *pdata = wm8994->pdata; 3069 struct wm8994_pdata *pdata = wm8994->pdata;
3032 struct snd_kcontrol_new controls[] = { 3070 struct snd_kcontrol_new controls[] = {
3033 SOC_ENUM_EXT("AIF1.1 EQ Mode", 3071 SOC_ENUM_EXT("AIF1.1 EQ Mode",
@@ -3085,16 +3123,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3085 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 3123 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3086 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 3124 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3087 3125
3088 ret = snd_soc_add_codec_controls(wm8994->codec, controls, 3126 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
3089 ARRAY_SIZE(controls)); 3127 ARRAY_SIZE(controls));
3090 if (ret != 0) 3128 if (ret != 0)
3091 dev_err(wm8994->codec->dev, 3129 dev_err(wm8994->hubs.codec->dev,
3092 "Failed to add ReTune Mobile controls: %d\n", ret); 3130 "Failed to add ReTune Mobile controls: %d\n", ret);
3093} 3131}
3094 3132
3095static void wm8994_handle_pdata(struct wm8994_priv *wm8994) 3133static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3096{ 3134{
3097 struct snd_soc_codec *codec = wm8994->codec; 3135 struct snd_soc_codec *codec = wm8994->hubs.codec;
3098 struct wm8994_pdata *pdata = wm8994->pdata; 3136 struct wm8994_pdata *pdata = wm8994->pdata;
3099 int ret, i; 3137 int ret, i;
3100 3138
@@ -3107,6 +3145,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3107 pdata->lineout2fb, 3145 pdata->lineout2fb,
3108 pdata->jd_scthr, 3146 pdata->jd_scthr,
3109 pdata->jd_thr, 3147 pdata->jd_thr,
3148 pdata->micb1_delay,
3149 pdata->micb2_delay,
3110 pdata->micbias1_lvl, 3150 pdata->micbias1_lvl,
3111 pdata->micbias2_lvl); 3151 pdata->micbias2_lvl);
3112 3152
@@ -3123,10 +3163,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3123 }; 3163 };
3124 3164
3125 /* We need an array of texts for the enum API */ 3165 /* We need an array of texts for the enum API */
3126 wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev, 3166 wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev,
3127 sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); 3167 sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL);
3128 if (!wm8994->drc_texts) { 3168 if (!wm8994->drc_texts) {
3129 dev_err(wm8994->codec->dev, 3169 dev_err(wm8994->hubs.codec->dev,
3130 "Failed to allocate %d DRC config texts\n", 3170 "Failed to allocate %d DRC config texts\n",
3131 pdata->num_drc_cfgs); 3171 pdata->num_drc_cfgs);
3132 return; 3172 return;
@@ -3138,23 +3178,28 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3138 wm8994->drc_enum.max = pdata->num_drc_cfgs; 3178 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3139 wm8994->drc_enum.texts = wm8994->drc_texts; 3179 wm8994->drc_enum.texts = wm8994->drc_texts;
3140 3180
3141 ret = snd_soc_add_codec_controls(wm8994->codec, controls, 3181 ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
3142 ARRAY_SIZE(controls)); 3182 ARRAY_SIZE(controls));
3143 if (ret != 0)
3144 dev_err(wm8994->codec->dev,
3145 "Failed to add DRC mode controls: %d\n", ret);
3146
3147 for (i = 0; i < WM8994_NUM_DRC; i++) 3183 for (i = 0; i < WM8994_NUM_DRC; i++)
3148 wm8994_set_drc(codec, i); 3184 wm8994_set_drc(codec, i);
3185 } else {
3186 ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
3187 wm8994_drc_controls,
3188 ARRAY_SIZE(wm8994_drc_controls));
3149 } 3189 }
3150 3190
3191 if (ret != 0)
3192 dev_err(wm8994->hubs.codec->dev,
3193 "Failed to add DRC mode controls: %d\n", ret);
3194
3195
3151 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", 3196 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3152 pdata->num_retune_mobile_cfgs); 3197 pdata->num_retune_mobile_cfgs);
3153 3198
3154 if (pdata->num_retune_mobile_cfgs) 3199 if (pdata->num_retune_mobile_cfgs)
3155 wm8994_handle_retune_mobile_pdata(wm8994); 3200 wm8994_handle_retune_mobile_pdata(wm8994);
3156 else 3201 else
3157 snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls, 3202 snd_soc_add_codec_controls(wm8994->hubs.codec, wm8994_eq_controls,
3158 ARRAY_SIZE(wm8994_eq_controls)); 3203 ARRAY_SIZE(wm8994_eq_controls));
3159 3204
3160 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { 3205 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -3236,6 +3281,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3236 3281
3237 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); 3282 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
3238 3283
3284 /* enable MICDET and MICSHRT deboune */
3285 snd_soc_update_bits(codec, WM8994_IRQ_DEBOUNCE,
3286 WM8994_MIC1_DET_DB_MASK | WM8994_MIC1_SHRT_DB_MASK |
3287 WM8994_MIC2_DET_DB_MASK | WM8994_MIC2_SHRT_DB_MASK,
3288 WM8994_MIC1_DET_DB | WM8994_MIC1_SHRT_DB);
3289
3239 snd_soc_dapm_sync(&codec->dapm); 3290 snd_soc_dapm_sync(&codec->dapm);
3240 3291
3241 return 0; 3292 return 0;
@@ -3309,7 +3360,7 @@ static void wm8994_mic_work(struct work_struct *work)
3309static irqreturn_t wm8994_mic_irq(int irq, void *data) 3360static irqreturn_t wm8994_mic_irq(int irq, void *data)
3310{ 3361{
3311 struct wm8994_priv *priv = data; 3362 struct wm8994_priv *priv = data;
3312 struct snd_soc_codec *codec = priv->codec; 3363 struct snd_soc_codec *codec = priv->hubs.codec;
3313 3364
3314#ifndef CONFIG_SND_SOC_WM8994_MODULE 3365#ifndef CONFIG_SND_SOC_WM8994_MODULE
3315 trace_snd_soc_jack_irq(dev_name(codec->dev)); 3366 trace_snd_soc_jack_irq(dev_name(codec->dev));
@@ -3345,7 +3396,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3345 3396
3346 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 3397 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3347 wm8994->btn_mask | 3398 wm8994->btn_mask |
3348 SND_JACK_HEADSET); 3399 SND_JACK_HEADSET);
3349 } 3400 }
3350 return; 3401 return;
3351 } 3402 }
@@ -3422,7 +3473,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3422static irqreturn_t wm1811_jackdet_irq(int irq, void *data) 3473static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3423{ 3474{
3424 struct wm8994_priv *wm8994 = data; 3475 struct wm8994_priv *wm8994 = data;
3425 struct snd_soc_codec *codec = wm8994->codec; 3476 struct snd_soc_codec *codec = wm8994->hubs.codec;
3426 int reg; 3477 int reg;
3427 bool present; 3478 bool present;
3428 3479
@@ -3499,10 +3550,22 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3499 SND_JACK_MECHANICAL | SND_JACK_HEADSET | 3550 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3500 wm8994->btn_mask); 3551 wm8994->btn_mask);
3501 3552
3553 /* Since we only report deltas force an update, ensures we
3554 * avoid bootstrapping issues with the core. */
3555 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0);
3556
3502 pm_runtime_put(codec->dev); 3557 pm_runtime_put(codec->dev);
3503 return IRQ_HANDLED; 3558 return IRQ_HANDLED;
3504} 3559}
3505 3560
3561static void wm1811_jackdet_bootstrap(struct work_struct *work)
3562{
3563 struct wm8994_priv *wm8994 = container_of(work,
3564 struct wm8994_priv,
3565 jackdet_bootstrap.work);
3566 wm1811_jackdet_irq(0, wm8994);
3567}
3568
3506/** 3569/**
3507 * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ 3570 * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
3508 * 3571 *
@@ -3573,6 +3636,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3573 * otherwise jump straight to microphone detection. 3636 * otherwise jump straight to microphone detection.
3574 */ 3637 */
3575 if (wm8994->jackdet) { 3638 if (wm8994->jackdet) {
3639 /* Disable debounce for the initial detect */
3640 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3641 WM1811_JACKDET_DB, 0);
3642
3576 snd_soc_update_bits(codec, WM8958_MICBIAS2, 3643 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3577 WM8958_MICB2_DISCH, 3644 WM8958_MICB2_DISCH,
3578 WM8958_MICB2_DISCH); 3645 WM8958_MICB2_DISCH);
@@ -3600,7 +3667,7 @@ EXPORT_SYMBOL_GPL(wm8958_mic_detect);
3600static irqreturn_t wm8958_mic_irq(int irq, void *data) 3667static irqreturn_t wm8958_mic_irq(int irq, void *data)
3601{ 3668{
3602 struct wm8994_priv *wm8994 = data; 3669 struct wm8994_priv *wm8994 = data;
3603 struct snd_soc_codec *codec = wm8994->codec; 3670 struct snd_soc_codec *codec = wm8994->hubs.codec;
3604 int reg, count; 3671 int reg, count;
3605 3672
3606 /* 3673 /*
@@ -3690,15 +3757,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3690 unsigned int reg; 3757 unsigned int reg;
3691 int ret, i; 3758 int ret, i;
3692 3759
3693 wm8994->codec = codec; 3760 wm8994->hubs.codec = codec;
3694 codec->control_data = control->regmap; 3761 codec->control_data = control->regmap;
3695 3762
3696 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); 3763 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
3697 3764
3698 wm8994->codec = codec;
3699
3700 mutex_init(&wm8994->accdet_lock); 3765 mutex_init(&wm8994->accdet_lock);
3701 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); 3766 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
3767 INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
3768 wm1811_jackdet_bootstrap);
3702 3769
3703 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) 3770 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3704 init_completion(&wm8994->fll_locked[i]); 3771 init_completion(&wm8994->fll_locked[i]);
@@ -3756,14 +3823,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3756 wm8994->hubs.no_cache_dac_hp_direct = true; 3823 wm8994->hubs.no_cache_dac_hp_direct = true;
3757 wm8994->fll_byp = true; 3824 wm8994->fll_byp = true;
3758 3825
3759 switch (wm8994->revision) { 3826 switch (control->cust_id) {
3760 case 0: 3827 case 0:
3761 case 1:
3762 case 2: 3828 case 2:
3763 case 3:
3764 wm8994->hubs.dcs_codes_l = -9; 3829 wm8994->hubs.dcs_codes_l = -9;
3765 wm8994->hubs.dcs_codes_r = -7; 3830 wm8994->hubs.dcs_codes_r = -7;
3766 break; 3831 break;
3832 case 1:
3833 case 3:
3834 wm8994->hubs.dcs_codes_l = -8;
3835 wm8994->hubs.dcs_codes_r = -7;
3836 break;
3767 default: 3837 default:
3768 break; 3838 break;
3769 } 3839 }
@@ -3852,7 +3922,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3852 3922
3853 switch (control->type) { 3923 switch (control->type) {
3854 case WM1811: 3924 case WM1811:
3855 if (wm8994->revision > 1) { 3925 if (control->cust_id > 1 || wm8994->revision > 1) {
3856 ret = wm8994_request_irq(wm8994->wm8994, 3926 ret = wm8994_request_irq(wm8994->wm8994,
3857 WM8994_IRQ_GPIO(6), 3927 WM8994_IRQ_GPIO(6),
3858 wm1811_jackdet_irq, "JACKDET", 3928 wm1811_jackdet_irq, "JACKDET",
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index d77e06f0a675..f142ec198db3 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -28,10 +28,11 @@
28#define WM8994_FLL1 1 28#define WM8994_FLL1 1
29#define WM8994_FLL2 2 29#define WM8994_FLL2 2
30 30
31#define WM8994_FLL_SRC_MCLK1 1 31#define WM8994_FLL_SRC_MCLK1 1
32#define WM8994_FLL_SRC_MCLK2 2 32#define WM8994_FLL_SRC_MCLK2 2
33#define WM8994_FLL_SRC_LRCLK 3 33#define WM8994_FLL_SRC_LRCLK 3
34#define WM8994_FLL_SRC_BCLK 4 34#define WM8994_FLL_SRC_BCLK 4
35#define WM8994_FLL_SRC_INTERNAL 5
35 36
36enum wm8994_vmid_mode { 37enum wm8994_vmid_mode {
37 WM8994_VMID_NORMAL, 38 WM8994_VMID_NORMAL,
@@ -72,7 +73,6 @@ struct wm8994;
72struct wm8994_priv { 73struct wm8994_priv {
73 struct wm_hubs_data hubs; 74 struct wm_hubs_data hubs;
74 struct wm8994 *wm8994; 75 struct wm8994 *wm8994;
75 struct snd_soc_codec *codec;
76 int sysclk[2]; 76 int sysclk[2];
77 int sysclk_rate[2]; 77 int sysclk_rate[2];
78 int mclk[2]; 78 int mclk[2];
@@ -81,6 +81,7 @@ struct wm8994_priv {
81 struct completion fll_locked[2]; 81 struct completion fll_locked[2];
82 bool fll_locked_irq; 82 bool fll_locked_irq;
83 bool fll_byp; 83 bool fll_byp;
84 bool clk_has_run;
84 85
85 int vmid_refcount; 86 int vmid_refcount;
86 int active_refcount; 87 int active_refcount;
@@ -134,6 +135,7 @@ struct wm8994_priv {
134 int btn_mask; 135 int btn_mask;
135 bool jackdet; 136 bool jackdet;
136 int jackdet_mode; 137 int jackdet_mode;
138 struct delayed_work jackdet_bootstrap;
137 139
138 wm8958_micdet_cb jack_cb; 140 wm8958_micdet_cb jack_cb;
139 void *jack_cb_data; 141 void *jack_cb_data;
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 2c2346fdd637..c7ddc56175d1 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -695,17 +695,7 @@ static struct i2c_driver wm9090_i2c_driver = {
695 .id_table = wm9090_id, 695 .id_table = wm9090_id,
696}; 696};
697 697
698static int __init wm9090_init(void) 698module_i2c_driver(wm9090_i2c_driver);
699{
700 return i2c_add_driver(&wm9090_i2c_driver);
701}
702module_init(wm9090_init);
703
704static void __exit wm9090_exit(void)
705{
706 i2c_del_driver(&wm9090_i2c_driver);
707}
708module_exit(wm9090_exit);
709 699
710MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 700MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
711MODULE_DESCRIPTION("WM9090 ASoC driver"); 701MODULE_DESCRIPTION("WM9090 ASoC driver");
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index c6d2076a796b..1992a6295a16 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -132,8 +132,9 @@ SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1),
132SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1), 132SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1),
133SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), 133SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1),
134 134
135SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), 135SOC_SINGLE_TLV("Capture Boost Switch", AC97_REC_SEL, 14, 1, 0, boost_tlv),
136SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), 136SOC_SINGLE_TLV("Capture to Phone Boost Switch", AC97_REC_SEL, 11, 1, 1,
137 boost_tlv),
137 138
138SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), 139SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
139SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), 140SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
@@ -146,7 +147,7 @@ SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
146SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1), 147SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1),
147SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), 148SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
148 149
149SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), 150SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
150SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), 151SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
151SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0), 152SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0),
152SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), 153SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
@@ -699,8 +700,8 @@ static int __devexit wm9712_remove(struct platform_device *pdev)
699 700
700static struct platform_driver wm9712_codec_driver = { 701static struct platform_driver wm9712_codec_driver = {
701 .driver = { 702 .driver = {
702 .name = "wm9712-codec", 703 .name = "wm9712-codec",
703 .owner = THIS_MODULE, 704 .owner = THIS_MODULE,
704 }, 705 },
705 706
706 .probe = wm9712_probe, 707 .probe = wm9712_probe,
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 61baa48823cb..7a773a835b8e 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -199,15 +199,56 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg)
199 list_add_tail(&cache->list, &hubs->dcs_cache); 199 list_add_tail(&cache->list, &hubs->dcs_cache);
200} 200}
201 201
202static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec,
203 u16 *reg_l, u16 *reg_r)
204{
205 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
206 u16 dcs_reg, reg;
207
208 switch (hubs->dcs_readback_mode) {
209 case 2:
210 dcs_reg = WM8994_DC_SERVO_4E;
211 break;
212 case 1:
213 dcs_reg = WM8994_DC_SERVO_READBACK;
214 break;
215 default:
216 dcs_reg = WM8993_DC_SERVO_3;
217 break;
218 }
219
220 /* Different chips in the family support different readback
221 * methods.
222 */
223 switch (hubs->dcs_readback_mode) {
224 case 0:
225 *reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
226 & WM8993_DCS_INTEG_CHAN_0_MASK;
227 *reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
228 & WM8993_DCS_INTEG_CHAN_1_MASK;
229 break;
230 case 2:
231 case 1:
232 reg = snd_soc_read(codec, dcs_reg);
233 *reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
234 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
235 *reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
236 break;
237 default:
238 WARN(1, "Unknown DCS readback method\n");
239 return;
240 }
241}
242
202/* 243/*
203 * Startup calibration of the DC servo 244 * Startup calibration of the DC servo
204 */ 245 */
205static void calibrate_dc_servo(struct snd_soc_codec *codec) 246static void enable_dc_servo(struct snd_soc_codec *codec)
206{ 247{
207 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 248 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
208 struct wm_hubs_dcs_cache *cache; 249 struct wm_hubs_dcs_cache *cache;
209 s8 offset; 250 s8 offset;
210 u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg; 251 u16 reg_l, reg_r, dcs_cfg, dcs_reg;
211 252
212 switch (hubs->dcs_readback_mode) { 253 switch (hubs->dcs_readback_mode) {
213 case 2: 254 case 2:
@@ -245,27 +286,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
245 WM8993_DCS_TRIG_STARTUP_1); 286 WM8993_DCS_TRIG_STARTUP_1);
246 } 287 }
247 288
248 /* Different chips in the family support different readback 289 wm_hubs_read_dc_servo(codec, &reg_l, &reg_r);
249 * methods.
250 */
251 switch (hubs->dcs_readback_mode) {
252 case 0:
253 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
254 & WM8993_DCS_INTEG_CHAN_0_MASK;
255 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
256 & WM8993_DCS_INTEG_CHAN_1_MASK;
257 break;
258 case 2:
259 case 1:
260 reg = snd_soc_read(codec, dcs_reg);
261 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
262 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
263 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
264 break;
265 default:
266 WARN(1, "Unknown DCS readback method\n");
267 return;
268 }
269 290
270 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); 291 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
271 292
@@ -276,12 +297,16 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
276 hubs->dcs_codes_l, hubs->dcs_codes_r); 297 hubs->dcs_codes_l, hubs->dcs_codes_r);
277 298
278 /* HPOUT1R */ 299 /* HPOUT1R */
279 offset = reg_r; 300 offset = (s8)reg_r;
301 dev_dbg(codec->dev, "DCS right %d->%d\n", offset,
302 offset + hubs->dcs_codes_r);
280 offset += hubs->dcs_codes_r; 303 offset += hubs->dcs_codes_r;
281 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; 304 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
282 305
283 /* HPOUT1L */ 306 /* HPOUT1L */
284 offset = reg_l; 307 offset = (s8)reg_l;
308 dev_dbg(codec->dev, "DCS left %d->%d\n", offset,
309 offset + hubs->dcs_codes_l);
285 offset += hubs->dcs_codes_l; 310 offset += hubs->dcs_codes_l;
286 dcs_cfg |= (u8)offset; 311 dcs_cfg |= (u8)offset;
287 312
@@ -535,7 +560,7 @@ static int hp_event(struct snd_soc_dapm_widget *w,
535 snd_soc_update_bits(codec, WM8993_DC_SERVO_1, 560 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
536 WM8993_DCS_TIMER_PERIOD_01_MASK, 0); 561 WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
537 562
538 calibrate_dc_servo(codec); 563 enable_dc_servo(codec);
539 564
540 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | 565 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
541 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; 566 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -619,6 +644,28 @@ static int lineout_event(struct snd_soc_dapm_widget *w,
619 return 0; 644 return 0;
620} 645}
621 646
647static int micbias_event(struct snd_soc_dapm_widget *w,
648 struct snd_kcontrol *kcontrol, int event)
649{
650 struct snd_soc_codec *codec = w->codec;
651 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
652
653 switch (w->shift) {
654 case WM8993_MICB1_ENA_SHIFT:
655 if (hubs->micb1_delay)
656 msleep(hubs->micb1_delay);
657 break;
658 case WM8993_MICB2_ENA_SHIFT:
659 if (hubs->micb2_delay)
660 msleep(hubs->micb2_delay);
661 break;
662 default:
663 return -EINVAL;
664 }
665
666 return 0;
667}
668
622void wm_hubs_update_class_w(struct snd_soc_codec *codec) 669void wm_hubs_update_class_w(struct snd_soc_codec *codec)
623{ 670{
624 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 671 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
@@ -809,8 +856,10 @@ SND_SOC_DAPM_INPUT("IN1RP"),
809SND_SOC_DAPM_INPUT("IN2RN"), 856SND_SOC_DAPM_INPUT("IN2RN"),
810SND_SOC_DAPM_INPUT("IN2RP:VXRP"), 857SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
811 858
812SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), 859SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0,
813SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), 860 micbias_event, SND_SOC_DAPM_POST_PMU),
861SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0,
862 micbias_event, SND_SOC_DAPM_POST_PMU),
814 863
815SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, 864SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
816 in1l_pga, ARRAY_SIZE(in1l_pga)), 865 in1l_pga, ARRAY_SIZE(in1l_pga)),
@@ -1112,6 +1161,8 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
1112 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 1161 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1113 struct snd_soc_dapm_context *dapm = &codec->dapm; 1162 struct snd_soc_dapm_context *dapm = &codec->dapm;
1114 1163
1164 hubs->codec = codec;
1165
1115 INIT_LIST_HEAD(&hubs->dcs_cache); 1166 INIT_LIST_HEAD(&hubs->dcs_cache);
1116 init_completion(&hubs->dcs_done); 1167 init_completion(&hubs->dcs_done);
1117 1168
@@ -1143,13 +1194,16 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
1143int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, 1194int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
1144 int lineout1_diff, int lineout2_diff, 1195 int lineout1_diff, int lineout2_diff,
1145 int lineout1fb, int lineout2fb, 1196 int lineout1fb, int lineout2fb,
1146 int jd_scthr, int jd_thr, int micbias1_lvl, 1197 int jd_scthr, int jd_thr,
1147 int micbias2_lvl) 1198 int micbias1_delay, int micbias2_delay,
1199 int micbias1_lvl, int micbias2_lvl)
1148{ 1200{
1149 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 1201 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1150 1202
1151 hubs->lineout1_se = !lineout1_diff; 1203 hubs->lineout1_se = !lineout1_diff;
1152 hubs->lineout2_se = !lineout2_diff; 1204 hubs->lineout2_se = !lineout2_diff;
1205 hubs->micb1_delay = micbias1_delay;
1206 hubs->micb2_delay = micbias2_delay;
1153 1207
1154 if (!lineout1_diff) 1208 if (!lineout1_diff)
1155 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 1209 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index da2dc899ce6d..24c763df21f9 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -36,6 +36,9 @@ struct wm_hubs_data {
36 struct list_head dcs_cache; 36 struct list_head dcs_cache;
37 bool (*check_class_w_digital)(struct snd_soc_codec *); 37 bool (*check_class_w_digital)(struct snd_soc_codec *);
38 38
39 int micb1_delay;
40 int micb2_delay;
41
39 bool lineout1_se; 42 bool lineout1_se;
40 bool lineout1n_ena; 43 bool lineout1n_ena;
41 bool lineout1p_ena; 44 bool lineout1p_ena;
@@ -46,6 +49,8 @@ struct wm_hubs_data {
46 49
47 bool dcs_done_irq; 50 bool dcs_done_irq;
48 struct completion dcs_done; 51 struct completion dcs_done;
52
53 struct snd_soc_codec *codec;
49}; 54};
50 55
51extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 56extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
@@ -54,6 +59,7 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
54 int lineout1_diff, int lineout2_diff, 59 int lineout1_diff, int lineout2_diff,
55 int lineout1fb, int lineout2fb, 60 int lineout1fb, int lineout2fb,
56 int jd_scthr, int jd_thr, 61 int jd_scthr, int jd_thr,
62 int micbias1_dly, int micbias2_dly,
57 int micbias1_lvl, int micbias2_lvl); 63 int micbias1_lvl, int micbias2_lvl);
58 64
59extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); 65extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 10a2d8c788b7..6fac5af13298 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -22,10 +22,6 @@
22#include <asm/dma.h> 22#include <asm/dma.h>
23#include <asm/mach-types.h> 23#include <asm/mach-types.h>
24 24
25#include <mach/asp.h>
26#include <mach/edma.h>
27#include <mach/mux.h>
28
29#include "davinci-pcm.h" 25#include "davinci-pcm.h"
30#include "davinci-i2s.h" 26#include "davinci-i2s.h"
31#include "davinci-mcasp.h" 27#include "davinci-mcasp.h"
@@ -160,7 +156,7 @@ static struct snd_soc_dai_link dm6446_evm_dai = {
160 .cpu_dai_name = "davinci-mcbsp", 156 .cpu_dai_name = "davinci-mcbsp",
161 .codec_dai_name = "tlv320aic3x-hifi", 157 .codec_dai_name = "tlv320aic3x-hifi",
162 .codec_name = "tlv320aic3x-codec.1-001b", 158 .codec_name = "tlv320aic3x-codec.1-001b",
163 .platform_name = "davinci-pcm-audio", 159 .platform_name = "davinci-mcbsp",
164 .init = evm_aic3x_init, 160 .init = evm_aic3x_init,
165 .ops = &evm_ops, 161 .ops = &evm_ops,
166}; 162};
@@ -171,7 +167,7 @@ static struct snd_soc_dai_link dm355_evm_dai = {
171 .cpu_dai_name = "davinci-mcbsp.1", 167 .cpu_dai_name = "davinci-mcbsp.1",
172 .codec_dai_name = "tlv320aic3x-hifi", 168 .codec_dai_name = "tlv320aic3x-hifi",
173 .codec_name = "tlv320aic3x-codec.1-001b", 169 .codec_name = "tlv320aic3x-codec.1-001b",
174 .platform_name = "davinci-pcm-audio", 170 .platform_name = "davinci-mcbsp.1",
175 .init = evm_aic3x_init, 171 .init = evm_aic3x_init,
176 .ops = &evm_ops, 172 .ops = &evm_ops,
177}; 173};
@@ -185,14 +181,15 @@ static struct snd_soc_dai_link dm365_evm_dai = {
185 .init = evm_aic3x_init, 181 .init = evm_aic3x_init,
186 .codec_name = "tlv320aic3x-codec.1-0018", 182 .codec_name = "tlv320aic3x-codec.1-0018",
187 .ops = &evm_ops, 183 .ops = &evm_ops,
184 .platform_name = "davinci-mcbsp",
188#elif defined(CONFIG_SND_DM365_VOICE_CODEC) 185#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
189 .name = "Voice Codec - CQ93VC", 186 .name = "Voice Codec - CQ93VC",
190 .stream_name = "CQ93", 187 .stream_name = "CQ93",
191 .cpu_dai_name = "davinci-vcif", 188 .cpu_dai_name = "davinci-vcif",
192 .codec_dai_name = "cq93vc-hifi", 189 .codec_dai_name = "cq93vc-hifi",
193 .codec_name = "cq93vc-codec", 190 .codec_name = "cq93vc-codec",
191 .platform_name = "davinci-vcif",
194#endif 192#endif
195 .platform_name = "davinci-pcm-audio",
196}; 193};
197 194
198static struct snd_soc_dai_link dm6467_evm_dai[] = { 195static struct snd_soc_dai_link dm6467_evm_dai[] = {
@@ -201,7 +198,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
201 .stream_name = "AIC3X", 198 .stream_name = "AIC3X",
202 .cpu_dai_name= "davinci-mcasp.0", 199 .cpu_dai_name= "davinci-mcasp.0",
203 .codec_dai_name = "tlv320aic3x-hifi", 200 .codec_dai_name = "tlv320aic3x-hifi",
204 .platform_name ="davinci-pcm-audio", 201 .platform_name = "davinci-mcasp.0",
205 .codec_name = "tlv320aic3x-codec.0-001a", 202 .codec_name = "tlv320aic3x-codec.0-001a",
206 .init = evm_aic3x_init, 203 .init = evm_aic3x_init,
207 .ops = &evm_ops, 204 .ops = &evm_ops,
@@ -212,7 +209,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
212 .cpu_dai_name= "davinci-mcasp.1", 209 .cpu_dai_name= "davinci-mcasp.1",
213 .codec_dai_name = "dit-hifi", 210 .codec_dai_name = "dit-hifi",
214 .codec_name = "spdif_dit", 211 .codec_name = "spdif_dit",
215 .platform_name = "davinci-pcm-audio", 212 .platform_name = "davinci-mcasp.1",
216 .ops = &evm_spdif_ops, 213 .ops = &evm_spdif_ops,
217 }, 214 },
218}; 215};
@@ -223,7 +220,7 @@ static struct snd_soc_dai_link da830_evm_dai = {
223 .cpu_dai_name = "davinci-mcasp.1", 220 .cpu_dai_name = "davinci-mcasp.1",
224 .codec_dai_name = "tlv320aic3x-hifi", 221 .codec_dai_name = "tlv320aic3x-hifi",
225 .codec_name = "tlv320aic3x-codec.1-0018", 222 .codec_name = "tlv320aic3x-codec.1-0018",
226 .platform_name = "davinci-pcm-audio", 223 .platform_name = "davinci-mcasp.1",
227 .init = evm_aic3x_init, 224 .init = evm_aic3x_init,
228 .ops = &evm_ops, 225 .ops = &evm_ops,
229}; 226};
@@ -234,7 +231,7 @@ static struct snd_soc_dai_link da850_evm_dai = {
234 .cpu_dai_name= "davinci-mcasp.0", 231 .cpu_dai_name= "davinci-mcasp.0",
235 .codec_dai_name = "tlv320aic3x-hifi", 232 .codec_dai_name = "tlv320aic3x-hifi",
236 .codec_name = "tlv320aic3x-codec.1-0018", 233 .codec_name = "tlv320aic3x-codec.1-0018",
237 .platform_name = "davinci-pcm-audio", 234 .platform_name = "davinci-mcasp.0",
238 .init = evm_aic3x_init, 235 .init = evm_aic3x_init,
239 .ops = &evm_ops, 236 .ops = &evm_ops,
240}; 237};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 0a74b9587a2c..821831207180 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/platform_data/davinci_asp.h>
19 20
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
@@ -23,8 +24,6 @@
23#include <sound/initval.h> 24#include <sound/initval.h>
24#include <sound/soc.h> 25#include <sound/soc.h>
25 26
26#include <mach/asp.h>
27
28#include "davinci-pcm.h" 27#include "davinci-pcm.h"
29#include "davinci-i2s.h" 28#include "davinci-i2s.h"
30 29
@@ -732,8 +731,16 @@ static int davinci_i2s_probe(struct platform_device *pdev)
732 if (ret != 0) 731 if (ret != 0)
733 goto err_release_clk; 732 goto err_release_clk;
734 733
734 ret = davinci_soc_platform_register(&pdev->dev);
735 if (ret) {
736 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
737 goto err_unregister_dai;
738 }
739
735 return 0; 740 return 0;
736 741
742err_unregister_dai:
743 snd_soc_unregister_dai(&pdev->dev);
737err_release_clk: 744err_release_clk:
738 clk_disable(dev->clk); 745 clk_disable(dev->clk);
739 clk_put(dev->clk); 746 clk_put(dev->clk);
@@ -745,6 +752,8 @@ static int davinci_i2s_remove(struct platform_device *pdev)
745 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); 752 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
746 753
747 snd_soc_unregister_dai(&pdev->dev); 754 snd_soc_unregister_dai(&pdev->dev);
755 davinci_soc_platform_unregister(&pdev->dev);
756
748 clk_disable(dev->clk); 757 clk_disable(dev->clk);
749 clk_put(dev->clk); 758 clk_put(dev->clk);
750 dev->clk = NULL; 759 dev->clk = NULL;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index ce5e5cd254dd..c3eae1d8e077 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -21,7 +21,10 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clk.h> 24#include <linux/pm_runtime.h>
25#include <linux/of.h>
26#include <linux/of_platform.h>
27#include <linux/of_device.h>
25 28
26#include <sound/core.h> 29#include <sound/core.h>
27#include <sound/pcm.h> 30#include <sound/pcm.h>
@@ -782,20 +785,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
782 case SNDRV_PCM_TRIGGER_RESUME: 785 case SNDRV_PCM_TRIGGER_RESUME:
783 case SNDRV_PCM_TRIGGER_START: 786 case SNDRV_PCM_TRIGGER_START:
784 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 787 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
785 if (!dev->clk_active) { 788 ret = pm_runtime_get_sync(dev->dev);
786 clk_enable(dev->clk); 789 if (IS_ERR_VALUE(ret))
787 dev->clk_active = 1; 790 dev_err(dev->dev, "pm_runtime_get_sync() failed\n");
788 }
789 davinci_mcasp_start(dev, substream->stream); 791 davinci_mcasp_start(dev, substream->stream);
790 break; 792 break;
791 793
792 case SNDRV_PCM_TRIGGER_SUSPEND: 794 case SNDRV_PCM_TRIGGER_SUSPEND:
793 davinci_mcasp_stop(dev, substream->stream); 795 davinci_mcasp_stop(dev, substream->stream);
794 if (dev->clk_active) { 796 ret = pm_runtime_put_sync(dev->dev);
795 clk_disable(dev->clk); 797 if (IS_ERR_VALUE(ret))
796 dev->clk_active = 0; 798 dev_err(dev->dev, "pm_runtime_put_sync() failed\n");
797 }
798
799 break; 799 break;
800 800
801 case SNDRV_PCM_TRIGGER_STOP: 801 case SNDRV_PCM_TRIGGER_STOP:
@@ -865,6 +865,114 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
865 865
866}; 866};
867 867
868static const struct of_device_id mcasp_dt_ids[] = {
869 {
870 .compatible = "ti,dm646x-mcasp-audio",
871 .data = (void *)MCASP_VERSION_1,
872 },
873 {
874 .compatible = "ti,da830-mcasp-audio",
875 .data = (void *)MCASP_VERSION_2,
876 },
877 { /* sentinel */ }
878};
879MODULE_DEVICE_TABLE(of, mcasp_dt_ids);
880
881static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
882 struct platform_device *pdev)
883{
884 struct device_node *np = pdev->dev.of_node;
885 struct snd_platform_data *pdata = NULL;
886 const struct of_device_id *match =
887 of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev);
888
889 const u32 *of_serial_dir32;
890 u8 *of_serial_dir;
891 u32 val;
892 int i, ret = 0;
893
894 if (pdev->dev.platform_data) {
895 pdata = pdev->dev.platform_data;
896 return pdata;
897 } else if (match) {
898 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
899 if (!pdata) {
900 ret = -ENOMEM;
901 goto nodata;
902 }
903 } else {
904 /* control shouldn't reach here. something is wrong */
905 ret = -EINVAL;
906 goto nodata;
907 }
908
909 if (match->data)
910 pdata->version = (u8)((int)match->data);
911
912 ret = of_property_read_u32(np, "op-mode", &val);
913 if (ret >= 0)
914 pdata->op_mode = val;
915
916 ret = of_property_read_u32(np, "tdm-slots", &val);
917 if (ret >= 0)
918 pdata->tdm_slots = val;
919
920 ret = of_property_read_u32(np, "num-serializer", &val);
921 if (ret >= 0)
922 pdata->num_serializer = val;
923
924 of_serial_dir32 = of_get_property(np, "serial-dir", &val);
925 val /= sizeof(u32);
926 if (val != pdata->num_serializer) {
927 dev_err(&pdev->dev,
928 "num-serializer(%d) != serial-dir size(%d)\n",
929 pdata->num_serializer, val);
930 ret = -EINVAL;
931 goto nodata;
932 }
933
934 if (of_serial_dir32) {
935 of_serial_dir = devm_kzalloc(&pdev->dev,
936 (sizeof(*of_serial_dir) * val),
937 GFP_KERNEL);
938 if (!of_serial_dir) {
939 ret = -ENOMEM;
940 goto nodata;
941 }
942
943 for (i = 0; i < pdata->num_serializer; i++)
944 of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]);
945
946 pdata->serial_dir = of_serial_dir;
947 }
948
949 ret = of_property_read_u32(np, "tx-num-evt", &val);
950 if (ret >= 0)
951 pdata->txnumevt = val;
952
953 ret = of_property_read_u32(np, "rx-num-evt", &val);
954 if (ret >= 0)
955 pdata->rxnumevt = val;
956
957 ret = of_property_read_u32(np, "sram-size-playback", &val);
958 if (ret >= 0)
959 pdata->sram_size_playback = val;
960
961 ret = of_property_read_u32(np, "sram-size-capture", &val);
962 if (ret >= 0)
963 pdata->sram_size_capture = val;
964
965 return pdata;
966
967nodata:
968 if (ret < 0) {
969 dev_err(&pdev->dev, "Error populating platform data, err %d\n",
970 ret);
971 pdata = NULL;
972 }
973 return pdata;
974}
975
868static int davinci_mcasp_probe(struct platform_device *pdev) 976static int davinci_mcasp_probe(struct platform_device *pdev)
869{ 977{
870 struct davinci_pcm_dma_params *dma_data; 978 struct davinci_pcm_dma_params *dma_data;
@@ -873,11 +981,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
873 struct davinci_audio_dev *dev; 981 struct davinci_audio_dev *dev;
874 int ret; 982 int ret;
875 983
984 if (!pdev->dev.platform_data && !pdev->dev.of_node) {
985 dev_err(&pdev->dev, "No platform data supplied\n");
986 return -EINVAL;
987 }
988
876 dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev), 989 dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev),
877 GFP_KERNEL); 990 GFP_KERNEL);
878 if (!dev) 991 if (!dev)
879 return -ENOMEM; 992 return -ENOMEM;
880 993
994 pdata = davinci_mcasp_set_pdata_from_of(pdev);
995 if (!pdata) {
996 dev_err(&pdev->dev, "no platform data\n");
997 return -EINVAL;
998 }
999
881 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1000 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
882 if (!mem) { 1001 if (!mem) {
883 dev_err(&pdev->dev, "no mem resource?\n"); 1002 dev_err(&pdev->dev, "no mem resource?\n");
@@ -891,13 +1010,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
891 return -EBUSY; 1010 return -EBUSY;
892 } 1011 }
893 1012
894 pdata = pdev->dev.platform_data; 1013 pm_runtime_enable(&pdev->dev);
895 dev->clk = clk_get(&pdev->dev, NULL);
896 if (IS_ERR(dev->clk))
897 return -ENODEV;
898 1014
899 clk_enable(dev->clk); 1015 ret = pm_runtime_get_sync(&pdev->dev);
900 dev->clk_active = 1; 1016 if (IS_ERR_VALUE(ret)) {
1017 dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
1018 return ret;
1019 }
901 1020
902 dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); 1021 dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
903 if (!dev->base) { 1022 if (!dev->base) {
@@ -914,6 +1033,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
914 dev->version = pdata->version; 1033 dev->version = pdata->version;
915 dev->txnumevt = pdata->txnumevt; 1034 dev->txnumevt = pdata->txnumevt;
916 dev->rxnumevt = pdata->rxnumevt; 1035 dev->rxnumevt = pdata->rxnumevt;
1036 dev->dev = &pdev->dev;
917 1037
918 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 1038 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
919 dma_data->asp_chan_q = pdata->asp_chan_q; 1039 dma_data->asp_chan_q = pdata->asp_chan_q;
@@ -952,22 +1072,31 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
952 1072
953 if (ret != 0) 1073 if (ret != 0)
954 goto err_release_clk; 1074 goto err_release_clk;
1075
1076 ret = davinci_soc_platform_register(&pdev->dev);
1077 if (ret) {
1078 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
1079 goto err_unregister_dai;
1080 }
1081
955 return 0; 1082 return 0;
956 1083
1084err_unregister_dai:
1085 snd_soc_unregister_dai(&pdev->dev);
957err_release_clk: 1086err_release_clk:
958 clk_disable(dev->clk); 1087 pm_runtime_put_sync(&pdev->dev);
959 clk_put(dev->clk); 1088 pm_runtime_disable(&pdev->dev);
960 return ret; 1089 return ret;
961} 1090}
962 1091
963static int davinci_mcasp_remove(struct platform_device *pdev) 1092static int davinci_mcasp_remove(struct platform_device *pdev)
964{ 1093{
965 struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
966 1094
967 snd_soc_unregister_dai(&pdev->dev); 1095 snd_soc_unregister_dai(&pdev->dev);
968 clk_disable(dev->clk); 1096 davinci_soc_platform_unregister(&pdev->dev);
969 clk_put(dev->clk); 1097
970 dev->clk = NULL; 1098 pm_runtime_put_sync(&pdev->dev);
1099 pm_runtime_disable(&pdev->dev);
971 1100
972 return 0; 1101 return 0;
973} 1102}
@@ -978,6 +1107,7 @@ static struct platform_driver davinci_mcasp_driver = {
978 .driver = { 1107 .driver = {
979 .name = "davinci-mcasp", 1108 .name = "davinci-mcasp",
980 .owner = THIS_MODULE, 1109 .owner = THIS_MODULE,
1110 .of_match_table = of_match_ptr(mcasp_dt_ids),
981 }, 1111 },
982}; 1112};
983 1113
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 4681acc63606..0de9ed6ce038 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -19,7 +19,8 @@
19#define DAVINCI_MCASP_H 19#define DAVINCI_MCASP_H
20 20
21#include <linux/io.h> 21#include <linux/io.h>
22#include <mach/asp.h> 22#include <linux/platform_data/davinci_asp.h>
23
23#include "davinci-pcm.h" 24#include "davinci-pcm.h"
24 25
25#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 26#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000
@@ -40,9 +41,8 @@ struct davinci_audio_dev {
40 struct davinci_pcm_dma_params dma_params[2]; 41 struct davinci_pcm_dma_params dma_params[2];
41 void __iomem *base; 42 void __iomem *base;
42 int sample_rate; 43 int sample_rate;
43 struct clk *clk; 44 struct device *dev;
44 unsigned int codec_fmt; 45 unsigned int codec_fmt;
45 u8 clk_active;
46 46
47 /* McASP specific data */ 47 /* McASP specific data */
48 int tdm_slots; 48 int tdm_slots;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 97d77b298968..93ea3bf567e1 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24 24
25#include <asm/dma.h> 25#include <asm/dma.h>
26#include <mach/edma.h>
27#include <mach/sram.h> 26#include <mach/sram.h>
28 27
29#include "davinci-pcm.h" 28#include "davinci-pcm.h"
@@ -864,28 +863,17 @@ static struct snd_soc_platform_driver davinci_soc_platform = {
864 .pcm_free = davinci_pcm_free, 863 .pcm_free = davinci_pcm_free,
865}; 864};
866 865
867static int __devinit davinci_soc_platform_probe(struct platform_device *pdev) 866int davinci_soc_platform_register(struct device *dev)
868{ 867{
869 return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform); 868 return snd_soc_register_platform(dev, &davinci_soc_platform);
870} 869}
870EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
871 871
872static int __devexit davinci_soc_platform_remove(struct platform_device *pdev) 872void davinci_soc_platform_unregister(struct device *dev)
873{ 873{
874 snd_soc_unregister_platform(&pdev->dev); 874 snd_soc_unregister_platform(dev);
875 return 0;
876} 875}
877 876EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister);
878static struct platform_driver davinci_pcm_driver = {
879 .driver = {
880 .name = "davinci-pcm-audio",
881 .owner = THIS_MODULE,
882 },
883
884 .probe = davinci_soc_platform_probe,
885 .remove = __devexit_p(davinci_soc_platform_remove),
886};
887
888module_platform_driver(davinci_pcm_driver);
889 877
890MODULE_AUTHOR("Vladimir Barinov"); 878MODULE_AUTHOR("Vladimir Barinov");
891MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); 879MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index c0d6c9be4b4d..fc4d01cdd8c9 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,9 +12,8 @@
12#ifndef _DAVINCI_PCM_H 12#ifndef _DAVINCI_PCM_H
13#define _DAVINCI_PCM_H 13#define _DAVINCI_PCM_H
14 14
15#include <linux/platform_data/davinci_asp.h>
15#include <mach/edma.h> 16#include <mach/edma.h>
16#include <mach/asp.h>
17
18 17
19struct davinci_pcm_dma_params { 18struct davinci_pcm_dma_params {
20 int channel; /* sync dma channel ID */ 19 int channel; /* sync dma channel ID */
@@ -28,4 +27,7 @@ struct davinci_pcm_dma_params {
28 unsigned int fifo_level; 27 unsigned int fifo_level;
29}; 28};
30 29
30int davinci_soc_platform_register(struct device *dev);
31void davinci_soc_platform_unregister(struct device *dev);
32
31#endif 33#endif
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index f71175b29e38..5be65aae7e0e 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -86,7 +86,7 @@ static struct snd_soc_dai_link sffsdr_dai = {
86 .cpu_dai_name = "davinci-mcbsp", 86 .cpu_dai_name = "davinci-mcbsp",
87 .codec_dai_name = "pcm3008-hifi", 87 .codec_dai_name = "pcm3008-hifi",
88 .codec_name = "pcm3008-codec", 88 .codec_name = "pcm3008-codec",
89 .platform_name = "davinci-pcm-audio", 89 .platform_name = "davinci-mcbsp",
90 .ops = &sffsdr_ops, 90 .ops = &sffsdr_ops,
91}; 91};
92 92
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index da030ff883d5..07bde2e6f84e 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -240,12 +240,20 @@ static int davinci_vcif_probe(struct platform_device *pdev)
240 return ret; 240 return ret;
241 } 241 }
242 242
243 ret = davinci_soc_platform_register(&pdev->dev);
244 if (ret) {
245 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
246 snd_soc_unregister_dai(&pdev->dev);
247 return ret;
248 }
249
243 return 0; 250 return 0;
244} 251}
245 252
246static int davinci_vcif_remove(struct platform_device *pdev) 253static int davinci_vcif_remove(struct platform_device *pdev)
247{ 254{
248 snd_soc_unregister_dai(&pdev->dev); 255 snd_soc_unregister_dai(&pdev->dev);
256 davinci_soc_platform_unregister(&pdev->dev);
249 257
250 return 0; 258 return 0;
251} 259}
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 81d7728cf67f..7074ae689984 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -524,7 +524,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
524 int ret = 0; 524 int ret = 0;
525 struct snd_soc_dai_driver *dai; 525 struct snd_soc_dai_driver *dai;
526 526
527 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); 527 ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL);
528 if (!ssi) 528 if (!ssi)
529 return -ENOMEM; 529 return -ENOMEM;
530 dev_set_drvdata(&pdev->dev, ssi); 530 dev_set_drvdata(&pdev->dev, ssi);
@@ -537,7 +537,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
537 537
538 ssi->irq = platform_get_irq(pdev, 0); 538 ssi->irq = platform_get_irq(pdev, 0);
539 539
540 ssi->clk = clk_get(&pdev->dev, NULL); 540 ssi->clk = devm_clk_get(&pdev->dev, NULL);
541 if (IS_ERR(ssi->clk)) { 541 if (IS_ERR(ssi->clk)) {
542 ret = PTR_ERR(ssi->clk); 542 ret = PTR_ERR(ssi->clk);
543 dev_err(&pdev->dev, "Cannot get the clock: %d\n", 543 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
@@ -552,23 +552,18 @@ static int imx_ssi_probe(struct platform_device *pdev)
552 goto failed_get_resource; 552 goto failed_get_resource;
553 } 553 }
554 554
555 if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) { 555 ssi->base = devm_request_and_ioremap(&pdev->dev, res);
556 dev_err(&pdev->dev, "request_mem_region failed\n");
557 ret = -EBUSY;
558 goto failed_get_resource;
559 }
560
561 ssi->base = ioremap(res->start, resource_size(res));
562 if (!ssi->base) { 556 if (!ssi->base) {
563 dev_err(&pdev->dev, "ioremap failed\n"); 557 dev_err(&pdev->dev, "ioremap failed\n");
564 ret = -ENODEV; 558 ret = -ENODEV;
565 goto failed_ioremap; 559 goto failed_register;
566 } 560 }
567 561
568 if (ssi->flags & IMX_SSI_USE_AC97) { 562 if (ssi->flags & IMX_SSI_USE_AC97) {
569 if (ac97_ssi) { 563 if (ac97_ssi) {
564 dev_err(&pdev->dev, "AC'97 SSI already registered\n");
570 ret = -EBUSY; 565 ret = -EBUSY;
571 goto failed_ac97; 566 goto failed_register;
572 } 567 }
573 ac97_ssi = ssi; 568 ac97_ssi = ssi;
574 setup_channel_to_ac97(ssi); 569 setup_channel_to_ac97(ssi);
@@ -637,15 +632,10 @@ failed_pdev_fiq_add:
637failed_pdev_fiq_alloc: 632failed_pdev_fiq_alloc:
638 snd_soc_unregister_dai(&pdev->dev); 633 snd_soc_unregister_dai(&pdev->dev);
639failed_register: 634failed_register:
640failed_ac97:
641 iounmap(ssi->base);
642failed_ioremap:
643 release_mem_region(res->start, resource_size(res)); 635 release_mem_region(res->start, resource_size(res));
644failed_get_resource: 636failed_get_resource:
645 clk_disable_unprepare(ssi->clk); 637 clk_disable_unprepare(ssi->clk);
646 clk_put(ssi->clk);
647failed_clk: 638failed_clk:
648 kfree(ssi);
649 639
650 return ret; 640 return ret;
651} 641}
@@ -663,11 +653,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
663 if (ssi->flags & IMX_SSI_USE_AC97) 653 if (ssi->flags & IMX_SSI_USE_AC97)
664 ac97_ssi = NULL; 654 ac97_ssi = NULL;
665 655
666 iounmap(ssi->base);
667 release_mem_region(res->start, resource_size(res)); 656 release_mem_region(res->start, resource_size(res));
668 clk_disable_unprepare(ssi->clk); 657 clk_disable_unprepare(ssi->clk);
669 clk_put(ssi->clk);
670 kfree(ssi);
671 658
672 return 0; 659 return 0;
673} 660}
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 2937e54da49e..2cc7782714b5 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -318,6 +318,15 @@ static struct snd_soc_dai_link mfld_msic_dailink[] = {
318 .platform_name = "sst-platform", 318 .platform_name = "sst-platform",
319 .init = NULL, 319 .init = NULL,
320 }, 320 },
321 {
322 .name = "Medfield Compress",
323 .stream_name = "Speaker",
324 .cpu_dai_name = "Compress-cpu-dai",
325 .codec_dai_name = "SN95031 Speaker",
326 .codec_name = "sn95031",
327 .platform_name = "sst-platform",
328 .init = NULL,
329 },
321}; 330};
322 331
323/* SoC card */ 332/* SoC card */
diff --git a/sound/soc/mid-x86/sst_dsp.h b/sound/soc/mid-x86/sst_dsp.h
new file mode 100644
index 000000000000..0fce1de284ff
--- /dev/null
+++ b/sound/soc/mid-x86/sst_dsp.h
@@ -0,0 +1,134 @@
1#ifndef __SST_DSP_H__
2#define __SST_DSP_H__
3/*
4 * sst_dsp.h - Intel SST Driver for audio engine
5 *
6 * Copyright (C) 2008-12 Intel Corporation
7 * Authors: Vinod Koul <vinod.koul@linux.intel.com>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
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 along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
25
26enum sst_codec_types {
27 /* AUDIO/MUSIC CODEC Type Definitions */
28 SST_CODEC_TYPE_UNKNOWN = 0,
29 SST_CODEC_TYPE_PCM, /* Pass through Audio codec */
30 SST_CODEC_TYPE_MP3,
31 SST_CODEC_TYPE_MP24,
32 SST_CODEC_TYPE_AAC,
33 SST_CODEC_TYPE_AACP,
34 SST_CODEC_TYPE_eAACP,
35};
36
37enum stream_type {
38 SST_STREAM_TYPE_NONE = 0,
39 SST_STREAM_TYPE_MUSIC = 1,
40};
41
42struct snd_pcm_params {
43 u16 codec; /* codec type */
44 u8 num_chan; /* 1=Mono, 2=Stereo */
45 u8 pcm_wd_sz; /* 16/24 - bit*/
46 u32 reserved; /* Bitrate in bits per second */
47 u32 sfreq; /* Sampling rate in Hz */
48 u8 use_offload_path;
49 u8 reserved2;
50 u16 reserved3;
51 u8 channel_map[8];
52} __packed;
53
54/* MP3 Music Parameters Message */
55struct snd_mp3_params {
56 u16 codec;
57 u8 num_chan; /* 1=Mono, 2=Stereo */
58 u8 pcm_wd_sz; /* 16/24 - bit*/
59 u8 crc_check; /* crc_check - disable (0) or enable (1) */
60 u8 reserved1; /* unused*/
61 u16 reserved2; /* Unused */
62} __packed;
63
64#define AAC_BIT_STREAM_ADTS 0
65#define AAC_BIT_STREAM_ADIF 1
66#define AAC_BIT_STREAM_RAW 2
67
68/* AAC Music Parameters Message */
69struct snd_aac_params {
70 u16 codec;
71 u8 num_chan; /* 1=Mono, 2=Stereo*/
72 u8 pcm_wd_sz; /* 16/24 - bit*/
73 u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */
74 u8 bs_format; /* input bit stream format adts=0, adif=1, raw=2 */
75 u16 reser2;
76 u32 externalsr; /*sampling rate of basic AAC raw bit stream*/
77 u8 sbr_signalling;/*disable/enable/set automode the SBR tool.AAC+*/
78 u8 reser1;
79 u16 reser3;
80} __packed;
81
82/* WMA Music Parameters Message */
83struct snd_wma_params {
84 u16 codec;
85 u8 num_chan; /* 1=Mono, 2=Stereo */
86 u8 pcm_wd_sz; /* 16/24 - bit*/
87 u32 brate; /* Use the hard coded value. */
88 u32 sfreq; /* Sampling freq eg. 8000, 441000, 48000 */
89 u32 channel_mask; /* Channel Mask */
90 u16 format_tag; /* Format Tag */
91 u16 block_align; /* packet size */
92 u16 wma_encode_opt;/* Encoder option */
93 u8 op_align; /* op align 0- 16 bit, 1- MSB, 2 LSB */
94 u8 reserved; /* reserved */
95} __packed;
96
97/* Codec params struture */
98union snd_sst_codec_params {
99 struct snd_pcm_params pcm_params;
100 struct snd_mp3_params mp3_params;
101 struct snd_aac_params aac_params;
102 struct snd_wma_params wma_params;
103} __packed;
104
105/* Address and size info of a frame buffer */
106struct sst_address_info {
107 u32 addr; /* Address at IA */
108 u32 size; /* Size of the buffer */
109};
110
111struct snd_sst_alloc_params_ext {
112 struct sst_address_info ring_buf_info[8];
113 u8 sg_count;
114 u8 reserved;
115 u16 reserved2;
116 u32 frag_size; /*Number of samples after which period elapsed
117 message is sent valid only if path = 0*/
118} __packed;
119
120struct snd_sst_stream_params {
121 union snd_sst_codec_params uc;
122} __packed;
123
124struct snd_sst_params {
125 u32 stream_id;
126 u8 codec;
127 u8 ops;
128 u8 stream_type;
129 u8 device_type;
130 struct snd_sst_stream_params sparams;
131 struct snd_sst_alloc_params_ext aparams;
132};
133
134#endif /* __SST_DSP_H__ */
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index d34563b12c3b..a263cbed8624 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * sst_platform.c - Intel MID Platform driver 2 * sst_platform.c - Intel MID Platform driver
3 * 3 *
4 * Copyright (C) 2010 Intel Corp 4 * Copyright (C) 2010-2012 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com> 5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com> 6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -32,6 +32,7 @@
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <sound/compress_driver.h>
35#include "sst_platform.h" 36#include "sst_platform.h"
36 37
37static struct sst_device *sst; 38static struct sst_device *sst;
@@ -152,6 +153,16 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
152 .formats = SNDRV_PCM_FMTBIT_S24_LE, 153 .formats = SNDRV_PCM_FMTBIT_S24_LE,
153 }, 154 },
154}, 155},
156{
157 .name = "Compress-cpu-dai",
158 .compress_dai = 1,
159 .playback = {
160 .channels_min = SST_STEREO,
161 .channels_max = SST_STEREO,
162 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
163 .formats = SNDRV_PCM_FMTBIT_S16_LE,
164 },
165},
155}; 166};
156 167
157/* helper functions */ 168/* helper functions */
@@ -463,8 +474,199 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
463 } 474 }
464 return retval; 475 return retval;
465} 476}
477
478/* compress stream operations */
479static void sst_compr_fragment_elapsed(void *arg)
480{
481 struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;
482
483 pr_debug("fragment elapsed by driver\n");
484 if (cstream)
485 snd_compr_fragment_elapsed(cstream);
486}
487
488static int sst_platform_compr_open(struct snd_compr_stream *cstream)
489{
490
491 int ret_val = 0;
492 struct snd_compr_runtime *runtime = cstream->runtime;
493 struct sst_runtime_stream *stream;
494
495 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
496 if (!stream)
497 return -ENOMEM;
498
499 spin_lock_init(&stream->status_lock);
500
501 /* get the sst ops */
502 if (!sst || !try_module_get(sst->dev->driver->owner)) {
503 pr_err("no device available to run\n");
504 ret_val = -ENODEV;
505 goto out_ops;
506 }
507 stream->compr_ops = sst->compr_ops;
508
509 stream->id = 0;
510 sst_set_stream_status(stream, SST_PLATFORM_INIT);
511 runtime->private_data = stream;
512 return 0;
513out_ops:
514 kfree(stream);
515 return ret_val;
516}
517
518static int sst_platform_compr_free(struct snd_compr_stream *cstream)
519{
520 struct sst_runtime_stream *stream;
521 int ret_val = 0, str_id;
522
523 stream = cstream->runtime->private_data;
524 /*need to check*/
525 str_id = stream->id;
526 if (str_id)
527 ret_val = stream->compr_ops->close(str_id);
528 module_put(sst->dev->driver->owner);
529 kfree(stream);
530 pr_debug("%s: %d\n", __func__, ret_val);
531 return 0;
532}
533
534static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
535 struct snd_compr_params *params)
536{
537 struct sst_runtime_stream *stream;
538 int retval;
539 struct snd_sst_params str_params;
540 struct sst_compress_cb cb;
541
542 stream = cstream->runtime->private_data;
543 /* construct fw structure for this*/
544 memset(&str_params, 0, sizeof(str_params));
545
546 str_params.ops = STREAM_OPS_PLAYBACK;
547 str_params.stream_type = SST_STREAM_TYPE_MUSIC;
548 str_params.device_type = SND_SST_DEVICE_COMPRESS;
549
550 switch (params->codec.id) {
551 case SND_AUDIOCODEC_MP3: {
552 str_params.codec = SST_CODEC_TYPE_MP3;
553 str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3;
554 str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in;
555 str_params.sparams.uc.mp3_params.pcm_wd_sz = 16;
556 break;
557 }
558
559 case SND_AUDIOCODEC_AAC: {
560 str_params.codec = SST_CODEC_TYPE_AAC;
561 str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC;
562 str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in;
563 str_params.sparams.uc.aac_params.pcm_wd_sz = 16;
564 if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS)
565 str_params.sparams.uc.aac_params.bs_format =
566 AAC_BIT_STREAM_ADTS;
567 else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW)
568 str_params.sparams.uc.aac_params.bs_format =
569 AAC_BIT_STREAM_RAW;
570 else {
571 pr_err("Undefined format%d\n", params->codec.format);
572 return -EINVAL;
573 }
574 str_params.sparams.uc.aac_params.externalsr =
575 params->codec.sample_rate;
576 break;
577 }
578
579 default:
580 pr_err("codec not supported, id =%d\n", params->codec.id);
581 return -EINVAL;
582 }
583
584 str_params.aparams.ring_buf_info[0].addr =
585 virt_to_phys(cstream->runtime->buffer);
586 str_params.aparams.ring_buf_info[0].size =
587 cstream->runtime->buffer_size;
588 str_params.aparams.sg_count = 1;
589 str_params.aparams.frag_size = cstream->runtime->fragment_size;
590
591 cb.param = cstream;
592 cb.compr_cb = sst_compr_fragment_elapsed;
593
594 retval = stream->compr_ops->open(&str_params, &cb);
595 if (retval < 0) {
596 pr_err("stream allocation failed %d\n", retval);
597 return retval;
598 }
599
600 stream->id = retval;
601 return 0;
602}
603
604static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd)
605{
606 struct sst_runtime_stream *stream =
607 cstream->runtime->private_data;
608
609 return stream->compr_ops->control(cmd, stream->id);
610}
611
612static int sst_platform_compr_pointer(struct snd_compr_stream *cstream,
613 struct snd_compr_tstamp *tstamp)
614{
615 struct sst_runtime_stream *stream;
616
617 stream = cstream->runtime->private_data;
618 stream->compr_ops->tstamp(stream->id, tstamp);
619 tstamp->byte_offset = tstamp->copied_total %
620 (u32)cstream->runtime->buffer_size;
621 pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
622 return 0;
623}
624
625static int sst_platform_compr_ack(struct snd_compr_stream *cstream,
626 size_t bytes)
627{
628 struct sst_runtime_stream *stream;
629
630 stream = cstream->runtime->private_data;
631 stream->compr_ops->ack(stream->id, (unsigned long)bytes);
632 stream->bytes_written += bytes;
633
634 return 0;
635}
636
637static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream,
638 struct snd_compr_caps *caps)
639{
640 struct sst_runtime_stream *stream =
641 cstream->runtime->private_data;
642
643 return stream->compr_ops->get_caps(caps);
644}
645
646static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream,
647 struct snd_compr_codec_caps *codec)
648{
649 struct sst_runtime_stream *stream =
650 cstream->runtime->private_data;
651
652 return stream->compr_ops->get_codec_caps(codec);
653}
654
655static struct snd_compr_ops sst_platform_compr_ops = {
656
657 .open = sst_platform_compr_open,
658 .free = sst_platform_compr_free,
659 .set_params = sst_platform_compr_set_params,
660 .trigger = sst_platform_compr_trigger,
661 .pointer = sst_platform_compr_pointer,
662 .ack = sst_platform_compr_ack,
663 .get_caps = sst_platform_compr_get_caps,
664 .get_codec_caps = sst_platform_compr_get_codec_caps,
665};
666
466static struct snd_soc_platform_driver sst_soc_platform_drv = { 667static struct snd_soc_platform_driver sst_soc_platform_drv = {
467 .ops = &sst_platform_ops, 668 .ops = &sst_platform_ops,
669 .compr_ops = &sst_platform_compr_ops,
468 .pcm_new = sst_pcm_new, 670 .pcm_new = sst_pcm_new,
469 .pcm_free = sst_pcm_free, 671 .pcm_free = sst_pcm_free,
470}; 672};
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
index f04f4f72daa0..d61c5d514ffa 100644
--- a/sound/soc/mid-x86/sst_platform.h
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -27,6 +27,8 @@
27#ifndef __SST_PLATFORMDRV_H__ 27#ifndef __SST_PLATFORMDRV_H__
28#define __SST_PLATFORMDRV_H__ 28#define __SST_PLATFORMDRV_H__
29 29
30#include "sst_dsp.h"
31
30#define SST_MONO 1 32#define SST_MONO 1
31#define SST_STEREO 2 33#define SST_STEREO 2
32#define SST_MAX_CAP 5 34#define SST_MAX_CAP 5
@@ -42,7 +44,6 @@
42#define SST_MIN_PERIODS 2 44#define SST_MIN_PERIODS 2
43#define SST_MAX_PERIODS (1024*2) 45#define SST_MAX_PERIODS (1024*2)
44#define SST_FIFO_SIZE 0 46#define SST_FIFO_SIZE 0
45#define SST_CODEC_TYPE_PCM 1
46 47
47struct pcm_stream_info { 48struct pcm_stream_info {
48 int str_id; 49 int str_id;
@@ -83,6 +84,7 @@ enum sst_audio_device_type {
83 SND_SST_DEVICE_VIBRA, 84 SND_SST_DEVICE_VIBRA,
84 SND_SST_DEVICE_HAPTIC, 85 SND_SST_DEVICE_HAPTIC,
85 SND_SST_DEVICE_CAPTURE, 86 SND_SST_DEVICE_CAPTURE,
87 SND_SST_DEVICE_COMPRESS,
86}; 88};
87 89
88/* PCM Parameters */ 90/* PCM Parameters */
@@ -107,6 +109,24 @@ struct sst_stream_params {
107 struct sst_pcm_params sparams; 109 struct sst_pcm_params sparams;
108}; 110};
109 111
112struct sst_compress_cb {
113 void *param;
114 void (*compr_cb)(void *param);
115};
116
117struct compress_sst_ops {
118 const char *name;
119 int (*open) (struct snd_sst_params *str_params,
120 struct sst_compress_cb *cb);
121 int (*control) (unsigned int cmd, unsigned int str_id);
122 int (*tstamp) (unsigned int str_id, struct snd_compr_tstamp *tstamp);
123 int (*ack) (unsigned int str_id, unsigned long bytes);
124 int (*close) (unsigned int str_id);
125 int (*get_caps) (struct snd_compr_caps *caps);
126 int (*get_codec_caps) (struct snd_compr_codec_caps *codec);
127
128};
129
110struct sst_ops { 130struct sst_ops {
111 int (*open) (struct sst_stream_params *str_param); 131 int (*open) (struct sst_stream_params *str_param);
112 int (*device_control) (int cmd, void *arg); 132 int (*device_control) (int cmd, void *arg);
@@ -115,8 +135,11 @@ struct sst_ops {
115 135
116struct sst_runtime_stream { 136struct sst_runtime_stream {
117 int stream_status; 137 int stream_status;
138 unsigned int id;
139 size_t bytes_written;
118 struct pcm_stream_info stream_info; 140 struct pcm_stream_info stream_info;
119 struct sst_ops *ops; 141 struct sst_ops *ops;
142 struct compress_sst_ops *compr_ops;
120 spinlock_t status_lock; 143 spinlock_t status_lock;
121}; 144};
122 145
@@ -124,6 +147,7 @@ struct sst_device {
124 char *name; 147 char *name;
125 struct device *dev; 148 struct device *dev;
126 struct sst_ops *ops; 149 struct sst_ops *ops;
150 struct compress_sst_ops *compr_ops;
127}; 151};
128 152
129int sst_register_dsp(struct sst_device *sst); 153int sst_register_dsp(struct sst_device *sst);
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index b3030718c228..aa037b292f3d 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -704,7 +704,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
704 return ret; 704 return ret;
705 } 705 }
706 706
707 saif->clk = clk_get(&pdev->dev, NULL); 707 saif->clk = devm_clk_get(&pdev->dev, NULL);
708 if (IS_ERR(saif->clk)) { 708 if (IS_ERR(saif->clk)) {
709 ret = PTR_ERR(saif->clk); 709 ret = PTR_ERR(saif->clk);
710 dev_err(&pdev->dev, "Cannot get the clock: %d\n", 710 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
@@ -717,8 +717,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
717 saif->base = devm_request_and_ioremap(&pdev->dev, iores); 717 saif->base = devm_request_and_ioremap(&pdev->dev, iores);
718 if (!saif->base) { 718 if (!saif->base) {
719 dev_err(&pdev->dev, "ioremap failed\n"); 719 dev_err(&pdev->dev, "ioremap failed\n");
720 ret = -ENODEV; 720 return -ENODEV;
721 goto failed_get_resource;
722 } 721 }
723 722
724 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 723 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -731,7 +730,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
731 &saif->dma_param.chan_num); 730 &saif->dma_param.chan_num);
732 if (ret) { 731 if (ret) {
733 dev_err(&pdev->dev, "failed to get dma channel\n"); 732 dev_err(&pdev->dev, "failed to get dma channel\n");
734 goto failed_get_resource; 733 return ret;
735 } 734 }
736 } else { 735 } else {
737 saif->dma_param.chan_num = dmares->start; 736 saif->dma_param.chan_num = dmares->start;
@@ -742,7 +741,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
742 ret = saif->irq; 741 ret = saif->irq;
743 dev_err(&pdev->dev, "failed to get irq resource: %d\n", 742 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
744 ret); 743 ret);
745 goto failed_get_resource; 744 return ret;
746 } 745 }
747 746
748 saif->dev = &pdev->dev; 747 saif->dev = &pdev->dev;
@@ -750,7 +749,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
750 "mxs-saif", saif); 749 "mxs-saif", saif);
751 if (ret) { 750 if (ret) {
752 dev_err(&pdev->dev, "failed to request irq\n"); 751 dev_err(&pdev->dev, "failed to request irq\n");
753 goto failed_get_resource; 752 return ret;
754 } 753 }
755 754
756 saif->dma_param.chan_irq = platform_get_irq(pdev, 1); 755 saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
@@ -758,7 +757,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
758 ret = saif->dma_param.chan_irq; 757 ret = saif->dma_param.chan_irq;
759 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", 758 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
760 ret); 759 ret);
761 goto failed_get_resource; 760 return ret;
762 } 761 }
763 762
764 platform_set_drvdata(pdev, saif); 763 platform_set_drvdata(pdev, saif);
@@ -766,7 +765,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
766 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); 765 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
767 if (ret) { 766 if (ret) {
768 dev_err(&pdev->dev, "register DAI failed\n"); 767 dev_err(&pdev->dev, "register DAI failed\n");
769 goto failed_get_resource; 768 return ret;
770 } 769 }
771 770
772 ret = mxs_pcm_platform_register(&pdev->dev); 771 ret = mxs_pcm_platform_register(&pdev->dev);
@@ -779,19 +778,14 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
779 778
780failed_pdev_alloc: 779failed_pdev_alloc:
781 snd_soc_unregister_dai(&pdev->dev); 780 snd_soc_unregister_dai(&pdev->dev);
782failed_get_resource:
783 clk_put(saif->clk);
784 781
785 return ret; 782 return ret;
786} 783}
787 784
788static int __devexit mxs_saif_remove(struct platform_device *pdev) 785static int __devexit mxs_saif_remove(struct platform_device *pdev)
789{ 786{
790 struct mxs_saif *saif = platform_get_drvdata(pdev);
791
792 mxs_pcm_platform_unregister(&pdev->dev); 787 mxs_pcm_platform_unregister(&pdev->dev);
793 snd_soc_unregister_dai(&pdev->dev); 788 snd_soc_unregister_dai(&pdev->dev);
794 clk_put(saif->clk);
795 789
796 return 0; 790 return 0;
797} 791}
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 9d93793d3077..be525dfe9faa 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -25,6 +25,7 @@
25#include <linux/mfd/twl6040.h> 25#include <linux/mfd/twl6040.h>
26#include <linux/platform_data/omap-abe-twl6040.h> 26#include <linux/platform_data/omap-abe-twl6040.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of.h>
28 29
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
@@ -43,6 +44,8 @@
43struct abe_twl6040 { 44struct abe_twl6040 {
44 int jack_detection; /* board can detect jack events */ 45 int jack_detection; /* board can detect jack events */
45 int mclk_freq; /* MCLK frequency speed for twl6040 */ 46 int mclk_freq; /* MCLK frequency speed for twl6040 */
47
48 struct platform_device *dmic_codec_dev;
46}; 49};
47 50
48static int omap_abe_hw_params(struct snd_pcm_substream *substream, 51static int omap_abe_hw_params(struct snd_pcm_substream *substream,
@@ -185,17 +188,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
185 int hs_trim; 188 int hs_trim;
186 int ret = 0; 189 int ret = 0;
187 190
188 /* Disable not connected paths if not used */
189 twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
190 twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
191 twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
192 twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
193 twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
194 twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
195 twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
196 twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
197 twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
198
199 /* 191 /*
200 * Configure McPDM offset cancellation based on the HSOTRIM value from 192 * Configure McPDM offset cancellation based on the HSOTRIM value from
201 * twl6040. 193 * twl6040.
@@ -216,6 +208,24 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
216 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); 208 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
217 } 209 }
218 210
211 /*
212 * NULL pdata means we booted with DT. In this case the routing is
213 * provided and the card is fully routed, no need to mark pins.
214 */
215 if (!pdata)
216 return ret;
217
218 /* Disable not connected paths if not used */
219 twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
220 twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
221 twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
222 twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
223 twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
224 twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
225 twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
226 twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
227 twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
228
219 return ret; 229 return ret;
220} 230}
221 231
@@ -270,52 +280,116 @@ static struct snd_soc_card omap_abe_card = {
270static __devinit int omap_abe_probe(struct platform_device *pdev) 280static __devinit int omap_abe_probe(struct platform_device *pdev)
271{ 281{
272 struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); 282 struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
283 struct device_node *node = pdev->dev.of_node;
273 struct snd_soc_card *card = &omap_abe_card; 284 struct snd_soc_card *card = &omap_abe_card;
274 struct abe_twl6040 *priv; 285 struct abe_twl6040 *priv;
275 int num_links = 0; 286 int num_links = 0;
276 int ret; 287 int ret = 0;
277 288
278 card->dev = &pdev->dev; 289 card->dev = &pdev->dev;
279 290
280 if (!pdata) {
281 dev_err(&pdev->dev, "Missing pdata\n");
282 return -ENODEV;
283 }
284
285 priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); 291 priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
286 if (priv == NULL) 292 if (priv == NULL)
287 return -ENOMEM; 293 return -ENOMEM;
288 294
289 if (pdata->card_name) { 295 priv->dmic_codec_dev = ERR_PTR(-EINVAL);
290 card->name = pdata->card_name; 296
297 if (node) {
298 struct device_node *dai_node;
299
300 if (snd_soc_of_parse_card_name(card, "ti,model")) {
301 dev_err(&pdev->dev, "Card name is not provided\n");
302 return -ENODEV;
303 }
304
305 ret = snd_soc_of_parse_audio_routing(card,
306 "ti,audio-routing");
307 if (ret) {
308 dev_err(&pdev->dev,
309 "Error while parsing DAPM routing\n");
310 return ret;
311 }
312
313 dai_node = of_parse_phandle(node, "ti,mcpdm", 0);
314 if (!dai_node) {
315 dev_err(&pdev->dev, "McPDM node is not provided\n");
316 return -EINVAL;
317 }
318 abe_twl6040_dai_links[0].cpu_dai_name = NULL;
319 abe_twl6040_dai_links[0].cpu_of_node = dai_node;
320
321 dai_node = of_parse_phandle(node, "ti,dmic", 0);
322 if (dai_node) {
323 num_links = 2;
324 abe_twl6040_dai_links[1].cpu_dai_name = NULL;
325 abe_twl6040_dai_links[1].cpu_of_node = dai_node;
326
327 priv->dmic_codec_dev = platform_device_register_simple(
328 "dmic-codec", -1, NULL, 0);
329 if (IS_ERR(priv->dmic_codec_dev)) {
330 dev_err(&pdev->dev,
331 "Can't instantiate dmic-codec\n");
332 return PTR_ERR(priv->dmic_codec_dev);
333 }
334 } else {
335 num_links = 1;
336 }
337
338 of_property_read_u32(node, "ti,jack-detection",
339 &priv->jack_detection);
340 of_property_read_u32(node, "ti,mclk-freq",
341 &priv->mclk_freq);
342 if (!priv->mclk_freq) {
343 dev_err(&pdev->dev, "MCLK frequency not provided\n");
344 ret = -EINVAL;
345 goto err_unregister;
346 }
347
348 omap_abe_card.fully_routed = 1;
349 } else if (pdata) {
350 if (pdata->card_name) {
351 card->name = pdata->card_name;
352 } else {
353 dev_err(&pdev->dev, "Card name is not provided\n");
354 return -ENODEV;
355 }
356
357 if (pdata->has_dmic)
358 num_links = 2;
359 else
360 num_links = 1;
361
362 priv->jack_detection = pdata->jack_detection;
363 priv->mclk_freq = pdata->mclk_freq;
291 } else { 364 } else {
292 dev_err(&pdev->dev, "Card name is not provided\n"); 365 dev_err(&pdev->dev, "Missing pdata\n");
293 return -ENODEV; 366 return -ENODEV;
294 } 367 }
295 368
296 priv->jack_detection = pdata->jack_detection;
297 priv->mclk_freq = pdata->mclk_freq;
298
299 369
300 if (!priv->mclk_freq) { 370 if (!priv->mclk_freq) {
301 dev_err(&pdev->dev, "MCLK frequency missing\n"); 371 dev_err(&pdev->dev, "MCLK frequency missing\n");
302 return -ENODEV; 372 ret = -ENODEV;
373 goto err_unregister;
303 } 374 }
304 375
305 if (pdata->has_dmic)
306 num_links = 2;
307 else
308 num_links = 1;
309
310 card->dai_link = abe_twl6040_dai_links; 376 card->dai_link = abe_twl6040_dai_links;
311 card->num_links = num_links; 377 card->num_links = num_links;
312 378
313 snd_soc_card_set_drvdata(card, priv); 379 snd_soc_card_set_drvdata(card, priv);
314 380
315 ret = snd_soc_register_card(card); 381 ret = snd_soc_register_card(card);
316 if (ret) 382 if (ret) {
317 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 383 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
318 ret); 384 ret);
385 goto err_unregister;
386 }
387
388 return 0;
389
390err_unregister:
391 if (!IS_ERR(priv->dmic_codec_dev))
392 platform_device_unregister(priv->dmic_codec_dev);
319 393
320 return ret; 394 return ret;
321} 395}
@@ -323,17 +397,28 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
323static int __devexit omap_abe_remove(struct platform_device *pdev) 397static int __devexit omap_abe_remove(struct platform_device *pdev)
324{ 398{
325 struct snd_soc_card *card = platform_get_drvdata(pdev); 399 struct snd_soc_card *card = platform_get_drvdata(pdev);
400 struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
326 401
327 snd_soc_unregister_card(card); 402 snd_soc_unregister_card(card);
328 403
404 if (!IS_ERR(priv->dmic_codec_dev))
405 platform_device_unregister(priv->dmic_codec_dev);
406
329 return 0; 407 return 0;
330} 408}
331 409
410static const struct of_device_id omap_abe_of_match[] = {
411 {.compatible = "ti,abe-twl6040", },
412 { },
413};
414MODULE_DEVICE_TABLE(of, omap_abe_of_match);
415
332static struct platform_driver omap_abe_driver = { 416static struct platform_driver omap_abe_driver = {
333 .driver = { 417 .driver = {
334 .name = "omap-abe-twl6040", 418 .name = "omap-abe-twl6040",
335 .owner = THIS_MODULE, 419 .owner = THIS_MODULE,
336 .pm = &snd_soc_pm_ops, 420 .pm = &snd_soc_pm_ops,
421 .of_match_table = omap_abe_of_match,
337 }, 422 },
338 .probe = omap_abe_probe, 423 .probe = omap_abe_probe,
339 .remove = __devexit_p(omap_abe_remove), 424 .remove = __devexit_p(omap_abe_remove),
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 2c66e2498a45..f7babb374a37 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -445,9 +445,8 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
445{ 445{
446 struct omap_mcpdm *mcpdm; 446 struct omap_mcpdm *mcpdm;
447 struct resource *res; 447 struct resource *res;
448 int ret = 0;
449 448
450 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); 449 mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL);
451 if (!mcpdm) 450 if (!mcpdm)
452 return -ENOMEM; 451 return -ENOMEM;
453 452
@@ -456,55 +455,30 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
456 mutex_init(&mcpdm->mutex); 455 mutex_init(&mcpdm->mutex);
457 456
458 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 457 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
459 if (res == NULL) { 458 if (res == NULL)
460 dev_err(&pdev->dev, "no resource\n"); 459 return -ENOMEM;
461 goto err_res;
462 }
463 460
464 if (!request_mem_region(res->start, resource_size(res), "McPDM")) { 461 if (!devm_request_mem_region(&pdev->dev, res->start,
465 ret = -EBUSY; 462 resource_size(res), "McPDM"))
466 goto err_res; 463 return -EBUSY;
467 }
468 464
469 mcpdm->io_base = ioremap(res->start, resource_size(res)); 465 mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
470 if (!mcpdm->io_base) { 466 resource_size(res));
471 ret = -ENOMEM; 467 if (!mcpdm->io_base)
472 goto err_iomap; 468 return -ENOMEM;
473 }
474 469
475 mcpdm->irq = platform_get_irq(pdev, 0); 470 mcpdm->irq = platform_get_irq(pdev, 0);
476 if (mcpdm->irq < 0) { 471 if (mcpdm->irq < 0)
477 ret = mcpdm->irq; 472 return mcpdm->irq;
478 goto err_irq;
479 }
480 473
481 mcpdm->dev = &pdev->dev; 474 mcpdm->dev = &pdev->dev;
482 475
483 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); 476 return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
484 if (!ret)
485 return 0;
486
487err_irq:
488 iounmap(mcpdm->io_base);
489err_iomap:
490 release_mem_region(res->start, resource_size(res));
491err_res:
492 kfree(mcpdm);
493 return ret;
494} 477}
495 478
496static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) 479static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
497{ 480{
498 struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
499 struct resource *res;
500
501 snd_soc_unregister_dai(&pdev->dev); 481 snd_soc_unregister_dai(&pdev->dev);
502
503 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
504 iounmap(mcpdm->io_base);
505 release_mem_region(res->start, resource_size(res));
506
507 kfree(mcpdm);
508 return 0; 482 return 0;
509} 483}
510 484
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index fe3995ce9b38..e7b83179aca2 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,6 +1,6 @@
1config SND_SOC_SAMSUNG 1config SND_SOC_SAMSUNG
2 tristate "ASoC support for Samsung" 2 tristate "ASoC support for Samsung"
3 depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 3 depends on PLAT_SAMSUNG
4 select S3C64XX_DMA if ARCH_S3C64XX 4 select S3C64XX_DMA if ARCH_S3C64XX
5 select S3C2410_DMA if ARCH_S3C24XX 5 select S3C2410_DMA if ARCH_S3C24XX
6 help 6 help
@@ -191,6 +191,7 @@ config SND_SOC_SPEYSIDE
191 select SND_SAMSUNG_I2S 191 select SND_SAMSUNG_I2S
192 select SND_SOC_WM8996 192 select SND_SOC_WM8996
193 select SND_SOC_WM9081 193 select SND_SOC_WM9081
194 select SND_SOC_WM0010
194 select SND_SOC_WM1250_EV1 195 select SND_SOC_WM1250_EV1
195 196
196config SND_SOC_TOBERMORY 197config SND_SOC_TOBERMORY
@@ -199,6 +200,14 @@ config SND_SOC_TOBERMORY
199 select SND_SAMSUNG_I2S 200 select SND_SAMSUNG_I2S
200 select SND_SOC_WM8962 201 select SND_SOC_WM8962
201 202
203config SND_SOC_BELLS
204 tristate "Audio support for Wolfson Bells"
205 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
206 select SND_SAMSUNG_I2S
207 select SND_SOC_WM5102
208 select SND_SOC_WM5110
209 select SND_SOC_WM9081
210
202config SND_SOC_LOWLAND 211config SND_SOC_LOWLAND
203 tristate "Audio support for Wolfson Lowland" 212 tristate "Audio support for Wolfson Lowland"
204 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 213 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 9d03beb40c86..709f6059ad67 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -42,6 +42,7 @@ snd-soc-speyside-objs := speyside.o
42snd-soc-tobermory-objs := tobermory.o 42snd-soc-tobermory-objs := tobermory.o
43snd-soc-lowland-objs := lowland.o 43snd-soc-lowland-objs := lowland.o
44snd-soc-littlemill-objs := littlemill.o 44snd-soc-littlemill-objs := littlemill.o
45snd-soc-bells-objs := bells.o
45 46
46obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 47obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
47obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 48obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -65,3 +66,4 @@ obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
65obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o 66obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
66obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o 67obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
67obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o 68obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
69obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
new file mode 100644
index 000000000000..5dc10dfc0d42
--- /dev/null
+++ b/sound/soc/samsung/bells.c
@@ -0,0 +1,346 @@
1/*
2 * Bells audio support
3 *
4 * Copyright 2012 Wolfson Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/jack.h>
15#include <linux/gpio.h>
16#include <linux/module.h>
17
18#include "../codecs/wm5102.h"
19#include "../codecs/wm9081.h"
20
21/*
22 * 44.1kHz based clocks for the SYSCLK domain, use a very high clock
23 * to allow all the DSP functionality to be enabled if desired.
24 */
25#define SYSCLK_RATE (44100 * 1024)
26
27/* 48kHz based clocks for the ASYNC domain */
28#define ASYNCCLK_RATE (48000 * 512)
29
30/* BCLK2 is fixed at this currently */
31#define BCLK2_RATE (64 * 8000)
32
33/*
34 * Expect a 24.576MHz crystal if one is fitted (the driver will function
35 * if this is not fitted).
36 */
37#define MCLK_RATE 24576000
38
39#define WM9081_AUDIO_RATE 44100
40#define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256)
41
42static int bells_set_bias_level(struct snd_soc_card *card,
43 struct snd_soc_dapm_context *dapm,
44 enum snd_soc_bias_level level)
45{
46 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
47 struct snd_soc_codec *codec = codec_dai->codec;
48 int ret;
49
50 if (dapm->dev != codec_dai->dev)
51 return 0;
52
53 switch (level) {
54 case SND_SOC_BIAS_PREPARE:
55 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
56 ret = snd_soc_codec_set_pll(codec, WM5102_FLL1,
57 ARIZONA_FLL_SRC_MCLK1,
58 MCLK_RATE,
59 SYSCLK_RATE);
60 if (ret < 0)
61 pr_err("Failed to start FLL: %d\n", ret);
62
63 ret = snd_soc_codec_set_pll(codec, WM5102_FLL2,
64 ARIZONA_FLL_SRC_AIF2BCLK,
65 BCLK2_RATE,
66 ASYNCCLK_RATE);
67 if (ret < 0)
68 pr_err("Failed to start FLL: %d\n", ret);
69 }
70 break;
71
72 default:
73 break;
74 }
75
76 return 0;
77}
78
79static int bells_set_bias_level_post(struct snd_soc_card *card,
80 struct snd_soc_dapm_context *dapm,
81 enum snd_soc_bias_level level)
82{
83 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
84 struct snd_soc_codec *codec = codec_dai->codec;
85 int ret;
86
87 if (dapm->dev != codec_dai->dev)
88 return 0;
89
90 switch (level) {
91 case SND_SOC_BIAS_STANDBY:
92 ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0);
93 if (ret < 0) {
94 pr_err("Failed to stop FLL: %d\n", ret);
95 return ret;
96 }
97
98 ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0);
99 if (ret < 0) {
100 pr_err("Failed to stop FLL: %d\n", ret);
101 return ret;
102 }
103 break;
104
105 default:
106 break;
107 }
108
109 dapm->bias_level = level;
110
111 return 0;
112}
113
114static int bells_late_probe(struct snd_soc_card *card)
115{
116 struct snd_soc_codec *codec = card->rtd[0].codec;
117 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
118 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
119 struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai;
120 struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai;
121 int ret;
122
123 ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
124 if (ret != 0) {
125 dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
126 return ret;
127 }
128
129 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
130 if (ret != 0) {
131 dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret);
132 return ret;
133 }
134
135 ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
136 if (ret != 0) {
137 dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
138 return ret;
139 }
140
141 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
142 ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE,
143 SND_SOC_CLOCK_IN);
144 if (ret != 0) {
145 dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
146 return ret;
147 }
148
149 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0,
150 WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT);
151 if (ret != 0) {
152 dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret);
153 return ret;
154 }
155
156 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
157 ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE,
158 SND_SOC_CLOCK_IN);
159 if (ret != 0) {
160 dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
161 return ret;
162 }
163
164 ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK,
165 0, WM9081_MCLK_RATE, 0);
166 if (ret != 0) {
167 dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret);
168 return ret;
169 }
170
171 return 0;
172}
173
174static const struct snd_soc_pcm_stream baseband_params = {
175 .formats = SNDRV_PCM_FMTBIT_S32_LE,
176 .rate_min = 8000,
177 .rate_max = 8000,
178 .channels_min = 2,
179 .channels_max = 2,
180};
181
182static const struct snd_soc_pcm_stream sub_params = {
183 .formats = SNDRV_PCM_FMTBIT_S32_LE,
184 .rate_min = WM9081_AUDIO_RATE,
185 .rate_max = WM9081_AUDIO_RATE,
186 .channels_min = 2,
187 .channels_max = 2,
188};
189
190static struct snd_soc_dai_link bells_dai_wm5102[] = {
191 {
192 .name = "CPU",
193 .stream_name = "CPU",
194 .cpu_dai_name = "samsung-i2s.0",
195 .codec_dai_name = "wm5102-aif1",
196 .platform_name = "samsung-audio",
197 .codec_name = "wm5102-codec",
198 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
199 | SND_SOC_DAIFMT_CBM_CFM,
200 },
201 {
202 .name = "Baseband",
203 .stream_name = "Baseband",
204 .cpu_dai_name = "wm5102-aif2",
205 .codec_dai_name = "wm1250-ev1",
206 .codec_name = "wm1250-ev1.1-0027",
207 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
208 | SND_SOC_DAIFMT_CBM_CFM,
209 .ignore_suspend = 1,
210 .params = &baseband_params,
211 },
212 {
213 .name = "Sub",
214 .stream_name = "Sub",
215 .cpu_dai_name = "wm5102-aif3",
216 .codec_dai_name = "wm9081-hifi",
217 .codec_name = "wm9081.1-006c",
218 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
219 | SND_SOC_DAIFMT_CBS_CFS,
220 .ignore_suspend = 1,
221 .params = &sub_params,
222 },
223};
224
225static struct snd_soc_dai_link bells_dai_wm5110[] = {
226 {
227 .name = "CPU",
228 .stream_name = "CPU",
229 .cpu_dai_name = "samsung-i2s.0",
230 .codec_dai_name = "wm5110-aif1",
231 .platform_name = "samsung-audio",
232 .codec_name = "wm5110-codec",
233 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
234 | SND_SOC_DAIFMT_CBM_CFM,
235 },
236 {
237 .name = "Baseband",
238 .stream_name = "Baseband",
239 .cpu_dai_name = "wm5110-aif2",
240 .codec_dai_name = "wm1250-ev1",
241 .codec_name = "wm1250-ev1.1-0027",
242 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
243 | SND_SOC_DAIFMT_CBM_CFM,
244 .ignore_suspend = 1,
245 .params = &baseband_params,
246 },
247 {
248 .name = "Sub",
249 .stream_name = "Sub",
250 .cpu_dai_name = "wm5102-aif3",
251 .codec_dai_name = "wm9081-hifi",
252 .codec_name = "wm9081.1-006c",
253 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
254 | SND_SOC_DAIFMT_CBS_CFS,
255 .ignore_suspend = 1,
256 .params = &sub_params,
257 },
258};
259
260static struct snd_soc_codec_conf bells_codec_conf[] = {
261 {
262 .dev_name = "wm9081.1-006c",
263 .name_prefix = "Sub",
264 },
265};
266
267static struct snd_soc_dapm_route bells_routes[] = {
268 { "Sub CLK_SYS", NULL, "OPCLK" },
269};
270
271static struct snd_soc_card bells_cards[] = {
272 {
273 .name = "Bells WM5102",
274 .owner = THIS_MODULE,
275 .dai_link = bells_dai_wm5102,
276 .num_links = ARRAY_SIZE(bells_dai_wm5102),
277 .codec_conf = bells_codec_conf,
278 .num_configs = ARRAY_SIZE(bells_codec_conf),
279
280 .late_probe = bells_late_probe,
281
282 .dapm_routes = bells_routes,
283 .num_dapm_routes = ARRAY_SIZE(bells_routes),
284
285 .set_bias_level = bells_set_bias_level,
286 .set_bias_level_post = bells_set_bias_level_post,
287 },
288 {
289 .name = "Bells WM5110",
290 .owner = THIS_MODULE,
291 .dai_link = bells_dai_wm5110,
292 .num_links = ARRAY_SIZE(bells_dai_wm5110),
293 .codec_conf = bells_codec_conf,
294 .num_configs = ARRAY_SIZE(bells_codec_conf),
295
296 .late_probe = bells_late_probe,
297
298 .dapm_routes = bells_routes,
299 .num_dapm_routes = ARRAY_SIZE(bells_routes),
300
301 .set_bias_level = bells_set_bias_level,
302 .set_bias_level_post = bells_set_bias_level_post,
303 },
304};
305
306
307static __devinit int bells_probe(struct platform_device *pdev)
308{
309 int ret;
310
311 bells_cards[pdev->id].dev = &pdev->dev;
312
313 ret = snd_soc_register_card(&bells_cards[pdev->id]);
314 if (ret) {
315 dev_err(&pdev->dev,
316 "snd_soc_register_card(%s) failed: %d\n",
317 bells_cards[pdev->id].name, ret);
318 return ret;
319 }
320
321 return 0;
322}
323
324static int __devexit bells_remove(struct platform_device *pdev)
325{
326 snd_soc_unregister_card(&bells_cards[pdev->id]);
327
328 return 0;
329}
330
331static struct platform_driver bells_driver = {
332 .driver = {
333 .name = "bells",
334 .owner = THIS_MODULE,
335 .pm = &snd_soc_pm_ops,
336 },
337 .probe = bells_probe,
338 .remove = __devexit_p(bells_remove),
339};
340
341module_platform_driver(bells_driver);
342
343MODULE_DESCRIPTION("Bells audio support");
344MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
345MODULE_LICENSE("GPL");
346MODULE_ALIAS("platform:bells");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index a4a9fc7e8c76..c7e1c28528a4 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -25,7 +25,7 @@ static int speyside_set_bias_level(struct snd_soc_card *card,
25 struct snd_soc_dapm_context *dapm, 25 struct snd_soc_dapm_context *dapm,
26 enum snd_soc_bias_level level) 26 enum snd_soc_bias_level level)
27{ 27{
28 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 28 struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
29 int ret; 29 int ret;
30 30
31 if (dapm->dev != codec_dai->dev) 31 if (dapm->dev != codec_dai->dev)
@@ -57,7 +57,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
57 struct snd_soc_dapm_context *dapm, 57 struct snd_soc_dapm_context *dapm,
58 enum snd_soc_bias_level level) 58 enum snd_soc_bias_level level)
59{ 59{
60 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 60 struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
61 int ret; 61 int ret;
62 62
63 if (dapm->dev != codec_dai->dev) 63 if (dapm->dev != codec_dai->dev)
@@ -126,6 +126,18 @@ static void speyside_set_polarity(struct snd_soc_codec *codec,
126 snd_soc_dapm_sync(&codec->dapm); 126 snd_soc_dapm_sync(&codec->dapm);
127} 127}
128 128
129static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd)
130{
131 struct snd_soc_dai *dai = rtd->codec_dai;
132 int ret;
133
134 ret = snd_soc_dai_set_sysclk(dai, 0, MCLK_AUDIO_RATE, 0);
135 if (ret < 0)
136 return ret;
137
138 return 0;
139}
140
129static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) 141static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
130{ 142{
131 struct snd_soc_dai *dai = rtd->codec_dai; 143 struct snd_soc_dai *dai = rtd->codec_dai;
@@ -172,17 +184,37 @@ static int speyside_late_probe(struct snd_soc_card *card)
172 return 0; 184 return 0;
173} 185}
174 186
187static const struct snd_soc_pcm_stream dsp_codec_params = {
188 .formats = SNDRV_PCM_FMTBIT_S32_LE,
189 .rate_min = 48000,
190 .rate_max = 48000,
191 .channels_min = 2,
192 .channels_max = 2,
193};
194
175static struct snd_soc_dai_link speyside_dai[] = { 195static struct snd_soc_dai_link speyside_dai[] = {
176 { 196 {
177 .name = "CPU", 197 .name = "CPU-DSP",
178 .stream_name = "CPU", 198 .stream_name = "CPU-DSP",
179 .cpu_dai_name = "samsung-i2s.0", 199 .cpu_dai_name = "samsung-i2s.0",
180 .codec_dai_name = "wm8996-aif1", 200 .codec_dai_name = "wm0010-sdi1",
181 .platform_name = "samsung-audio", 201 .platform_name = "samsung-audio",
202 .codec_name = "spi0.0",
203 .init = speyside_wm0010_init,
204 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
205 | SND_SOC_DAIFMT_CBM_CFM,
206 },
207 {
208 .name = "DSP-CODEC",
209 .stream_name = "DSP-CODEC",
210 .cpu_dai_name = "wm0010-sdi2",
211 .codec_dai_name = "wm8996-aif1",
182 .codec_name = "wm8996.1-001a", 212 .codec_name = "wm8996.1-001a",
183 .init = speyside_wm8996_init, 213 .init = speyside_wm8996_init,
184 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 214 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
185 | SND_SOC_DAIFMT_CBM_CFM, 215 | SND_SOC_DAIFMT_CBM_CFM,
216 .params = &dsp_codec_params,
217 .ignore_suspend = 1,
186 }, 218 },
187 { 219 {
188 .name = "Baseband", 220 .name = "Baseband",
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
new file mode 100644
index 000000000000..967d0e173e1b
--- /dev/null
+++ b/sound/soc/soc-compress.c
@@ -0,0 +1,294 @@
1/*
2 * soc-compress.c -- ALSA SoC Compress
3 *
4 * Copyright (C) 2012 Intel Corp.
5 *
6 * Authors: Namarta Kohli <namartax.kohli@intel.com>
7 * Ramesh Babu K V <ramesh.babu@linux.intel.com>
8 * Vinod Koul <vinod.koul@linux.intel.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/workqueue.h>
22#include <sound/core.h>
23#include <sound/compress_params.h>
24#include <sound/compress_driver.h>
25#include <sound/soc.h>
26#include <sound/initval.h>
27
28static int soc_compr_open(struct snd_compr_stream *cstream)
29{
30 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
31 struct snd_soc_platform *platform = rtd->platform;
32 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
33 struct snd_soc_dai *codec_dai = rtd->codec_dai;
34 int ret = 0;
35
36 if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
37 ret = platform->driver->compr_ops->open(cstream);
38 if (ret < 0) {
39 pr_err("compress asoc: can't open platform %s\n", platform->name);
40 goto out;
41 }
42 }
43
44 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
45 ret = rtd->dai_link->compr_ops->startup(cstream);
46 if (ret < 0) {
47 pr_err("compress asoc: %s startup failed\n", rtd->dai_link->name);
48 goto machine_err;
49 }
50 }
51
52 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
53 cpu_dai->playback_active++;
54 codec_dai->playback_active++;
55 } else {
56 cpu_dai->capture_active++;
57 codec_dai->capture_active++;
58 }
59
60 cpu_dai->active++;
61 codec_dai->active++;
62 rtd->codec->active++;
63
64 return 0;
65
66machine_err:
67 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
68 platform->driver->compr_ops->free(cstream);
69out:
70 return ret;
71}
72
73static int soc_compr_free(struct snd_compr_stream *cstream)
74{
75 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
76 struct snd_soc_platform *platform = rtd->platform;
77 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
78 struct snd_soc_dai *codec_dai = rtd->codec_dai;
79 struct snd_soc_codec *codec = rtd->codec;
80
81 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
82 cpu_dai->playback_active--;
83 codec_dai->playback_active--;
84 } else {
85 cpu_dai->capture_active--;
86 codec_dai->capture_active--;
87 }
88
89 snd_soc_dai_digital_mute(codec_dai, 1);
90
91 cpu_dai->active--;
92 codec_dai->active--;
93 codec->active--;
94
95 if (!cpu_dai->active)
96 cpu_dai->rate = 0;
97
98 if (!codec_dai->active)
99 codec_dai->rate = 0;
100
101
102 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
103 rtd->dai_link->compr_ops->shutdown(cstream);
104
105 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
106 platform->driver->compr_ops->free(cstream);
107 cpu_dai->runtime = NULL;
108
109 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
110 if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
111 rtd->dai_link->ignore_pmdown_time) {
112 snd_soc_dapm_stream_event(rtd,
113 SNDRV_PCM_STREAM_PLAYBACK,
114 SND_SOC_DAPM_STREAM_STOP);
115 } else
116 codec_dai->pop_wait = 1;
117 schedule_delayed_work(&rtd->delayed_work,
118 msecs_to_jiffies(rtd->pmdown_time));
119 } else {
120 /* capture streams can be powered down now */
121 snd_soc_dapm_stream_event(rtd,
122 SNDRV_PCM_STREAM_CAPTURE,
123 SND_SOC_DAPM_STREAM_STOP);
124 }
125
126 return 0;
127}
128
129static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
130{
131
132 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
133 struct snd_soc_platform *platform = rtd->platform;
134 struct snd_soc_dai *codec_dai = rtd->codec_dai;
135 int ret = 0;
136
137 if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
138 ret = platform->driver->compr_ops->trigger(cstream, cmd);
139 if (ret < 0)
140 return ret;
141 }
142
143 if (cmd == SNDRV_PCM_TRIGGER_START)
144 snd_soc_dai_digital_mute(codec_dai, 0);
145 else if (cmd == SNDRV_PCM_TRIGGER_STOP)
146 snd_soc_dai_digital_mute(codec_dai, 1);
147
148 return ret;
149}
150
151static int soc_compr_set_params(struct snd_compr_stream *cstream,
152 struct snd_compr_params *params)
153{
154 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
155 struct snd_soc_platform *platform = rtd->platform;
156 int ret = 0;
157
158 /* first we call set_params for the platform driver
159 * this should configure the soc side
160 * if the machine has compressed ops then we call that as well
161 * expectation is that platform and machine will configure everything
162 * for this compress path, like configuring pcm port for codec
163 */
164 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
165 ret = platform->driver->compr_ops->set_params(cstream, params);
166 if (ret < 0)
167 return ret;
168 }
169
170 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
171 ret = rtd->dai_link->compr_ops->set_params(cstream);
172 if (ret < 0)
173 return ret;
174 }
175
176 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
177 SND_SOC_DAPM_STREAM_START);
178
179 return ret;
180}
181
182static int soc_compr_get_params(struct snd_compr_stream *cstream,
183 struct snd_codec *params)
184{
185 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
186 struct snd_soc_platform *platform = rtd->platform;
187 int ret = 0;
188
189 if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
190 ret = platform->driver->compr_ops->get_params(cstream, params);
191
192 return ret;
193}
194
195static int soc_compr_get_caps(struct snd_compr_stream *cstream,
196 struct snd_compr_caps *caps)
197{
198 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
199 struct snd_soc_platform *platform = rtd->platform;
200 int ret = 0;
201
202 if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps)
203 ret = platform->driver->compr_ops->get_caps(cstream, caps);
204
205 return ret;
206}
207
208static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
209 struct snd_compr_codec_caps *codec)
210{
211 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
212 struct snd_soc_platform *platform = rtd->platform;
213 int ret = 0;
214
215 if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps)
216 ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
217
218 return ret;
219}
220
221static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
222{
223 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
224 struct snd_soc_platform *platform = rtd->platform;
225 int ret = 0;
226
227 if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
228 ret = platform->driver->compr_ops->ack(cstream, bytes);
229
230 return ret;
231}
232
233static int soc_compr_pointer(struct snd_compr_stream *cstream,
234 struct snd_compr_tstamp *tstamp)
235{
236 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
237 struct snd_soc_platform *platform = rtd->platform;
238
239 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
240 platform->driver->compr_ops->pointer(cstream, tstamp);
241
242 return 0;
243}
244
245/* ASoC Compress operations */
246static struct snd_compr_ops soc_compr_ops = {
247 .open = soc_compr_open,
248 .free = soc_compr_free,
249 .set_params = soc_compr_set_params,
250 .get_params = soc_compr_get_params,
251 .trigger = soc_compr_trigger,
252 .pointer = soc_compr_pointer,
253 .ack = soc_compr_ack,
254 .get_caps = soc_compr_get_caps,
255 .get_codec_caps = soc_compr_get_codec_caps
256};
257
258/* create a new compress */
259int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
260{
261 struct snd_soc_codec *codec = rtd->codec;
262 struct snd_soc_dai *codec_dai = rtd->codec_dai;
263 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
264 struct snd_compr *compr;
265 char new_name[64];
266 int ret = 0, direction = 0;
267
268 /* check client and interface hw capabilities */
269 snprintf(new_name, sizeof(new_name), "%s %s-%d",
270 rtd->dai_link->stream_name, codec_dai->name, num);
271 direction = SND_COMPRESS_PLAYBACK;
272 compr = kzalloc(sizeof(*compr), GFP_KERNEL);
273 if (compr == NULL) {
274 snd_printk(KERN_ERR "Cannot allocate compr\n");
275 return -ENOMEM;
276 }
277
278 compr->ops = &soc_compr_ops;
279 mutex_init(&compr->lock);
280 ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
281 if (ret < 0) {
282 pr_err("compress asoc: can't create compress for codec %s\n",
283 codec->name);
284 kfree(compr);
285 return ret;
286 }
287
288 rtd->compr = compr;
289 compr->private_data = rtd;
290
291 printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
292 cpu_dai->name);
293 return ret;
294}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c501af6d8dbe..b95d1fb388a1 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1388,37 +1388,48 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1388 if (ret < 0) 1388 if (ret < 0)
1389 pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); 1389 pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
1390 1390
1391 if (!dai_link->params) { 1391 if (cpu_dai->driver->compress_dai) {
1392 /* create the pcm */ 1392 /*create compress_device"*/
1393 ret = soc_new_pcm(rtd, num); 1393 ret = soc_new_compress(rtd, num);
1394 if (ret < 0) { 1394 if (ret < 0) {
1395 pr_err("asoc: can't create pcm %s :%d\n", 1395 pr_err("asoc: can't create compress %s\n",
1396 dai_link->stream_name, ret); 1396 dai_link->stream_name);
1397 return ret; 1397 return ret;
1398 } 1398 }
1399 } else { 1399 } else {
1400 /* link the DAI widgets */ 1400
1401 play_w = codec_dai->playback_widget; 1401 if (!dai_link->params) {
1402 capture_w = cpu_dai->capture_widget; 1402 /* create the pcm */
1403 if (play_w && capture_w) { 1403 ret = soc_new_pcm(rtd, num);
1404 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1404 if (ret < 0) {
1405 capture_w, play_w); 1405 pr_err("asoc: can't create pcm %s :%d\n",
1406 if (ret != 0) { 1406 dai_link->stream_name, ret);
1407 dev_err(card->dev, "Can't link %s to %s: %d\n",
1408 play_w->name, capture_w->name, ret);
1409 return ret; 1407 return ret;
1410 } 1408 }
1411 } 1409 } else {
1410 /* link the DAI widgets */
1411 play_w = codec_dai->playback_widget;
1412 capture_w = cpu_dai->capture_widget;
1413 if (play_w && capture_w) {
1414 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1415 capture_w, play_w);
1416 if (ret != 0) {
1417 dev_err(card->dev, "Can't link %s to %s: %d\n",
1418 play_w->name, capture_w->name, ret);
1419 return ret;
1420 }
1421 }
1412 1422
1413 play_w = cpu_dai->playback_widget; 1423 play_w = cpu_dai->playback_widget;
1414 capture_w = codec_dai->capture_widget; 1424 capture_w = codec_dai->capture_widget;
1415 if (play_w && capture_w) { 1425 if (play_w && capture_w) {
1416 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1426 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1417 capture_w, play_w); 1427 capture_w, play_w);
1418 if (ret != 0) { 1428 if (ret != 0) {
1419 dev_err(card->dev, "Can't link %s to %s: %d\n", 1429 dev_err(card->dev, "Can't link %s to %s: %d\n",
1420 play_w->name, capture_w->name, ret); 1430 play_w->name, capture_w->name, ret);
1421 return ret; 1431 return ret;
1432 }
1422 } 1433 }
1423 } 1434 }
1424 } 1435 }
@@ -1816,7 +1827,6 @@ base_error:
1816static int soc_probe(struct platform_device *pdev) 1827static int soc_probe(struct platform_device *pdev)
1817{ 1828{
1818 struct snd_soc_card *card = platform_get_drvdata(pdev); 1829 struct snd_soc_card *card = platform_get_drvdata(pdev);
1819 int ret = 0;
1820 1830
1821 /* 1831 /*
1822 * no card, so machine driver should be registering card 1832 * no card, so machine driver should be registering card
@@ -1832,13 +1842,7 @@ static int soc_probe(struct platform_device *pdev)
1832 /* Bodge while we unpick instantiation */ 1842 /* Bodge while we unpick instantiation */
1833 card->dev = &pdev->dev; 1843 card->dev = &pdev->dev;
1834 1844
1835 ret = snd_soc_register_card(card); 1845 return snd_soc_register_card(card);
1836 if (ret != 0) {
1837 dev_err(&pdev->dev, "Failed to register card\n");
1838 return ret;
1839 }
1840
1841 return 0;
1842} 1846}
1843 1847
1844static int soc_cleanup_card_resources(struct snd_soc_card *card) 1848static int soc_cleanup_card_resources(struct snd_soc_card *card)
@@ -3717,6 +3721,9 @@ int snd_soc_register_dai(struct device *dev,
3717 } 3721 }
3718 } 3722 }
3719 3723
3724 if (!dai->codec)
3725 dai->dapm.idle_bias_off = 1;
3726
3720 list_add(&dai->list, &dai_list); 3727 list_add(&dai->list, &dai_list);
3721 3728
3722 mutex_unlock(&client_mutex); 3729 mutex_unlock(&client_mutex);
@@ -3805,6 +3812,9 @@ int snd_soc_register_dais(struct device *dev,
3805 } 3812 }
3806 } 3813 }
3807 3814
3815 if (!dai->codec)
3816 dai->dapm.idle_bias_off = 1;
3817
3808 list_add(&dai->list, &dai_list); 3818 list_add(&dai->list, &dai_list);
3809 3819
3810 mutex_unlock(&client_mutex); 3820 mutex_unlock(&client_mutex);
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 0c172938b82a..fa0fd8ddae90 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -83,11 +83,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
83 jack->status &= ~mask; 83 jack->status &= ~mask;
84 jack->status |= status & mask; 84 jack->status |= status & mask;
85 85
86 /* The DAPM sync is expensive enough to be worth skipping.
87 * However, empty mask means pin synchronization is desired. */
88 if (mask && (jack->status == oldstatus))
89 goto out;
90
91 trace_snd_soc_jack_notify(jack, status); 86 trace_snd_soc_jack_notify(jack, status);
92 87
93 list_for_each_entry(pin, &jack->pins, list) { 88 list_for_each_entry(pin, &jack->pins, list) {
@@ -109,7 +104,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
109 104
110 snd_jack_report(jack->jack, jack->status); 105 snd_jack_report(jack->jack, jack->status);
111 106
112out:
113 mutex_unlock(&jack->mutex); 107 mutex_unlock(&jack->mutex);
114} 108}
115EXPORT_SYMBOL_GPL(snd_soc_jack_report); 109EXPORT_SYMBOL_GPL(snd_soc_jack_report);
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 057e28ef770e..772cb19d2fb3 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -760,6 +760,9 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
760 drvdata = devm_kzalloc(&pdev->dev, 760 drvdata = devm_kzalloc(&pdev->dev,
761 sizeof(struct ux500_msp_i2s_drvdata), 761 sizeof(struct ux500_msp_i2s_drvdata),
762 GFP_KERNEL); 762 GFP_KERNEL);
763 if (!drvdata)
764 return -ENOMEM;
765
763 drvdata->fmt = 0; 766 drvdata->fmt = 0;
764 drvdata->slots = 1; 767 drvdata->slots = 1;
765 drvdata->tx_mask = 0x01; 768 drvdata->tx_mask = 0x01;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 5c472f335a64..36be11e47ad6 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -673,6 +673,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
673 673
674 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); 674 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
675 msp = *msp_p; 675 msp = *msp_p;
676 if (!msp)
677 return -ENOMEM;
676 678
677 msp->id = platform_data->id; 679 msp->id = platform_data->id;
678 msp->dev = &pdev->dev; 680 msp->dev = &pdev->dev;