diff options
Diffstat (limited to 'sound/soc/au1x/dbdma2.c')
| -rw-r--r-- | sound/soc/au1x/dbdma2.c | 115 |
1 files changed, 96 insertions, 19 deletions
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 594c6c5b7838..19e4d37eba1c 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Au12x0/Au1550 PSC ALSA ASoC audio support. | 2 | * Au12x0/Au1550 PSC ALSA ASoC audio support. |
| 3 | * | 3 | * |
| 4 | * (c) 2007-2008 MSC Vertriebsges.m.b.H., | 4 | * (c) 2007-2008 MSC Vertriebsges.m.b.H., |
| 5 | * Manuel Lauss <mano@roarinelk.homelinux.net> | 5 | * Manuel Lauss <manuel.lauss@gmail.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -333,6 +333,30 @@ static int au1xpsc_pcm_new(struct snd_card *card, | |||
| 333 | 333 | ||
| 334 | static int au1xpsc_pcm_probe(struct platform_device *pdev) | 334 | static int au1xpsc_pcm_probe(struct platform_device *pdev) |
| 335 | { | 335 | { |
| 336 | if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX]) | ||
| 337 | return -ENODEV; | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | static int au1xpsc_pcm_remove(struct platform_device *pdev) | ||
| 343 | { | ||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | /* au1xpsc audio platform */ | ||
| 348 | struct snd_soc_platform au1xpsc_soc_platform = { | ||
| 349 | .name = "au1xpsc-pcm-dbdma", | ||
| 350 | .probe = au1xpsc_pcm_probe, | ||
| 351 | .remove = au1xpsc_pcm_remove, | ||
| 352 | .pcm_ops = &au1xpsc_pcm_ops, | ||
| 353 | .pcm_new = au1xpsc_pcm_new, | ||
| 354 | .pcm_free = au1xpsc_pcm_free_dma_buffers, | ||
| 355 | }; | ||
| 356 | EXPORT_SYMBOL_GPL(au1xpsc_soc_platform); | ||
| 357 | |||
| 358 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) | ||
| 359 | { | ||
| 336 | struct resource *r; | 360 | struct resource *r; |
| 337 | int ret; | 361 | int ret; |
| 338 | 362 | ||
| @@ -365,7 +389,9 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev) | |||
| 365 | } | 389 | } |
| 366 | (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; | 390 | (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; |
| 367 | 391 | ||
| 368 | return 0; | 392 | ret = snd_soc_register_platform(&au1xpsc_soc_platform); |
| 393 | if (!ret) | ||
| 394 | return ret; | ||
| 369 | 395 | ||
| 370 | out2: | 396 | out2: |
| 371 | kfree(au1xpsc_audio_pcmdma[PCM_RX]); | 397 | kfree(au1xpsc_audio_pcmdma[PCM_RX]); |
| @@ -376,10 +402,12 @@ out1: | |||
| 376 | return ret; | 402 | return ret; |
| 377 | } | 403 | } |
| 378 | 404 | ||
| 379 | static int au1xpsc_pcm_remove(struct platform_device *pdev) | 405 | static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) |
| 380 | { | 406 | { |
| 381 | int i; | 407 | int i; |
| 382 | 408 | ||
| 409 | snd_soc_unregister_platform(&au1xpsc_soc_platform); | ||
| 410 | |||
| 383 | for (i = 0; i < 2; i++) { | 411 | for (i = 0; i < 2; i++) { |
| 384 | if (au1xpsc_audio_pcmdma[i]) { | 412 | if (au1xpsc_audio_pcmdma[i]) { |
| 385 | au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); | 413 | au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); |
| @@ -391,32 +419,81 @@ static int au1xpsc_pcm_remove(struct platform_device *pdev) | |||
| 391 | return 0; | 419 | return 0; |
| 392 | } | 420 | } |
| 393 | 421 | ||
| 394 | /* au1xpsc audio platform */ | 422 | static struct platform_driver au1xpsc_pcm_driver = { |
| 395 | struct snd_soc_platform au1xpsc_soc_platform = { | 423 | .driver = { |
| 396 | .name = "au1xpsc-pcm-dbdma", | 424 | .name = "au1xpsc-pcm", |
| 397 | .probe = au1xpsc_pcm_probe, | 425 | .owner = THIS_MODULE, |
| 398 | .remove = au1xpsc_pcm_remove, | 426 | }, |
| 399 | .pcm_ops = &au1xpsc_pcm_ops, | 427 | .probe = au1xpsc_pcm_drvprobe, |
| 400 | .pcm_new = au1xpsc_pcm_new, | 428 | .remove = __devexit_p(au1xpsc_pcm_drvremove), |
| 401 | .pcm_free = au1xpsc_pcm_free_dma_buffers, | ||
| 402 | }; | 429 | }; |
| 403 | EXPORT_SYMBOL_GPL(au1xpsc_soc_platform); | ||
| 404 | 430 | ||
| 405 | static int __init au1xpsc_audio_dbdma_init(void) | 431 | static int __init au1xpsc_audio_dbdma_load(void) |
| 406 | { | 432 | { |
| 407 | au1xpsc_audio_pcmdma[PCM_TX] = NULL; | 433 | au1xpsc_audio_pcmdma[PCM_TX] = NULL; |
| 408 | au1xpsc_audio_pcmdma[PCM_RX] = NULL; | 434 | au1xpsc_audio_pcmdma[PCM_RX] = NULL; |
| 409 | return snd_soc_register_platform(&au1xpsc_soc_platform); | 435 | return platform_driver_register(&au1xpsc_pcm_driver); |
| 410 | } | 436 | } |
| 411 | 437 | ||
| 412 | static void __exit au1xpsc_audio_dbdma_exit(void) | 438 | static void __exit au1xpsc_audio_dbdma_unload(void) |
| 413 | { | 439 | { |
| 414 | snd_soc_unregister_platform(&au1xpsc_soc_platform); | 440 | platform_driver_unregister(&au1xpsc_pcm_driver); |
| 415 | } | 441 | } |
| 416 | 442 | ||
| 417 | module_init(au1xpsc_audio_dbdma_init); | 443 | module_init(au1xpsc_audio_dbdma_load); |
| 418 | module_exit(au1xpsc_audio_dbdma_exit); | 444 | module_exit(au1xpsc_audio_dbdma_unload); |
| 445 | |||
| 446 | |||
| 447 | struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev) | ||
| 448 | { | ||
| 449 | struct resource *res, *r; | ||
| 450 | struct platform_device *pd; | ||
| 451 | int id[2]; | ||
| 452 | int ret; | ||
| 453 | |||
| 454 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 455 | if (!r) | ||
| 456 | return NULL; | ||
| 457 | id[0] = r->start; | ||
| 458 | |||
| 459 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 460 | if (!r) | ||
| 461 | return NULL; | ||
| 462 | id[1] = r->start; | ||
| 463 | |||
| 464 | res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); | ||
| 465 | if (!res) | ||
| 466 | return NULL; | ||
| 467 | |||
| 468 | res[0].start = res[0].end = id[0]; | ||
| 469 | res[1].start = res[1].end = id[1]; | ||
| 470 | res[0].flags = res[1].flags = IORESOURCE_DMA; | ||
| 471 | |||
| 472 | pd = platform_device_alloc("au1xpsc-pcm", -1); | ||
| 473 | if (!pd) | ||
| 474 | goto out; | ||
| 475 | |||
| 476 | pd->resource = res; | ||
| 477 | pd->num_resources = 2; | ||
| 478 | |||
| 479 | ret = platform_device_add(pd); | ||
| 480 | if (!ret) | ||
| 481 | return pd; | ||
| 482 | |||
| 483 | platform_device_put(pd); | ||
| 484 | out: | ||
| 485 | kfree(res); | ||
| 486 | return NULL; | ||
| 487 | } | ||
| 488 | EXPORT_SYMBOL_GPL(au1xpsc_pcm_add); | ||
| 489 | |||
| 490 | void au1xpsc_pcm_destroy(struct platform_device *dmapd) | ||
| 491 | { | ||
| 492 | if (dmapd) | ||
| 493 | platform_device_unregister(dmapd); | ||
| 494 | } | ||
| 495 | EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy); | ||
| 419 | 496 | ||
| 420 | MODULE_LICENSE("GPL"); | 497 | MODULE_LICENSE("GPL"); |
| 421 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); | 498 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); |
| 422 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | 499 | MODULE_AUTHOR("Manuel Lauss"); |
