aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/au1x/dbdma2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/au1x/dbdma2.c')
-rw-r--r--sound/soc/au1x/dbdma2.c95
1 files changed, 29 insertions, 66 deletions
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 6d9f4c624949..10fdd2854e58 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -10,9 +10,6 @@
10 * 10 *
11 * DMA glue for Au1x-PSC audio. 11 * DMA glue for Au1x-PSC audio.
12 * 12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 */ 13 */
17 14
18 15
@@ -61,9 +58,6 @@ struct au1xpsc_audio_dmadata {
61 int msbits; 58 int msbits;
62}; 59};
63 60
64/* instance data. There can be only one, MacLeod!!!! */
65static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2];
66
67/* 61/*
68 * These settings are somewhat okay, at least on my machine audio plays 62 * These settings are somewhat okay, at least on my machine audio plays
69 * almost skip-free. Especially the 64kB buffer seems to help a LOT. 63 * almost skip-free. Especially the 64kB buffer seems to help a LOT.
@@ -199,6 +193,14 @@ out:
199 return 0; 193 return 0;
200} 194}
201 195
196static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss)
197{
198 struct snd_soc_pcm_runtime *rtd = ss->private_data;
199 struct au1xpsc_audio_dmadata *pcd =
200 snd_soc_platform_get_drvdata(rtd->platform);
201 return &pcd[SUBSTREAM_TYPE(ss)];
202}
203
202static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, 204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params) 205 struct snd_pcm_hw_params *params)
204{ 206{
@@ -211,7 +213,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
211 goto out; 213 goto out;
212 214
213 stype = SUBSTREAM_TYPE(substream); 215 stype = SUBSTREAM_TYPE(substream);
214 pcd = au1xpsc_audio_pcmdma[stype]; 216 pcd = to_dmadata(substream);
215 217
216 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " 218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
217 "runtime->min_align %d\n", 219 "runtime->min_align %d\n",
@@ -249,8 +251,7 @@ static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream)
249 251
250static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) 252static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
251{ 253{
252 struct au1xpsc_audio_dmadata *pcd = 254 struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
253 au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)];
254 255
255 au1xxx_dbdma_reset(pcd->ddma_chan); 256 au1xxx_dbdma_reset(pcd->ddma_chan);
256 257
@@ -267,7 +268,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
267 268
268static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 269static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
269{ 270{
270 u32 c = au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->ddma_chan; 271 u32 c = to_dmadata(substream)->ddma_chan;
271 272
272 switch (cmd) { 273 switch (cmd) {
273 case SNDRV_PCM_TRIGGER_START: 274 case SNDRV_PCM_TRIGGER_START:
@@ -287,8 +288,7 @@ static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
287static snd_pcm_uframes_t 288static snd_pcm_uframes_t
288au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) 289au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
289{ 290{
290 return bytes_to_frames(substream->runtime, 291 return bytes_to_frames(substream->runtime, to_dmadata(substream)->pos);
291 au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->pos);
292} 292}
293 293
294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) 294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
@@ -299,7 +299,7 @@ static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
299 299
300static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) 300static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
301{ 301{
302 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]); 302 au1x_pcm_dbdma_free(to_dmadata(substream));
303 return 0; 303 return 0;
304} 304}
305 305
@@ -329,42 +329,21 @@ static int au1xpsc_pcm_new(struct snd_card *card,
329 return 0; 329 return 0;
330} 330}
331 331
332static int au1xpsc_pcm_probe(struct platform_device *pdev)
333{
334 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
335 return -ENODEV;
336
337 return 0;
338}
339
340static int au1xpsc_pcm_remove(struct platform_device *pdev)
341{
342 return 0;
343}
344
345/* au1xpsc audio platform */ 332/* au1xpsc audio platform */
346struct snd_soc_platform au1xpsc_soc_platform = { 333struct snd_soc_platform_driver au1xpsc_soc_platform = {
347 .name = "au1xpsc-pcm-dbdma", 334 .ops = &au1xpsc_pcm_ops,
348 .probe = au1xpsc_pcm_probe,
349 .remove = au1xpsc_pcm_remove,
350 .pcm_ops = &au1xpsc_pcm_ops,
351 .pcm_new = au1xpsc_pcm_new, 335 .pcm_new = au1xpsc_pcm_new,
352 .pcm_free = au1xpsc_pcm_free_dma_buffers, 336 .pcm_free = au1xpsc_pcm_free_dma_buffers,
353}; 337};
354EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
355 338
356static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) 339static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
357{ 340{
341 struct au1xpsc_audio_dmadata *dmadata;
358 struct resource *r; 342 struct resource *r;
359 int ret; 343 int ret;
360 344
361 if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX]) 345 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
362 return -EBUSY; 346 if (!dmadata)
363
364 /* TX DMA */
365 au1xpsc_audio_pcmdma[PCM_TX]
366 = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
367 if (!au1xpsc_audio_pcmdma[PCM_TX])
368 return -ENOMEM; 347 return -ENOMEM;
369 348
370 r = platform_get_resource(pdev, IORESOURCE_DMA, 0); 349 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -372,47 +351,33 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
372 ret = -ENODEV; 351 ret = -ENODEV;
373 goto out1; 352 goto out1;
374 } 353 }
375 (au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start; 354 dmadata[PCM_TX].ddma_id = r->start;
376 355
377 /* RX DMA */ 356 /* RX DMA */
378 au1xpsc_audio_pcmdma[PCM_RX]
379 = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
380 if (!au1xpsc_audio_pcmdma[PCM_RX])
381 return -ENOMEM;
382
383 r = platform_get_resource(pdev, IORESOURCE_DMA, 1); 357 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
384 if (!r) { 358 if (!r) {
385 ret = -ENODEV; 359 ret = -ENODEV;
386 goto out2; 360 goto out1;
387 } 361 }
388 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; 362 dmadata[PCM_RX].ddma_id = r->start;
363
364 platform_set_drvdata(pdev, dmadata);
389 365
390 ret = snd_soc_register_platform(&au1xpsc_soc_platform); 366 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
391 if (!ret) 367 if (!ret)
392 return ret; 368 return ret;
393 369
394out2:
395 kfree(au1xpsc_audio_pcmdma[PCM_RX]);
396 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
397out1: 370out1:
398 kfree(au1xpsc_audio_pcmdma[PCM_TX]); 371 kfree(dmadata);
399 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
400 return ret; 372 return ret;
401} 373}
402 374
403static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) 375static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
404{ 376{
405 int i; 377 struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev);
406 378
407 snd_soc_unregister_platform(&au1xpsc_soc_platform); 379 snd_soc_unregister_platform(&pdev->dev);
408 380 kfree(dmadata);
409 for (i = 0; i < 2; i++) {
410 if (au1xpsc_audio_pcmdma[i]) {
411 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
412 kfree(au1xpsc_audio_pcmdma[i]);
413 au1xpsc_audio_pcmdma[i] = NULL;
414 }
415 }
416 381
417 return 0; 382 return 0;
418} 383}
@@ -428,8 +393,6 @@ static struct platform_driver au1xpsc_pcm_driver = {
428 393
429static int __init au1xpsc_audio_dbdma_load(void) 394static int __init au1xpsc_audio_dbdma_load(void)
430{ 395{
431 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
432 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
433 return platform_driver_register(&au1xpsc_pcm_driver); 396 return platform_driver_register(&au1xpsc_pcm_driver);
434} 397}
435 398
@@ -467,7 +430,7 @@ struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
467 res[1].start = res[1].end = id[1]; 430 res[1].start = res[1].end = id[1];
468 res[0].flags = res[1].flags = IORESOURCE_DMA; 431 res[0].flags = res[1].flags = IORESOURCE_DMA;
469 432
470 pd = platform_device_alloc("au1xpsc-pcm", -1); 433 pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
471 if (!pd) 434 if (!pd)
472 goto out; 435 goto out;
473 436