diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2010-08-26 08:53:51 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-31 08:06:31 -0400 |
commit | ffc4fdbbe1b4be79e98340ebcd5a0ade6f5de318 (patch) | |
tree | e4f16ef2561497482df5ac9039ba7bdb21212b2d /sound/soc/au1x/dbdma2.c | |
parent | 0bb5f267af41c39af895faee3abe2d9ab8c562e0 (diff) |
ASoC: fix au1x platform
This patch fixes up the au1x audio platform after the multi-component
merge:
- compile fixes and updates to get DB1200 platform audio working again,
- removal of global variables in AC97/I2S/DMA(PCM) modules.
The AC97 part is limited to one instance only for now due to issues
with getting at driver data in the soc_ac97_ops.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/au1x/dbdma2.c')
-rw-r--r-- | sound/soc/au1x/dbdma2.c | 82 |
1 files changed, 26 insertions, 56 deletions
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 00fdb9cbfc2d..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!!!! */ | ||
65 | static 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 | ||
196 | static 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 | |||
202 | static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, | 204 | static 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 | ||
250 | static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) | 252 | static 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 | ||
268 | static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 269 | static 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) | |||
287 | static snd_pcm_uframes_t | 288 | static snd_pcm_uframes_t |
288 | au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) | 289 | au1xpsc_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 | ||
294 | static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) | 294 | static 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 | ||
300 | static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) | 300 | static 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,35 +329,21 @@ static int au1xpsc_pcm_new(struct snd_card *card, | |||
329 | return 0; | 329 | return 0; |
330 | } | 330 | } |
331 | 331 | ||
332 | static int au1xpsc_pcm_probe(struct snd_soc_platform *platform) | ||
333 | { | ||
334 | if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX]) | ||
335 | return -ENODEV; | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | /* au1xpsc audio platform */ | 332 | /* au1xpsc audio platform */ |
341 | struct snd_soc_platform_driver au1xpsc_soc_platform = { | 333 | struct snd_soc_platform_driver au1xpsc_soc_platform = { |
342 | .probe = au1xpsc_pcm_probe, | ||
343 | .ops = &au1xpsc_pcm_ops, | 334 | .ops = &au1xpsc_pcm_ops, |
344 | .pcm_new = au1xpsc_pcm_new, | 335 | .pcm_new = au1xpsc_pcm_new, |
345 | .pcm_free = au1xpsc_pcm_free_dma_buffers, | 336 | .pcm_free = au1xpsc_pcm_free_dma_buffers, |
346 | }; | 337 | }; |
347 | EXPORT_SYMBOL_GPL(au1xpsc_soc_platform); | ||
348 | 338 | ||
349 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) | 339 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) |
350 | { | 340 | { |
341 | struct au1xpsc_audio_dmadata *dmadata; | ||
351 | struct resource *r; | 342 | struct resource *r; |
352 | int ret; | 343 | int ret; |
353 | 344 | ||
354 | if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX]) | 345 | dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); |
355 | return -EBUSY; | 346 | if (!dmadata) |
356 | |||
357 | /* TX DMA */ | ||
358 | au1xpsc_audio_pcmdma[PCM_TX] | ||
359 | = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); | ||
360 | if (!au1xpsc_audio_pcmdma[PCM_TX]) | ||
361 | return -ENOMEM; | 347 | return -ENOMEM; |
362 | 348 | ||
363 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 349 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -365,54 +351,40 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) | |||
365 | ret = -ENODEV; | 351 | ret = -ENODEV; |
366 | goto out1; | 352 | goto out1; |
367 | } | 353 | } |
368 | (au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start; | 354 | dmadata[PCM_TX].ddma_id = r->start; |
369 | 355 | ||
370 | /* RX DMA */ | 356 | /* RX DMA */ |
371 | au1xpsc_audio_pcmdma[PCM_RX] | ||
372 | = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); | ||
373 | if (!au1xpsc_audio_pcmdma[PCM_RX]) | ||
374 | return -ENOMEM; | ||
375 | |||
376 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | 357 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); |
377 | if (!r) { | 358 | if (!r) { |
378 | ret = -ENODEV; | 359 | ret = -ENODEV; |
379 | goto out2; | 360 | goto out1; |
380 | } | 361 | } |
381 | (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; | 362 | dmadata[PCM_RX].ddma_id = r->start; |
363 | |||
364 | platform_set_drvdata(pdev, dmadata); | ||
382 | 365 | ||
383 | ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); | 366 | ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); |
384 | if (!ret) | 367 | if (!ret) |
385 | return ret; | 368 | return ret; |
386 | 369 | ||
387 | out2: | ||
388 | kfree(au1xpsc_audio_pcmdma[PCM_RX]); | ||
389 | au1xpsc_audio_pcmdma[PCM_RX] = NULL; | ||
390 | out1: | 370 | out1: |
391 | kfree(au1xpsc_audio_pcmdma[PCM_TX]); | 371 | kfree(dmadata); |
392 | au1xpsc_audio_pcmdma[PCM_TX] = NULL; | ||
393 | return ret; | 372 | return ret; |
394 | } | 373 | } |
395 | 374 | ||
396 | static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) | 375 | static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) |
397 | { | 376 | { |
398 | int i; | 377 | struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev); |
399 | 378 | ||
400 | snd_soc_unregister_platform(&pdev->dev); | 379 | snd_soc_unregister_platform(&pdev->dev); |
401 | 380 | kfree(dmadata); | |
402 | for (i = 0; i < 2; i++) { | ||
403 | if (au1xpsc_audio_pcmdma[i]) { | ||
404 | au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); | ||
405 | kfree(au1xpsc_audio_pcmdma[i]); | ||
406 | au1xpsc_audio_pcmdma[i] = NULL; | ||
407 | } | ||
408 | } | ||
409 | 381 | ||
410 | return 0; | 382 | return 0; |
411 | } | 383 | } |
412 | 384 | ||
413 | static struct platform_driver au1xpsc_pcm_driver = { | 385 | static struct platform_driver au1xpsc_pcm_driver = { |
414 | .driver = { | 386 | .driver = { |
415 | .name = "au1xpsc-pcm-audio", | 387 | .name = "au1xpsc-pcm", |
416 | .owner = THIS_MODULE, | 388 | .owner = THIS_MODULE, |
417 | }, | 389 | }, |
418 | .probe = au1xpsc_pcm_drvprobe, | 390 | .probe = au1xpsc_pcm_drvprobe, |
@@ -421,8 +393,6 @@ static struct platform_driver au1xpsc_pcm_driver = { | |||
421 | 393 | ||
422 | static int __init au1xpsc_audio_dbdma_load(void) | 394 | static int __init au1xpsc_audio_dbdma_load(void) |
423 | { | 395 | { |
424 | au1xpsc_audio_pcmdma[PCM_TX] = NULL; | ||
425 | au1xpsc_audio_pcmdma[PCM_RX] = NULL; | ||
426 | return platform_driver_register(&au1xpsc_pcm_driver); | 396 | return platform_driver_register(&au1xpsc_pcm_driver); |
427 | } | 397 | } |
428 | 398 | ||
@@ -460,7 +430,7 @@ struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev) | |||
460 | res[1].start = res[1].end = id[1]; | 430 | res[1].start = res[1].end = id[1]; |
461 | res[0].flags = res[1].flags = IORESOURCE_DMA; | 431 | res[0].flags = res[1].flags = IORESOURCE_DMA; |
462 | 432 | ||
463 | pd = platform_device_alloc("au1xpsc-pcm", -1); | 433 | pd = platform_device_alloc("au1xpsc-pcm", pdev->id); |
464 | if (!pd) | 434 | if (!pd) |
465 | goto out; | 435 | goto out; |
466 | 436 | ||