aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/imx
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/imx')
-rw-r--r--sound/soc/imx/Kconfig16
-rw-r--r--sound/soc/imx/Makefile10
-rw-r--r--sound/soc/imx/eukrea-tlv320.c16
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c43
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c68
-rw-r--r--sound/soc/imx/imx-ssi.c148
-rw-r--r--sound/soc/imx/imx-ssi.h7
-rw-r--r--sound/soc/imx/phycore-ac97.c19
-rw-r--r--sound/soc/imx/wm1133-ev1.c27
9 files changed, 203 insertions, 151 deletions
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 52dac5e3874c..66ba26393c10 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -8,12 +8,24 @@ menuconfig SND_IMX_SOC
8 Say Y or M if you want to add support for codecs attached to 8 Say Y or M if you want to add support for codecs attached to
9 the i.MX SSI interface. 9 the i.MX SSI interface.
10 10
11
11if SND_IMX_SOC 12if SND_IMX_SOC
12 13
14config SND_MXC_SOC_SSI
15 tristate
16
17config SND_MXC_SOC_FIQ
18 tristate
19
20config SND_MXC_SOC_MX2
21 tristate
22
13config SND_MXC_SOC_WM1133_EV1 23config SND_MXC_SOC_WM1133_EV1
14 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" 24 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
15 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL 25 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
16 select SND_SOC_WM8350 26 select SND_SOC_WM8350
27 select SND_MXC_SOC_SSI
28 select SND_MXC_SOC_FIQ
17 help 29 help
18 Enable support for audio on the i.MX31ADS with the WM1133-EV1 30 Enable support for audio on the i.MX31ADS with the WM1133-EV1
19 PMIC board with WM8835x fitted. 31 PMIC board with WM8835x fitted.
@@ -22,6 +34,8 @@ config SND_SOC_PHYCORE_AC97
22 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 34 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
23 depends on MACH_PCM043 || MACH_PCA100 35 depends on MACH_PCM043 || MACH_PCA100
24 select SND_SOC_WM9712 36 select SND_SOC_WM9712
37 select SND_MXC_SOC_SSI
38 select SND_MXC_SOC_FIQ
25 help 39 help
26 Say Y if you want to add support for SoC audio on Phytec phyCORE 40 Say Y if you want to add support for SoC audio on Phytec phyCORE
27 and phyCARD boards in AC97 mode 41 and phyCARD boards in AC97 mode
@@ -30,6 +44,8 @@ config SND_SOC_EUKREA_TLV320
30 tristate "Eukrea TLV320" 44 tristate "Eukrea TLV320"
31 depends on MACH_EUKREA_MBIMX27_BASEBOARD || MACH_EUKREA_MBIMXSD_BASEBOARD 45 depends on MACH_EUKREA_MBIMX27_BASEBOARD || MACH_EUKREA_MBIMXSD_BASEBOARD
32 select SND_SOC_TLV320AIC23 46 select SND_SOC_TLV320AIC23
47 select SND_MXC_SOC_SSI
48 select SND_MXC_SOC_FIQ
33 help 49 help
34 Enable I2S based access to the TLV320AIC23B codec attached 50 Enable I2S based access to the TLV320AIC23B codec attached
35 to the SSI interface 51 to the SSI interface
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 7bc57baf2b0e..b67fc02a4ecc 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -1,11 +1,11 @@
1# i.MX Platform Support 1# i.MX Platform Support
2snd-soc-imx-objs := imx-ssi.o imx-pcm-fiq.o 2snd-soc-imx-objs := imx-ssi.o
3 3snd-soc-imx-fiq-objs := imx-pcm-fiq.o
4ifdef CONFIG_MACH_MX27 4snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o
5snd-soc-imx-objs += imx-pcm-dma-mx2.o
6endif
7 5
8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o 6obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
7obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o
8obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
9 9
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index f15dfbdc47ee..807f736ee294 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -79,22 +79,19 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = {
79static struct snd_soc_dai_link eukrea_tlv320_dai = { 79static struct snd_soc_dai_link eukrea_tlv320_dai = {
80 .name = "tlv320aic23", 80 .name = "tlv320aic23",
81 .stream_name = "TLV320AIC23", 81 .stream_name = "TLV320AIC23",
82 .codec_dai = &tlv320aic23_dai, 82 .codec_dai = "tlv320aic23-hifi",
83 .platform_name = "imx-pcm-audio.0",
84 .codec_name = "tlv320aic23-codec.0-001a",
85 .cpu_dai = "imx-ssi-dai.0",
83 .ops = &eukrea_tlv320_snd_ops, 86 .ops = &eukrea_tlv320_snd_ops,
84}; 87};
85 88
86static struct snd_soc_card eukrea_tlv320 = { 89static struct snd_soc_card eukrea_tlv320 = {
87 .name = "cpuimx-audio", 90 .name = "cpuimx-audio",
88 .platform = &imx_soc_platform,
89 .dai_link = &eukrea_tlv320_dai, 91 .dai_link = &eukrea_tlv320_dai,
90 .num_links = 1, 92 .num_links = 1,
91}; 93};
92 94
93static struct snd_soc_device eukrea_tlv320_snd_devdata = {
94 .card = &eukrea_tlv320,
95 .codec_dev = &soc_codec_dev_tlv320aic23,
96};
97
98static struct platform_device *eukrea_tlv320_snd_device; 95static struct platform_device *eukrea_tlv320_snd_device;
99 96
100static int __init eukrea_tlv320_init(void) 97static int __init eukrea_tlv320_init(void)
@@ -110,10 +107,7 @@ static int __init eukrea_tlv320_init(void)
110 if (!eukrea_tlv320_snd_device) 107 if (!eukrea_tlv320_snd_device)
111 return -ENOMEM; 108 return -ENOMEM;
112 109
113 eukrea_tlv320_dai.cpu_dai = &imx_ssi_pcm_dai[0]; 110 platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
114
115 platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320_snd_devdata);
116 eukrea_tlv320_snd_devdata.dev = &eukrea_tlv320_snd_device->dev;
117 ret = platform_device_add(eukrea_tlv320_snd_device); 111 ret = platform_device_add(eukrea_tlv320_snd_device);
118 112
119 if (ret) { 113 if (ret) {
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 0a595da4811d..fd493ee1428e 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -103,7 +103,7 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
103 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 103 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
104 int ret; 104 int ret;
105 105
106 dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 106 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
107 107
108 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); 108 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
109 if (iprtd->dma < 0) { 109 if (iprtd->dma < 0) {
@@ -213,7 +213,7 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
213 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 213 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
214 int err; 214 int err;
215 215
216 dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 216 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
217 217
218 iprtd->substream = substream; 218 iprtd->substream = substream;
219 iprtd->buf = (unsigned int *)substream->dma_buffer.area; 219 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
@@ -318,19 +318,42 @@ static struct snd_pcm_ops imx_pcm_ops = {
318 .mmap = snd_imx_pcm_mmap, 318 .mmap = snd_imx_pcm_mmap,
319}; 319};
320 320
321static struct snd_soc_platform imx_soc_platform_dma = { 321static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
322 .name = "imx-audio", 322 .ops = &imx_pcm_ops,
323 .pcm_ops = &imx_pcm_ops,
324 .pcm_new = imx_pcm_new, 323 .pcm_new = imx_pcm_new,
325 .pcm_free = imx_pcm_free, 324 .pcm_free = imx_pcm_free,
326}; 325};
327 326
328struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev, 327static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
329 struct imx_ssi *ssi)
330{ 328{
331 ssi->dma_params_tx.burstsize = DMA_TXFIFO_BURST; 329 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
332 ssi->dma_params_rx.burstsize = DMA_RXFIFO_BURST; 330}
331
332static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
333{
334 snd_soc_unregister_platform(&pdev->dev);
335 return 0;
336}
337
338static struct platform_driver imx_pcm_driver = {
339 .driver = {
340 .name = "imx-pcm-audio",
341 .owner = THIS_MODULE,
342 },
333 343
334 return &imx_soc_platform_dma; 344 .probe = imx_soc_platform_probe,
345 .remove = __devexit_p(imx_soc_platform_remove),
346};
347
348static int __init snd_imx_pcm_init(void)
349{
350 return platform_driver_register(&imx_pcm_driver);
351}
352module_init(snd_imx_pcm_init);
353
354static void __exit snd_imx_pcm_exit(void)
355{
356 platform_driver_unregister(&imx_pcm_driver);
335} 357}
358module_exit(snd_imx_pcm_exit);
336 359
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index b2bf27282cd2..413b78da248f 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -236,6 +236,8 @@ static struct snd_pcm_ops imx_pcm_ops = {
236 .mmap = snd_imx_pcm_mmap, 236 .mmap = snd_imx_pcm_mmap,
237}; 237};
238 238
239static int ssi_irq = 0;
240
239static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai, 241static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
240 struct snd_pcm *pcm) 242 struct snd_pcm *pcm)
241{ 243{
@@ -245,7 +247,7 @@ static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
245 if (ret) 247 if (ret)
246 return ret; 248 return ret;
247 249
248 if (dai->playback.channels_min) { 250 if (dai->driver->playback.channels_min) {
249 struct snd_pcm_substream *substream = 251 struct snd_pcm_substream *substream =
250 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 252 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
251 struct snd_dma_buffer *buf = &substream->dma_buffer; 253 struct snd_dma_buffer *buf = &substream->dma_buffer;
@@ -253,7 +255,7 @@ static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
253 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; 255 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
254 } 256 }
255 257
256 if (dai->capture.channels_min) { 258 if (dai->driver->capture.channels_min) {
257 struct snd_pcm_substream *substream = 259 struct snd_pcm_substream *substream =
258 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 260 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
259 struct snd_dma_buffer *buf = &substream->dma_buffer; 261 struct snd_dma_buffer *buf = &substream->dma_buffer;
@@ -267,24 +269,32 @@ static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
267 return 0; 269 return 0;
268} 270}
269 271
270static struct snd_soc_platform imx_soc_platform_fiq = { 272static void imx_pcm_fiq_free(struct snd_pcm *pcm)
271 .pcm_ops = &imx_pcm_ops, 273{
274 mxc_set_irq_fiq(ssi_irq, 0);
275 release_fiq(&fh);
276 imx_pcm_free(pcm);
277}
278
279static struct snd_soc_platform_driver imx_soc_platform_fiq = {
280 .ops = &imx_pcm_ops,
272 .pcm_new = imx_pcm_fiq_new, 281 .pcm_new = imx_pcm_fiq_new,
273 .pcm_free = imx_pcm_free, 282 .pcm_free = imx_pcm_fiq_free,
274}; 283};
275 284
276struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, 285static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
277 struct imx_ssi *ssi)
278{ 286{
279 int ret = 0; 287 struct imx_ssi *ssi = platform_get_drvdata(pdev);
288 int ret;
280 289
281 ret = claim_fiq(&fh); 290 ret = claim_fiq(&fh);
282 if (ret) { 291 if (ret) {
283 dev_err(&pdev->dev, "failed to claim fiq: %d", ret); 292 dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
284 return ERR_PTR(ret); 293 return ret;
285 } 294 }
286 295
287 mxc_set_irq_fiq(ssi->irq, 1); 296 mxc_set_irq_fiq(ssi->irq, 1);
297 ssi_irq = ssi->irq;
288 298
289 imx_pcm_fiq = ssi->irq; 299 imx_pcm_fiq = ssi->irq;
290 300
@@ -293,13 +303,43 @@ struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
293 ssi->dma_params_tx.burstsize = 4; 303 ssi->dma_params_tx.burstsize = 4;
294 ssi->dma_params_rx.burstsize = 6; 304 ssi->dma_params_rx.burstsize = 6;
295 305
296 return &imx_soc_platform_fiq; 306 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
307 if (ret)
308 goto failed_register;
309
310 return 0;
311
312failed_register:
313 mxc_set_irq_fiq(ssi_irq, 0);
314 release_fiq(&fh);
315
316 return ret;
297} 317}
298 318
299void imx_ssi_fiq_exit(struct platform_device *pdev, 319static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
300 struct imx_ssi *ssi)
301{ 320{
302 mxc_set_irq_fiq(ssi->irq, 0); 321 snd_soc_unregister_platform(&pdev->dev);
303 release_fiq(&fh); 322 return 0;
304} 323}
305 324
325static struct platform_driver imx_pcm_driver = {
326 .driver = {
327 .name = "imx-fiq-pcm-audio",
328 .owner = THIS_MODULE,
329 },
330
331 .probe = imx_soc_platform_probe,
332 .remove = __devexit_p(imx_soc_platform_remove),
333};
334
335static int __init snd_imx_pcm_init(void)
336{
337 return platform_driver_register(&imx_pcm_driver);
338}
339module_init(snd_imx_pcm_init);
340
341static void __exit snd_imx_pcm_exit(void)
342{
343 platform_driver_unregister(&imx_pcm_driver);
344}
345module_exit(snd_imx_pcm_exit);
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 50f51624c535..02a3e7c799d8 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -61,7 +61,7 @@
61static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, 61static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
62 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 62 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
63{ 63{
64 struct imx_ssi *ssi = cpu_dai->private_data; 64 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
65 u32 sccr; 65 u32 sccr;
66 66
67 sccr = readl(ssi->base + SSI_STCCR); 67 sccr = readl(ssi->base + SSI_STCCR);
@@ -86,7 +86,7 @@ static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
86 */ 86 */
87static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 87static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
88{ 88{
89 struct imx_ssi *ssi = cpu_dai->private_data; 89 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
90 u32 strcr = 0, scr; 90 u32 strcr = 0, scr;
91 91
92 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET); 92 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
@@ -164,7 +164,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
164static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 164static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
165 int clk_id, unsigned int freq, int dir) 165 int clk_id, unsigned int freq, int dir)
166{ 166{
167 struct imx_ssi *ssi = cpu_dai->private_data; 167 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
168 u32 scr; 168 u32 scr;
169 169
170 scr = readl(ssi->base + SSI_SCR); 170 scr = readl(ssi->base + SSI_SCR);
@@ -192,7 +192,7 @@ static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
192static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, 192static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
193 int div_id, int div) 193 int div_id, int div)
194{ 194{
195 struct imx_ssi *ssi = cpu_dai->private_data; 195 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
196 u32 stccr, srccr; 196 u32 stccr, srccr;
197 197
198 stccr = readl(ssi->base + SSI_STCCR); 198 stccr = readl(ssi->base + SSI_STCCR);
@@ -241,7 +241,7 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
241 struct snd_pcm_hw_params *params, 241 struct snd_pcm_hw_params *params,
242 struct snd_soc_dai *cpu_dai) 242 struct snd_soc_dai *cpu_dai)
243{ 243{
244 struct imx_ssi *ssi = cpu_dai->private_data; 244 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
245 struct imx_pcm_dma_params *dma_data; 245 struct imx_pcm_dma_params *dma_data;
246 u32 reg, sccr; 246 u32 reg, sccr;
247 247
@@ -279,9 +279,7 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
279static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, 279static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
280 struct snd_soc_dai *dai) 280 struct snd_soc_dai *dai)
281{ 281{
282 struct snd_soc_pcm_runtime *rtd = substream->private_data; 282 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(dai);
283 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
284 struct imx_ssi *ssi = cpu_dai->private_data;
285 unsigned int sier_bits, sier; 283 unsigned int sier_bits, sier;
286 unsigned int scr; 284 unsigned int scr;
287 285
@@ -350,22 +348,6 @@ static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
350 .trigger = imx_ssi_trigger, 348 .trigger = imx_ssi_trigger,
351}; 349};
352 350
353static struct snd_soc_dai imx_ssi_dai = {
354 .playback = {
355 .channels_min = 2,
356 .channels_max = 2,
357 .rates = SNDRV_PCM_RATE_8000_96000,
358 .formats = SNDRV_PCM_FMTBIT_S16_LE,
359 },
360 .capture = {
361 .channels_min = 2,
362 .channels_max = 2,
363 .rates = SNDRV_PCM_RATE_8000_96000,
364 .formats = SNDRV_PCM_FMTBIT_S16_LE,
365 },
366 .ops = &imx_ssi_pcm_dai_ops,
367};
368
369int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 351int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
370 struct vm_area_struct *vma) 352 struct vm_area_struct *vma)
371{ 353{
@@ -381,6 +363,7 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
381 runtime->dma_bytes); 363 runtime->dma_bytes);
382 return ret; 364 return ret;
383} 365}
366EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
384 367
385static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 368static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
386{ 369{
@@ -412,14 +395,14 @@ int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
412 card->dev->dma_mask = &imx_pcm_dmamask; 395 card->dev->dma_mask = &imx_pcm_dmamask;
413 if (!card->dev->coherent_dma_mask) 396 if (!card->dev->coherent_dma_mask)
414 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 397 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
415 if (dai->playback.channels_min) { 398 if (dai->driver->playback.channels_min) {
416 ret = imx_pcm_preallocate_dma_buffer(pcm, 399 ret = imx_pcm_preallocate_dma_buffer(pcm,
417 SNDRV_PCM_STREAM_PLAYBACK); 400 SNDRV_PCM_STREAM_PLAYBACK);
418 if (ret) 401 if (ret)
419 goto out; 402 goto out;
420 } 403 }
421 404
422 if (dai->capture.channels_min) { 405 if (dai->driver->capture.channels_min) {
423 ret = imx_pcm_preallocate_dma_buffer(pcm, 406 ret = imx_pcm_preallocate_dma_buffer(pcm,
424 SNDRV_PCM_STREAM_CAPTURE); 407 SNDRV_PCM_STREAM_CAPTURE);
425 if (ret) 408 if (ret)
@@ -429,6 +412,7 @@ int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
429out: 412out:
430 return ret; 413 return ret;
431} 414}
415EXPORT_SYMBOL_GPL(imx_pcm_new);
432 416
433void imx_pcm_free(struct snd_pcm *pcm) 417void imx_pcm_free(struct snd_pcm *pcm)
434{ 418{
@@ -450,14 +434,40 @@ void imx_pcm_free(struct snd_pcm *pcm)
450 buf->area = NULL; 434 buf->area = NULL;
451 } 435 }
452} 436}
437EXPORT_SYMBOL_GPL(imx_pcm_free);
453 438
454struct snd_soc_platform imx_soc_platform = { 439static struct snd_soc_dai_driver imx_ssi_dai = {
455 .name = "imx-audio", 440 .playback = {
441 .channels_min = 2,
442 .channels_max = 2,
443 .rates = SNDRV_PCM_RATE_8000_96000,
444 .formats = SNDRV_PCM_FMTBIT_S16_LE,
445 },
446 .capture = {
447 .channels_min = 2,
448 .channels_max = 2,
449 .rates = SNDRV_PCM_RATE_8000_96000,
450 .formats = SNDRV_PCM_FMTBIT_S16_LE,
451 },
452 .ops = &imx_ssi_pcm_dai_ops,
456}; 453};
457EXPORT_SYMBOL_GPL(imx_soc_platform);
458 454
459static struct snd_soc_dai imx_ac97_dai = { 455static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
460 .name = "AC97", 456{
457 struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
458 uint32_t val;
459
460 snd_soc_dai_set_drvdata(dai, ssi);
461
462 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
463 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
464 writel(val, ssi->base + SSI_SFCSR);
465
466 return 0;
467}
468
469static struct snd_soc_dai_driver imx_ac97_dai = {
470 .probe = imx_ssi_dai_probe,
461 .ac97_control = 1, 471 .ac97_control = 1,
462 .playback = { 472 .playback = {
463 .stream_name = "AC97 Playback", 473 .stream_name = "AC97 Playback",
@@ -577,25 +587,18 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
577}; 587};
578EXPORT_SYMBOL_GPL(soc_ac97_ops); 588EXPORT_SYMBOL_GPL(soc_ac97_ops);
579 589
580struct snd_soc_dai imx_ssi_pcm_dai[2];
581EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
582
583static int imx_ssi_probe(struct platform_device *pdev) 590static int imx_ssi_probe(struct platform_device *pdev)
584{ 591{
585 struct resource *res; 592 struct resource *res;
586 struct imx_ssi *ssi; 593 struct imx_ssi *ssi;
587 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data; 594 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
588 struct snd_soc_platform *platform;
589 int ret = 0; 595 int ret = 0;
590 unsigned int val; 596 struct snd_soc_dai_driver *dai;
591 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
592
593 if (dai->id >= ARRAY_SIZE(imx_ssi_pcm_dai))
594 return -EINVAL;
595 597
596 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); 598 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
597 if (!ssi) 599 if (!ssi)
598 return -ENOMEM; 600 return -ENOMEM;
601 dev_set_drvdata(&pdev->dev, ssi);
599 602
600 if (pdata) { 603 if (pdata) {
601 ssi->ac97_reset = pdata->ac97_reset; 604 ssi->ac97_reset = pdata->ac97_reset;
@@ -640,9 +643,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
640 } 643 }
641 ac97_ssi = ssi; 644 ac97_ssi = ssi;
642 setup_channel_to_ac97(ssi); 645 setup_channel_to_ac97(ssi);
643 memcpy(dai, &imx_ac97_dai, sizeof(imx_ac97_dai)); 646 dai = &imx_ac97_dai;
644 } else 647 } else
645 memcpy(dai, &imx_ssi_dai, sizeof(imx_ssi_dai)); 648 dai = &imx_ssi_dai;
646 649
647 writel(0x0, ssi->base + SSI_SIER); 650 writel(0x0, ssi->base + SSI_SIER);
648 651
@@ -657,37 +660,36 @@ static int imx_ssi_probe(struct platform_device *pdev)
657 if (res) 660 if (res)
658 ssi->dma_params_rx.dma = res->start; 661 ssi->dma_params_rx.dma = res->start;
659 662
660 dai->id = pdev->id;
661 dai->dev = &pdev->dev;
662 dai->name = kasprintf(GFP_KERNEL, "imx-ssi.%d", pdev->id);
663 dai->private_data = ssi;
664
665 if ((cpu_is_mx27() || cpu_is_mx21()) && 663 if ((cpu_is_mx27() || cpu_is_mx21()) &&
666 !(ssi->flags & IMX_SSI_USE_AC97) && 664 !(ssi->flags & IMX_SSI_USE_AC97) &&
667 (ssi->flags & IMX_SSI_DMA)) { 665 (ssi->flags & IMX_SSI_DMA)) {
668 ssi->flags |= IMX_SSI_DMA; 666 ssi->flags |= IMX_SSI_DMA;
669 platform = imx_ssi_dma_mx2_init(pdev, ssi); 667 }
670 } else
671 platform = imx_ssi_fiq_init(pdev, ssi);
672
673 imx_soc_platform.pcm_ops = platform->pcm_ops;
674 imx_soc_platform.pcm_new = platform->pcm_new;
675 imx_soc_platform.pcm_free = platform->pcm_free;
676 668
677 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | 669 platform_set_drvdata(pdev, ssi);
678 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
679 writel(val, ssi->base + SSI_SFCSR);
680 670
681 ret = snd_soc_register_dai(dai); 671 ret = snd_soc_register_dai(&pdev->dev, dai);
682 if (ret) { 672 if (ret) {
683 dev_err(&pdev->dev, "register DAI failed\n"); 673 dev_err(&pdev->dev, "register DAI failed\n");
684 goto failed_register; 674 goto failed_register;
685 } 675 }
686 676
687 platform_set_drvdata(pdev, ssi); 677 ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
678 if (!ssi->soc_platform_pdev)
679 goto failed_pdev_alloc;
680 platform_set_drvdata(ssi->soc_platform_pdev, ssi);
681 ret = platform_device_add(ssi->soc_platform_pdev);
682 if (ret) {
683 dev_err(&pdev->dev, "failed to add platform device\n");
684 goto failed_pdev_add;
685 }
688 686
689 return 0; 687 return 0;
690 688
689failed_pdev_add:
690 platform_device_put(ssi->soc_platform_pdev);
691failed_pdev_alloc:
692 snd_soc_unregister_dai(&pdev->dev);
691failed_register: 693failed_register:
692failed_ac97: 694failed_ac97:
693 iounmap(ssi->base); 695 iounmap(ssi->base);
@@ -706,16 +708,15 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
706{ 708{
707 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 709 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
708 struct imx_ssi *ssi = platform_get_drvdata(pdev); 710 struct imx_ssi *ssi = platform_get_drvdata(pdev);
709 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
710 711
711 snd_soc_unregister_dai(dai); 712 platform_device_del(ssi->soc_platform_pdev);
713 platform_device_put(ssi->soc_platform_pdev);
714
715 snd_soc_unregister_dai(&pdev->dev);
712 716
713 if (ssi->flags & IMX_SSI_USE_AC97) 717 if (ssi->flags & IMX_SSI_USE_AC97)
714 ac97_ssi = NULL; 718 ac97_ssi = NULL;
715 719
716 if (!(ssi->flags & IMX_SSI_DMA))
717 imx_ssi_fiq_exit(pdev, ssi);
718
719 iounmap(ssi->base); 720 iounmap(ssi->base);
720 release_mem_region(res->start, resource_size(res)); 721 release_mem_region(res->start, resource_size(res));
721 clk_disable(ssi->clk); 722 clk_disable(ssi->clk);
@@ -730,34 +731,19 @@ static struct platform_driver imx_ssi_driver = {
730 .remove = __devexit_p(imx_ssi_remove), 731 .remove = __devexit_p(imx_ssi_remove),
731 732
732 .driver = { 733 .driver = {
733 .name = DRV_NAME, 734 .name = "imx-ssi-dai",
734 .owner = THIS_MODULE, 735 .owner = THIS_MODULE,
735 }, 736 },
736}; 737};
737 738
738static int __init imx_ssi_init(void) 739static int __init imx_ssi_init(void)
739{ 740{
740 int ret; 741 return platform_driver_register(&imx_ssi_driver);
741
742 ret = snd_soc_register_platform(&imx_soc_platform);
743 if (ret) {
744 pr_err("failed to register soc platform: %d\n", ret);
745 return ret;
746 }
747
748 ret = platform_driver_register(&imx_ssi_driver);
749 if (ret) {
750 snd_soc_unregister_platform(&imx_soc_platform);
751 return ret;
752 }
753
754 return 0;
755} 742}
756 743
757static void __exit imx_ssi_exit(void) 744static void __exit imx_ssi_exit(void)
758{ 745{
759 platform_driver_unregister(&imx_ssi_driver); 746 platform_driver_unregister(&imx_ssi_driver);
760 snd_soc_unregister_platform(&imx_soc_platform);
761} 747}
762 748
763module_init(imx_ssi_init); 749module_init(imx_ssi_init);
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 55f26ebcd8c2..53b780d9b2b0 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -183,9 +183,6 @@
183#define IMX_SSI_RX_DIV_PSR 4 183#define IMX_SSI_RX_DIV_PSR 4
184#define IMX_SSI_RX_DIV_PM 5 184#define IMX_SSI_RX_DIV_PM 5
185 185
186extern struct snd_soc_dai imx_ssi_pcm_dai[2];
187extern struct snd_soc_platform imx_soc_platform;
188
189#define DRV_NAME "imx-ssi" 186#define DRV_NAME "imx-ssi"
190 187
191struct imx_pcm_dma_params { 188struct imx_pcm_dma_params {
@@ -197,7 +194,7 @@ struct imx_pcm_dma_params {
197struct imx_ssi { 194struct imx_ssi {
198 struct platform_device *ac97_dev; 195 struct platform_device *ac97_dev;
199 196
200 struct snd_soc_device imx_ac97; 197 struct snd_soc_dai *imx_ac97;
201 struct clk *clk; 198 struct clk *clk;
202 void __iomem *base; 199 void __iomem *base;
203 int irq; 200 int irq;
@@ -213,6 +210,8 @@ struct imx_ssi {
213 struct imx_pcm_dma_params dma_params_tx; 210 struct imx_pcm_dma_params dma_params_tx;
214 211
215 int enabled; 212 int enabled;
213
214 struct platform_device *soc_platform_pdev;
216}; 215};
217 216
218struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, 217struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index a8307d55c70e..65f0f99ca6dd 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -32,23 +32,20 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
32 { 32 {
33 .name = "HiFi", 33 .name = "HiFi",
34 .stream_name = "HiFi", 34 .stream_name = "HiFi",
35 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 35 .codec_dai_name = "wm9712-hifi",
36 .codec_name = "wm9712-codec",
37 .cpu_dai_name = "imx-ssi-dai.0",
38 .platform_name = "imx-fiq-pcm-audio.0",
36 .ops = &imx_phycore_hifi_ops, 39 .ops = &imx_phycore_hifi_ops,
37 }, 40 },
38}; 41};
39 42
40static struct snd_soc_card imx_phycore = { 43static struct snd_soc_card imx_phycore = {
41 .name = "PhyCORE-audio", 44 .name = "PhyCORE-audio",
42 .platform = &imx_soc_platform,
43 .dai_link = imx_phycore_dai_ac97, 45 .dai_link = imx_phycore_dai_ac97,
44 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97), 46 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
45}; 47};
46 48
47static struct snd_soc_device imx_phycore_snd_devdata = {
48 .card = &imx_phycore,
49 .codec_dev = &soc_codec_dev_wm9712,
50};
51
52static struct platform_device *imx_phycore_snd_device; 49static struct platform_device *imx_phycore_snd_device;
53 50
54static int __init imx_phycore_init(void) 51static int __init imx_phycore_init(void)
@@ -63,10 +60,12 @@ static int __init imx_phycore_init(void)
63 if (!imx_phycore_snd_device) 60 if (!imx_phycore_snd_device)
64 return -ENOMEM; 61 return -ENOMEM;
65 62
66 imx_phycore_dai_ac97[0].cpu_dai = &imx_ssi_pcm_dai[0]; 63 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore);
64 ret = platform_device_add(imx_phycore_snd_device);
67 65
68 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore_snd_devdata); 66 imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
69 imx_phycore_snd_devdata.dev = &imx_phycore_snd_device->dev; 67 if (!imx_phycore_snd_device)
68 return -ENOMEM;
70 ret = platform_device_add(imx_phycore_snd_device); 69 ret = platform_device_add(imx_phycore_snd_device);
71 70
72 if (ret) { 71 if (ret) {
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index a6e7d9497639..74068636c1d8 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -82,8 +82,8 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params) 82 struct snd_pcm_hw_params *params)
83{ 83{
84 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 85 struct snd_soc_dai *codec_dai = rtd->codec_dai;
86 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 86 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
87 int i, found = 0; 87 int i, found = 0;
88 snd_pcm_format_t format = params_format(params); 88 snd_pcm_format_t format = params_format(params);
89 unsigned int rate = params_rate(params); 89 unsigned int rate = params_rate(params);
@@ -210,9 +210,9 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
210 { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE }, 210 { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
211}; 211};
212 212
213static int wm1133_ev1_init(struct snd_soc_codec *codec) 213static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
214{ 214{
215 struct snd_soc_card *card = codec->socdev->card; 215 struct snd_soc_codec *codec = rtd->codec;
216 216
217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets, 217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets,
218 ARRAY_SIZE(wm1133_ev1_widgets)); 218 ARRAY_SIZE(wm1133_ev1_widgets));
@@ -221,13 +221,13 @@ static int wm1133_ev1_init(struct snd_soc_codec *codec)
221 ARRAY_SIZE(wm1133_ev1_map)); 221 ARRAY_SIZE(wm1133_ev1_map));
222 222
223 /* Headphone jack detection */ 223 /* Headphone jack detection */
224 snd_soc_jack_new(card, "Headphone", SND_JACK_HEADPHONE, &hp_jack); 224 snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), 225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
226 hp_jack_pins); 226 hp_jack_pins);
227 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE); 227 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
228 228
229 /* Microphone jack detection */ 229 /* Microphone jack detection */
230 snd_soc_jack_new(card, "Microphone", 230 snd_soc_jack_new(codec, "Microphone",
231 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack); 231 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
232 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins), 232 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
233 mic_jack_pins); 233 mic_jack_pins);
@@ -243,8 +243,10 @@ static int wm1133_ev1_init(struct snd_soc_codec *codec)
243static struct snd_soc_dai_link wm1133_ev1_dai = { 243static struct snd_soc_dai_link wm1133_ev1_dai = {
244 .name = "WM1133-EV1", 244 .name = "WM1133-EV1",
245 .stream_name = "Audio", 245 .stream_name = "Audio",
246 .cpu_dai = &imx_ssi_pcm_dai[0], 246 .cpu_dai_name = "imx-ssi-dai.0",
247 .codec_dai = &wm8350_dai, 247 .codec_dai_name = "wm8350-hifi",
248 .platform_name = "imx-fiq-pcm-audio.0",
249 .codec_name = "wm8350-codec.0-0x1a",
248 .init = wm1133_ev1_init, 250 .init = wm1133_ev1_init,
249 .ops = &wm1133_ev1_ops, 251 .ops = &wm1133_ev1_ops,
250 .symmetric_rates = 1, 252 .symmetric_rates = 1,
@@ -252,16 +254,10 @@ static struct snd_soc_dai_link wm1133_ev1_dai = {
252 254
253static struct snd_soc_card wm1133_ev1 = { 255static struct snd_soc_card wm1133_ev1 = {
254 .name = "WM1133-EV1", 256 .name = "WM1133-EV1",
255 .platform = &imx_soc_platform,
256 .dai_link = &wm1133_ev1_dai, 257 .dai_link = &wm1133_ev1_dai,
257 .num_links = 1, 258 .num_links = 1,
258}; 259};
259 260
260static struct snd_soc_device wm1133_ev1_snd_devdata = {
261 .card = &wm1133_ev1,
262 .codec_dev = &soc_codec_dev_wm8350,
263};
264
265static struct platform_device *wm1133_ev1_snd_device; 261static struct platform_device *wm1133_ev1_snd_device;
266 262
267static int __init wm1133_ev1_audio_init(void) 263static int __init wm1133_ev1_audio_init(void)
@@ -286,8 +282,7 @@ static int __init wm1133_ev1_audio_init(void)
286 if (!wm1133_ev1_snd_device) 282 if (!wm1133_ev1_snd_device)
287 return -ENOMEM; 283 return -ENOMEM;
288 284
289 platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1_snd_devdata); 285 platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1);
290 wm1133_ev1_snd_devdata.dev = &wm1133_ev1_snd_device->dev;
291 ret = platform_device_add(wm1133_ev1_snd_device); 286 ret = platform_device_add(wm1133_ev1_snd_device);
292 287
293 if (ret) 288 if (ret)