aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s6000
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/s6000
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/s6000')
-rw-r--r--sound/soc/s6000/s6000-i2s.c56
-rw-r--r--sound/soc/s6000/s6000-i2s.h2
-rw-r--r--sound/soc/s6000/s6000-pcm.c100
-rw-r--r--sound/soc/s6000/s6000-pcm.h2
-rw-r--r--sound/soc/s6000/s6105-ipcam.c31
5 files changed, 97 insertions, 94 deletions
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 59e3fa7bcb05..8778faa174a6 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -140,7 +140,7 @@ static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel)
140static void s6000_i2s_start(struct snd_pcm_substream *substream) 140static void s6000_i2s_start(struct snd_pcm_substream *substream)
141{ 141{
142 struct snd_soc_pcm_runtime *rtd = substream->private_data; 142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
143 struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; 143 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
144 int channel; 144 int channel;
145 145
146 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 146 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
@@ -152,7 +152,7 @@ static void s6000_i2s_start(struct snd_pcm_substream *substream)
152static void s6000_i2s_stop(struct snd_pcm_substream *substream) 152static void s6000_i2s_stop(struct snd_pcm_substream *substream)
153{ 153{
154 struct snd_soc_pcm_runtime *rtd = substream->private_data; 154 struct snd_soc_pcm_runtime *rtd = substream->private_data;
155 struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; 155 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
156 int channel; 156 int channel;
157 157
158 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 158 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
@@ -194,7 +194,7 @@ static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev)
194 194
195static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai) 195static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai)
196{ 196{
197 struct s6000_i2s_dev *dev = cpu_dai->private_data; 197 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
198 unsigned int errors; 198 unsigned int errors;
199 unsigned int ret; 199 unsigned int ret;
200 200
@@ -232,7 +232,7 @@ static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev)
232static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 232static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
233 unsigned int fmt) 233 unsigned int fmt)
234{ 234{
235 struct s6000_i2s_dev *dev = cpu_dai->private_data; 235 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
236 u32 w; 236 u32 w;
237 237
238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -273,7 +273,7 @@ static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
273 273
274static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) 274static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
275{ 275{
276 struct s6000_i2s_dev *dev = dai->private_data; 276 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
277 277
278 if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2) 278 if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2)
279 return -EINVAL; 279 return -EINVAL;
@@ -287,7 +287,7 @@ static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
287 struct snd_pcm_hw_params *params, 287 struct snd_pcm_hw_params *params,
288 struct snd_soc_dai *dai) 288 struct snd_soc_dai *dai)
289{ 289{
290 struct s6000_i2s_dev *dev = dai->private_data; 290 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
291 int interf; 291 int interf;
292 u32 w = 0; 292 u32 w = 0;
293 293
@@ -326,15 +326,17 @@ static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
326 return 0; 326 return 0;
327} 327}
328 328
329static int s6000_i2s_dai_probe(struct platform_device *pdev, 329static int s6000_i2s_dai_probe(struct snd_soc_dai *dai)
330 struct snd_soc_dai *dai)
331{ 330{
332 struct s6000_i2s_dev *dev = dai->private_data; 331 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
333 struct s6000_snd_platform_data *pdata = pdev->dev.platform_data; 332 struct s6000_snd_platform_data *pdata = dai->dev->platform_data;
334 333
335 if (!pdata) 334 if (!pdata)
336 return -EINVAL; 335 return -EINVAL;
337 336
337 dai->capture_dma_data = &dev->dma_params;
338 dai->playback_dma_data = &dev->dma_params;
339
338 dev->wide = pdata->wide; 340 dev->wide = pdata->wide;
339 dev->channel_in = pdata->channel_in; 341 dev->channel_in = pdata->channel_in;
340 dev->channel_out = pdata->channel_out; 342 dev->channel_out = pdata->channel_out;
@@ -352,10 +354,10 @@ static int s6000_i2s_dai_probe(struct platform_device *pdev,
352 354
353 dev->channel_in = 0; 355 dev->channel_in = 0;
354 dev->channel_out = 1; 356 dev->channel_out = 1;
355 dai->capture.channels_min = 2 * dev->lines_in; 357 dai->driver->capture.channels_min = 2 * dev->lines_in;
356 dai->capture.channels_max = dai->capture.channels_min; 358 dai->driver->capture.channels_max = dai->driver->capture.channels_min;
357 dai->playback.channels_min = 2 * dev->lines_out; 359 dai->driver->playback.channels_min = 2 * dev->lines_out;
358 dai->playback.channels_max = dai->playback.channels_min; 360 dai->driver->playback.channels_max = dai->driver->playback.channels_min;
359 361
360 for (i = 0; i < dev->lines_out; i++) 362 for (i = 0; i < dev->lines_out; i++)
361 s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT); 363 s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT);
@@ -372,10 +374,10 @@ static int s6000_i2s_dai_probe(struct platform_device *pdev,
372 if (dev->lines_in > 1 || dev->lines_out > 1) 374 if (dev->lines_in > 1 || dev->lines_out > 1)
373 return -EINVAL; 375 return -EINVAL;
374 376
375 dai->capture.channels_min = 2 * dev->lines_in; 377 dai->driver->capture.channels_min = 2 * dev->lines_in;
376 dai->capture.channels_max = 8 * dev->lines_in; 378 dai->driver->capture.channels_max = 8 * dev->lines_in;
377 dai->playback.channels_min = 2 * dev->lines_out; 379 dai->driver->playback.channels_min = 2 * dev->lines_out;
378 dai->playback.channels_max = 8 * dev->lines_out; 380 dai->driver->playback.channels_max = 8 * dev->lines_out;
379 381
380 if (dev->lines_in) 382 if (dev->lines_in)
381 cfg[dev->channel_in] = S6_I2S_IN; 383 cfg[dev->channel_in] = S6_I2S_IN;
@@ -413,9 +415,7 @@ static struct snd_soc_dai_ops s6000_i2s_dai_ops = {
413 .hw_params = s6000_i2s_hw_params, 415 .hw_params = s6000_i2s_hw_params,
414}; 416};
415 417
416struct snd_soc_dai s6000_i2s_dai = { 418static struct snd_soc_dai_driver s6000_i2s_dai = {
417 .name = "s6000-i2s",
418 .id = 0,
419 .probe = s6000_i2s_dai_probe, 419 .probe = s6000_i2s_dai_probe,
420 .playback = { 420 .playback = {
421 .channels_min = 2, 421 .channels_min = 2,
@@ -435,7 +435,6 @@ struct snd_soc_dai s6000_i2s_dai = {
435 }, 435 },
436 .ops = &s6000_i2s_dai_ops, 436 .ops = &s6000_i2s_dai_ops,
437} 437}
438EXPORT_SYMBOL_GPL(s6000_i2s_dai);
439 438
440static int __devinit s6000_i2s_probe(struct platform_device *pdev) 439static int __devinit s6000_i2s_probe(struct platform_device *pdev)
441{ 440{
@@ -513,11 +512,7 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
513 ret = -ENOMEM; 512 ret = -ENOMEM;
514 goto err_release_dma2; 513 goto err_release_dma2;
515 } 514 }
516 515 dev_set_drvdata(&pdev->dev, dev);
517 s6000_i2s_dai.dev = &pdev->dev;
518 s6000_i2s_dai.private_data = dev;
519 s6000_i2s_dai.capture.dma_data = &dev->dma_params;
520 s6000_i2s_dai.playback.dma_data = &dev->dma_params;
521 516
522 dev->sifbase = sifmem->start; 517 dev->sifbase = sifmem->start;
523 dev->scbbase = mmio; 518 dev->scbbase = mmio;
@@ -548,7 +543,7 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
548 S6_I2S_INT_UNDERRUN | 543 S6_I2S_INT_UNDERRUN |
549 S6_I2S_INT_OVERRUN); 544 S6_I2S_INT_OVERRUN);
550 545
551 ret = snd_soc_register_dai(&s6000_i2s_dai); 546 ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai);
552 if (ret) 547 if (ret)
553 goto err_release_dev; 548 goto err_release_dev;
554 549
@@ -573,17 +568,16 @@ err_release_none:
573 568
574static void __devexit s6000_i2s_remove(struct platform_device *pdev) 569static void __devexit s6000_i2s_remove(struct platform_device *pdev)
575{ 570{
576 struct s6000_i2s_dev *dev = s6000_i2s_dai.private_data; 571 struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
577 struct resource *region; 572 struct resource *region;
578 void __iomem *mmio = dev->scbbase; 573 void __iomem *mmio = dev->scbbase;
579 574
580 snd_soc_unregister_dai(&s6000_i2s_dai); 575 snd_soc_unregister_dai(&pdev->dev);
581 576
582 s6000_i2s_stop_channel(dev, 0); 577 s6000_i2s_stop_channel(dev, 0);
583 s6000_i2s_stop_channel(dev, 1); 578 s6000_i2s_stop_channel(dev, 1);
584 579
585 s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0); 580 s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
586 s6000_i2s_dai.private_data = 0;
587 kfree(dev); 581 kfree(dev);
588 582
589 region = platform_get_resource(pdev, IORESOURCE_DMA, 0); 583 region = platform_get_resource(pdev, IORESOURCE_DMA, 0);
diff --git a/sound/soc/s6000/s6000-i2s.h b/sound/soc/s6000/s6000-i2s.h
index 2375fdfe6dba..86aa1921c89e 100644
--- a/sound/soc/s6000/s6000-i2s.h
+++ b/sound/soc/s6000/s6000-i2s.h
@@ -12,8 +12,6 @@
12#ifndef _S6000_I2S_H 12#ifndef _S6000_I2S_H
13#define _S6000_I2S_H 13#define _S6000_I2S_H
14 14
15extern struct snd_soc_dai s6000_i2s_dai;
16
17struct s6000_snd_platform_data { 15struct s6000_snd_platform_data {
18 int lines_in; 16 int lines_in;
19 int lines_out; 17 int lines_out;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 9c7f7f00cebb..271fd222bf19 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -65,7 +65,7 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
65 dma_addr_t dma_pos; 65 dma_addr_t dma_pos;
66 dma_addr_t src, dst; 66 dma_addr_t src, dst;
67 67
68 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 68 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
69 69
70 period_size = snd_pcm_lib_period_bytes(substream); 70 period_size = snd_pcm_lib_period_bytes(substream);
71 dma_offset = prtd->period * period_size; 71 dma_offset = prtd->period * period_size;
@@ -103,23 +103,25 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
103{ 103{
104 struct snd_pcm *pcm = data; 104 struct snd_pcm *pcm = data;
105 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 105 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
106 struct s6000_pcm_dma_params *params =
107 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
108 struct s6000_runtime_data *prtd; 106 struct s6000_runtime_data *prtd;
109 unsigned int has_xrun; 107 unsigned int has_xrun;
110 int i, ret = IRQ_NONE; 108 int i, ret = IRQ_NONE;
111 u32 channel[2] = {
112 [SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out,
113 [SNDRV_PCM_STREAM_CAPTURE] = params->dma_in
114 };
115
116 has_xrun = params->check_xrun(runtime->dai->cpu_dai);
117 109
118 for (i = 0; i < ARRAY_SIZE(channel); ++i) { 110 for (i = 0; i < 2; ++i) {
119 struct snd_pcm_substream *substream = pcm->streams[i].substream; 111 struct snd_pcm_substream *substream = pcm->streams[i].substream;
112 struct s6000_pcm_dma_params *params =
113 snd_soc_dai_get_dma_data(runtime->cpu_dai, substream);
114 u32 channel;
120 unsigned int pending; 115 unsigned int pending;
121 116
122 if (!channel[i]) 117 if (substream == SNDRV_PCM_STREAM_PLAYBACK)
118 channel = params->dma_out;
119 else
120 channel = params->dma_in;
121
122 has_xrun = params->check_xrun(runtime->cpu_dai);
123
124 if (!channel)
123 continue; 125 continue;
124 126
125 if (unlikely(has_xrun & (1 << i)) && 127 if (unlikely(has_xrun & (1 << i)) &&
@@ -130,8 +132,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
130 ret = IRQ_HANDLED; 132 ret = IRQ_HANDLED;
131 } 133 }
132 134
133 pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]), 135 pending = s6dmac_int_sources(DMA_MASK_DMAC(channel),
134 DMA_INDEX_CHNL(channel[i])); 136 DMA_INDEX_CHNL(channel));
135 137
136 if (pending & 1) { 138 if (pending & 1) {
137 ret = IRQ_HANDLED; 139 ret = IRQ_HANDLED;
@@ -139,10 +141,10 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
139 snd_pcm_running(substream))) { 141 snd_pcm_running(substream))) {
140 snd_pcm_period_elapsed(substream); 142 snd_pcm_period_elapsed(substream);
141 dev_dbg(pcm->dev, "period elapsed %x %x\n", 143 dev_dbg(pcm->dev, "period elapsed %x %x\n",
142 s6dmac_cur_src(DMA_MASK_DMAC(channel[i]), 144 s6dmac_cur_src(DMA_MASK_DMAC(channel),
143 DMA_INDEX_CHNL(channel[i])), 145 DMA_INDEX_CHNL(channel)),
144 s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]), 146 s6dmac_cur_dst(DMA_MASK_DMAC(channel),
145 DMA_INDEX_CHNL(channel[i]))); 147 DMA_INDEX_CHNL(channel)));
146 prtd = substream->runtime->private_data; 148 prtd = substream->runtime->private_data;
147 spin_lock(&prtd->lock); 149 spin_lock(&prtd->lock);
148 s6000_pcm_enqueue_dma(substream); 150 s6000_pcm_enqueue_dma(substream);
@@ -154,16 +156,16 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
154 if (pending & (1 << 3)) 156 if (pending & (1 << 3))
155 printk(KERN_WARNING 157 printk(KERN_WARNING
156 "s6000-pcm: DMA %x Underflow\n", 158 "s6000-pcm: DMA %x Underflow\n",
157 channel[i]); 159 channel);
158 if (pending & (1 << 4)) 160 if (pending & (1 << 4))
159 printk(KERN_WARNING 161 printk(KERN_WARNING
160 "s6000-pcm: DMA %x Overflow\n", 162 "s6000-pcm: DMA %x Overflow\n",
161 channel[i]); 163 channel);
162 if (pending & 0x1e0) 164 if (pending & 0x1e0)
163 printk(KERN_WARNING 165 printk(KERN_WARNING
164 "s6000-pcm: DMA %x Master Error " 166 "s6000-pcm: DMA %x Master Error "
165 "(mask %x)\n", 167 "(mask %x)\n",
166 channel[i], pending >> 5); 168 channel, pending >> 5);
167 169
168 } 170 }
169 } 171 }
@@ -180,7 +182,7 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
180 int srcinc; 182 int srcinc;
181 u32 dma; 183 u32 dma;
182 184
183 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 185 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
184 186
185 spin_lock_irqsave(&prtd->lock, flags); 187 spin_lock_irqsave(&prtd->lock, flags);
186 188
@@ -221,7 +223,7 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
221 unsigned long flags; 223 unsigned long flags;
222 u32 channel; 224 u32 channel;
223 225
224 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 226 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
225 227
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
227 channel = par->dma_out; 229 channel = par->dma_out;
@@ -246,7 +248,7 @@ static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
246 struct s6000_pcm_dma_params *par; 248 struct s6000_pcm_dma_params *par;
247 int ret; 249 int ret;
248 250
249 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 251 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
250 252
251 ret = par->trigger(substream, cmd, 0); 253 ret = par->trigger(substream, cmd, 0);
252 if (ret < 0) 254 if (ret < 0)
@@ -291,7 +293,7 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
291 unsigned int offset; 293 unsigned int offset;
292 dma_addr_t count; 294 dma_addr_t count;
293 295
294 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 296 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
295 297
296 spin_lock_irqsave(&prtd->lock, flags); 298 spin_lock_irqsave(&prtd->lock, flags);
297 299
@@ -321,7 +323,7 @@ static int s6000_pcm_open(struct snd_pcm_substream *substream)
321 struct s6000_runtime_data *prtd; 323 struct s6000_runtime_data *prtd;
322 int ret; 324 int ret;
323 325
324 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 326 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
325 snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); 327 snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
326 328
327 ret = snd_pcm_hw_constraint_step(runtime, 0, 329 ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -385,7 +387,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
385 return ret; 387 return ret;
386 } 388 }
387 389
388 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 390 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
389 391
390 if (par->same_rate) { 392 if (par->same_rate) {
391 spin_lock(&par->lock); 393 spin_lock(&par->lock);
@@ -407,7 +409,7 @@ static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
407{ 409{
408 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 410 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
409 struct s6000_pcm_dma_params *par = 411 struct s6000_pcm_dma_params *par =
410 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 412 snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
411 413
412 spin_lock(&par->lock); 414 spin_lock(&par->lock);
413 par->in_use &= ~(1 << substream->stream); 415 par->in_use &= ~(1 << substream->stream);
@@ -433,7 +435,7 @@ static void s6000_pcm_free(struct snd_pcm *pcm)
433{ 435{
434 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 436 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
435 struct s6000_pcm_dma_params *params = 437 struct s6000_pcm_dma_params *params =
436 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 438 snd_soc_dai_get_dma_data(runtime->cpu_dai, pcm->streams[0].substream);
437 439
438 free_irq(params->irq, pcm); 440 free_irq(params->irq, pcm);
439 snd_pcm_lib_preallocate_free_for_all(pcm); 441 snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -448,7 +450,8 @@ static int s6000_pcm_new(struct snd_card *card,
448 struct s6000_pcm_dma_params *params; 450 struct s6000_pcm_dma_params *params;
449 int res; 451 int res;
450 452
451 params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 453 params = snd_soc_dai_get_dma_data(runtime->cpu_dai,
454 pcm->streams[0].substream);
452 455
453 if (!card->dev->dma_mask) 456 if (!card->dev->dma_mask)
454 card->dev->dma_mask = &s6000_pcm_dmamask; 457 card->dev->dma_mask = &s6000_pcm_dmamask;
@@ -490,25 +493,44 @@ static int s6000_pcm_new(struct snd_card *card,
490 return 0; 493 return 0;
491} 494}
492 495
493struct snd_soc_platform s6000_soc_platform = { 496static struct snd_soc_platform_driver s6000_soc_platform = {
494 .name = "s6000-audio", 497 .ops = &s6000_pcm_ops,
495 .pcm_ops = &s6000_pcm_ops,
496 .pcm_new = s6000_pcm_new, 498 .pcm_new = s6000_pcm_new,
497 .pcm_free = s6000_pcm_free, 499 .pcm_free = s6000_pcm_free,
498}; 500};
499EXPORT_SYMBOL_GPL(s6000_soc_platform);
500 501
501static int __init s6000_pcm_init(void) 502static int __devinit s6000_soc_platform_probe(struct platform_device *pdev)
503{
504 return snd_soc_register_platform(&pdev->dev, &s6000_soc_platform);
505}
506
507static int __devexit s6000_soc_platform_remove(struct platform_device *pdev)
508{
509 snd_soc_unregister_platform(&pdev->dev);
510 return 0;
511}
512
513static struct platform_driver s6000_pcm_driver = {
514 .driver = {
515 .name = "s6000-pcm-audio",
516 .owner = THIS_MODULE,
517 },
518
519 .probe = s6000_soc_platform_probe,
520 .remove = __devexit_p(s6000_soc_platform_remove),
521};
522
523static int __init snd_s6000_pcm_init(void)
502{ 524{
503 return snd_soc_register_platform(&s6000_soc_platform); 525 return platform_driver_register(&s6000_pcm_driver);
504} 526}
505module_init(s6000_pcm_init); 527module_init(snd_s6000_pcm_init);
506 528
507static void __exit s6000_pcm_exit(void) 529static void __exit snd_s6000_pcm_exit(void)
508{ 530{
509 snd_soc_unregister_platform(&s6000_soc_platform); 531 platform_driver_unregister(&s6000_pcm_driver);
510} 532}
511module_exit(s6000_pcm_exit); 533module_exit(snd_s6000_pcm_exit);
512 534
513MODULE_AUTHOR("Daniel Gloeckner"); 535MODULE_AUTHOR("Daniel Gloeckner");
514MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module"); 536MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
diff --git a/sound/soc/s6000/s6000-pcm.h b/sound/soc/s6000/s6000-pcm.h
index 96f23f6f52bf..09d9b883e58b 100644
--- a/sound/soc/s6000/s6000-pcm.h
+++ b/sound/soc/s6000/s6000-pcm.h
@@ -30,6 +30,4 @@ struct s6000_pcm_dma_params {
30 int rate; 30 int rate;
31}; 31};
32 32
33extern struct snd_soc_platform s6000_soc_platform;
34
35#endif 33#endif
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index c1b40ac22c05..96c05e137538 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -32,8 +32,8 @@ static int s6105_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
33{ 33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 35 struct snd_soc_dai *codec_dai = rtd->codec_dai;
36 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 36 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
37 int ret = 0; 37 int ret = 0;
38 38
39 /* set codec DAI configuration */ 39 /* set codec DAI configuration */
@@ -134,8 +134,10 @@ static const struct snd_kcontrol_new audio_out_mux = {
134}; 134};
135 135
136/* Logic for a aic3x as connected on the s6105 ip camera ref design */ 136/* Logic for a aic3x as connected on the s6105 ip camera ref design */
137static int s6105_aic3x_init(struct snd_soc_codec *codec) 137static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
138{ 138{
139 struct snd_soc_codec *codec = rtd->codec;
140
139 /* Add s6105 specific widgets */ 141 /* Add s6105 specific widgets */
140 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 142 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
141 ARRAY_SIZE(aic3x_dapm_widgets)); 143 ARRAY_SIZE(aic3x_dapm_widgets));
@@ -165,7 +167,7 @@ static int s6105_aic3x_init(struct snd_soc_codec *codec)
165 167
166 snd_soc_dapm_sync(codec); 168 snd_soc_dapm_sync(codec);
167 169
168 snd_ctl_add(codec->card, snd_ctl_new1(&audio_out_mux, codec)); 170 snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec));
169 171
170 return 0; 172 return 0;
171} 173}
@@ -174,8 +176,10 @@ static int s6105_aic3x_init(struct snd_soc_codec *codec)
174static struct snd_soc_dai_link s6105_dai = { 176static struct snd_soc_dai_link s6105_dai = {
175 .name = "TLV320AIC31", 177 .name = "TLV320AIC31",
176 .stream_name = "AIC31", 178 .stream_name = "AIC31",
177 .cpu_dai = &s6000_i2s_dai, 179 .cpu_dai_name = "s6000-i2s",
178 .codec_dai = &aic3x_dai, 180 .codec_dai_name = "tlv320aic3x-hifi",
181 .platform_name = "s6000-pcm-audio",
182 .codec_name = "tlv320aic3x-codec.0-001a",
179 .init = s6105_aic3x_init, 183 .init = s6105_aic3x_init,
180 .ops = &s6105_ops, 184 .ops = &s6105_ops,
181}; 185};
@@ -183,22 +187,10 @@ static struct snd_soc_dai_link s6105_dai = {
183/* s6105 audio machine driver */ 187/* s6105 audio machine driver */
184static struct snd_soc_card snd_soc_card_s6105 = { 188static struct snd_soc_card snd_soc_card_s6105 = {
185 .name = "Stretch IP Camera", 189 .name = "Stretch IP Camera",
186 .platform = &s6000_soc_platform,
187 .dai_link = &s6105_dai, 190 .dai_link = &s6105_dai,
188 .num_links = 1, 191 .num_links = 1,
189}; 192};
190 193
191/* s6105 audio private data */
192static struct aic3x_setup_data s6105_aic3x_setup = {
193};
194
195/* s6105 audio subsystem */
196static struct snd_soc_device s6105_snd_devdata = {
197 .card = &snd_soc_card_s6105,
198 .codec_dev = &soc_codec_dev_aic3x,
199 .codec_data = &s6105_aic3x_setup,
200};
201
202static struct s6000_snd_platform_data __initdata s6105_snd_data = { 194static struct s6000_snd_platform_data __initdata s6105_snd_data = {
203 .wide = 0, 195 .wide = 0,
204 .channel_in = 0, 196 .channel_in = 0,
@@ -227,8 +219,7 @@ static int __init s6105_init(void)
227 if (!s6105_snd_device) 219 if (!s6105_snd_device)
228 return -ENOMEM; 220 return -ENOMEM;
229 221
230 platform_set_drvdata(s6105_snd_device, &s6105_snd_devdata); 222 platform_set_drvdata(s6105_snd_device, &snd_soc_card_s6105);
231 s6105_snd_devdata.dev = &s6105_snd_device->dev;
232 platform_device_add_data(s6105_snd_device, &s6105_snd_data, 223 platform_device_add_data(s6105_snd_device, &s6105_snd_data,
233 sizeof(s6105_snd_data)); 224 sizeof(s6105_snd_data));
234 225