diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-07-25 07:45:02 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-07-27 14:16:23 -0400 |
commit | 5b0912be7a8ff1dbfe56358c5f933d65445bb8af (patch) | |
tree | 6b0681c2a5e783be00d4f404ad902596b3235b9f /sound/soc/au1x | |
parent | 7137c6bcb7ff5d0e6f63f8a4175d5b77dc79abc0 (diff) |
ASoC: au1x: remove automatic DMA device registration from PSC drivers
The PSC audio drivers (psc-ac97/psc-i2s) register the DMA platform_device
on their own. This is frowned upon, from now on board code must
register a simple pcm dma platform device for each PSC with sound duties.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/au1x')
-rw-r--r-- | sound/soc/au1x/dbdma2.c | 83 | ||||
-rw-r--r-- | sound/soc/au1x/psc-ac97.c | 34 | ||||
-rw-r--r-- | sound/soc/au1x/psc-i2s.c | 32 | ||||
-rw-r--r-- | sound/soc/au1x/psc.h | 5 |
4 files changed, 58 insertions, 96 deletions
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 20bb53a837b1..fd5378f7dece 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c | |||
@@ -293,6 +293,16 @@ au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) | |||
293 | 293 | ||
294 | static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) | 294 | static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) |
295 | { | 295 | { |
296 | struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream); | ||
297 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
298 | int stype = SUBSTREAM_TYPE(substream), *dmaids; | ||
299 | |||
300 | dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
301 | if (!dmaids) | ||
302 | return -ENODEV; /* whoa, has ordering changed? */ | ||
303 | |||
304 | pcd->ddma_id = dmaids[stype]; | ||
305 | |||
296 | snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); | 306 | snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); |
297 | return 0; | 307 | return 0; |
298 | } | 308 | } |
@@ -340,36 +350,18 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = { | |||
340 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) | 350 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) |
341 | { | 351 | { |
342 | struct au1xpsc_audio_dmadata *dmadata; | 352 | struct au1xpsc_audio_dmadata *dmadata; |
343 | struct resource *r; | ||
344 | int ret; | 353 | int ret; |
345 | 354 | ||
346 | dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); | 355 | dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); |
347 | if (!dmadata) | 356 | if (!dmadata) |
348 | return -ENOMEM; | 357 | return -ENOMEM; |
349 | 358 | ||
350 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
351 | if (!r) { | ||
352 | ret = -ENODEV; | ||
353 | goto out1; | ||
354 | } | ||
355 | dmadata[PCM_TX].ddma_id = r->start; | ||
356 | |||
357 | /* RX DMA */ | ||
358 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
359 | if (!r) { | ||
360 | ret = -ENODEV; | ||
361 | goto out1; | ||
362 | } | ||
363 | dmadata[PCM_RX].ddma_id = r->start; | ||
364 | |||
365 | platform_set_drvdata(pdev, dmadata); | 359 | platform_set_drvdata(pdev, dmadata); |
366 | 360 | ||
367 | ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); | 361 | ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); |
368 | if (!ret) | 362 | if (ret) |
369 | return ret; | 363 | kfree(dmadata); |
370 | 364 | ||
371 | out1: | ||
372 | kfree(dmadata); | ||
373 | return ret; | 365 | return ret; |
374 | } | 366 | } |
375 | 367 | ||
@@ -405,57 +397,6 @@ static void __exit au1xpsc_audio_dbdma_unload(void) | |||
405 | module_init(au1xpsc_audio_dbdma_load); | 397 | module_init(au1xpsc_audio_dbdma_load); |
406 | module_exit(au1xpsc_audio_dbdma_unload); | 398 | module_exit(au1xpsc_audio_dbdma_unload); |
407 | 399 | ||
408 | |||
409 | struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev) | ||
410 | { | ||
411 | struct resource *res, *r; | ||
412 | struct platform_device *pd; | ||
413 | int id[2]; | ||
414 | int ret; | ||
415 | |||
416 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
417 | if (!r) | ||
418 | return NULL; | ||
419 | id[0] = r->start; | ||
420 | |||
421 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
422 | if (!r) | ||
423 | return NULL; | ||
424 | id[1] = r->start; | ||
425 | |||
426 | res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); | ||
427 | if (!res) | ||
428 | return NULL; | ||
429 | |||
430 | res[0].start = res[0].end = id[0]; | ||
431 | res[1].start = res[1].end = id[1]; | ||
432 | res[0].flags = res[1].flags = IORESOURCE_DMA; | ||
433 | |||
434 | pd = platform_device_alloc("au1xpsc-pcm", pdev->id); | ||
435 | if (!pd) | ||
436 | goto out; | ||
437 | |||
438 | pd->resource = res; | ||
439 | pd->num_resources = 2; | ||
440 | |||
441 | ret = platform_device_add(pd); | ||
442 | if (!ret) | ||
443 | return pd; | ||
444 | |||
445 | platform_device_put(pd); | ||
446 | out: | ||
447 | kfree(res); | ||
448 | return NULL; | ||
449 | } | ||
450 | EXPORT_SYMBOL_GPL(au1xpsc_pcm_add); | ||
451 | |||
452 | void au1xpsc_pcm_destroy(struct platform_device *dmapd) | ||
453 | { | ||
454 | if (dmapd) | ||
455 | platform_device_unregister(dmapd); | ||
456 | } | ||
457 | EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy); | ||
458 | |||
459 | MODULE_LICENSE("GPL"); | 400 | MODULE_LICENSE("GPL"); |
460 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); | 401 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); |
461 | MODULE_AUTHOR("Manuel Lauss"); | 402 | MODULE_AUTHOR("Manuel Lauss"); |
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index d0db66f24a00..44296abfc38f 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c | |||
@@ -324,12 +324,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, | |||
324 | return ret; | 324 | return ret; |
325 | } | 325 | } |
326 | 326 | ||
327 | static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream, | ||
328 | struct snd_soc_dai *dai) | ||
329 | { | ||
330 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | ||
331 | snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
327 | static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) | 335 | static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) |
328 | { | 336 | { |
329 | return au1xpsc_ac97_workdata ? 0 : -ENODEV; | 337 | return au1xpsc_ac97_workdata ? 0 : -ENODEV; |
330 | } | 338 | } |
331 | 339 | ||
332 | static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { | 340 | static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { |
341 | .startup = au1xpsc_ac97_startup, | ||
333 | .trigger = au1xpsc_ac97_trigger, | 342 | .trigger = au1xpsc_ac97_trigger, |
334 | .hw_params = au1xpsc_ac97_hw_params, | 343 | .hw_params = au1xpsc_ac97_hw_params, |
335 | }; | 344 | }; |
@@ -379,6 +388,16 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) | |||
379 | if (!wd->mmio) | 388 | if (!wd->mmio) |
380 | goto out1; | 389 | goto out1; |
381 | 390 | ||
391 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
392 | if (!r) | ||
393 | goto out2; | ||
394 | wd->dmaids[PCM_TX] = r->start; | ||
395 | |||
396 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
397 | if (!r) | ||
398 | goto out2; | ||
399 | wd->dmaids[PCM_RX] = r->start; | ||
400 | |||
382 | /* configuration: max dma trigger threshold, enable ac97 */ | 401 | /* configuration: max dma trigger threshold, enable ac97 */ |
383 | wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | | 402 | wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | |
384 | PSC_AC97CFG_DE_ENABLE; | 403 | PSC_AC97CFG_DE_ENABLE; |
@@ -401,15 +420,13 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) | |||
401 | 420 | ||
402 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); | 421 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); |
403 | if (ret) | 422 | if (ret) |
404 | goto out1; | 423 | goto out2; |
405 | 424 | ||
406 | wd->dmapd = au1xpsc_pcm_add(pdev); | 425 | au1xpsc_ac97_workdata = wd; |
407 | if (wd->dmapd) { | 426 | return 0; |
408 | au1xpsc_ac97_workdata = wd; | ||
409 | return 0; | ||
410 | } | ||
411 | 427 | ||
412 | snd_soc_unregister_dai(&pdev->dev); | 428 | out2: |
429 | iounmap(wd->mmio); | ||
413 | out1: | 430 | out1: |
414 | release_mem_region(r->start, resource_size(r)); | 431 | release_mem_region(r->start, resource_size(r)); |
415 | out0: | 432 | out0: |
@@ -422,9 +439,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) | |||
422 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); | 439 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); |
423 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 440 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
424 | 441 | ||
425 | if (wd->dmapd) | ||
426 | au1xpsc_pcm_destroy(wd->dmapd); | ||
427 | |||
428 | snd_soc_unregister_dai(&pdev->dev); | 442 | snd_soc_unregister_dai(&pdev->dev); |
429 | 443 | ||
430 | /* disable PSC completely */ | 444 | /* disable PSC completely */ |
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index fca091276320..1b7ab5d422e0 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c | |||
@@ -257,7 +257,16 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
257 | return ret; | 257 | return ret; |
258 | } | 258 | } |
259 | 259 | ||
260 | static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream, | ||
261 | struct snd_soc_dai *dai) | ||
262 | { | ||
263 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | ||
264 | snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
260 | static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { | 268 | static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { |
269 | .startup = au1xpsc_i2s_startup, | ||
261 | .trigger = au1xpsc_i2s_trigger, | 270 | .trigger = au1xpsc_i2s_trigger, |
262 | .hw_params = au1xpsc_i2s_hw_params, | 271 | .hw_params = au1xpsc_i2s_hw_params, |
263 | .set_fmt = au1xpsc_i2s_set_fmt, | 272 | .set_fmt = au1xpsc_i2s_set_fmt, |
@@ -304,6 +313,16 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) | |||
304 | if (!wd->mmio) | 313 | if (!wd->mmio) |
305 | goto out1; | 314 | goto out1; |
306 | 315 | ||
316 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
317 | if (!r) | ||
318 | goto out2; | ||
319 | wd->dmaids[PCM_TX] = r->start; | ||
320 | |||
321 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
322 | if (!r) | ||
323 | goto out2; | ||
324 | wd->dmaids[PCM_RX] = r->start; | ||
325 | |||
307 | /* preserve PSC clock source set up by platform (dev.platform_data | 326 | /* preserve PSC clock source set up by platform (dev.platform_data |
308 | * is already occupied by soc layer) | 327 | * is already occupied by soc layer) |
309 | */ | 328 | */ |
@@ -330,15 +349,11 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) | |||
330 | platform_set_drvdata(pdev, wd); | 349 | platform_set_drvdata(pdev, wd); |
331 | 350 | ||
332 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); | 351 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); |
333 | if (ret) | 352 | if (!ret) |
334 | goto out1; | ||
335 | |||
336 | /* finally add the DMA device for this PSC */ | ||
337 | wd->dmapd = au1xpsc_pcm_add(pdev); | ||
338 | if (wd->dmapd) | ||
339 | return 0; | 353 | return 0; |
340 | 354 | ||
341 | snd_soc_unregister_dai(&pdev->dev); | 355 | out2: |
356 | iounmap(wd->mmio); | ||
342 | out1: | 357 | out1: |
343 | release_mem_region(r->start, resource_size(r)); | 358 | release_mem_region(r->start, resource_size(r)); |
344 | out0: | 359 | out0: |
@@ -351,9 +366,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) | |||
351 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); | 366 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); |
352 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 367 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
353 | 368 | ||
354 | if (wd->dmapd) | ||
355 | au1xpsc_pcm_destroy(wd->dmapd); | ||
356 | |||
357 | snd_soc_unregister_dai(&pdev->dev); | 369 | snd_soc_unregister_dai(&pdev->dev); |
358 | 370 | ||
359 | au_writel(0, I2S_CFG(wd)); | 371 | au_writel(0, I2S_CFG(wd)); |
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h index c59b9e544e72..1b21c4ffae12 100644 --- a/sound/soc/au1x/psc.h +++ b/sound/soc/au1x/psc.h | |||
@@ -19,10 +19,6 @@ | |||
19 | #define SUBSTREAM_TYPE(substream) \ | 19 | #define SUBSTREAM_TYPE(substream) \ |
20 | ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX) | 20 | ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX) |
21 | 21 | ||
22 | /* PSC/DBDMA helpers */ | ||
23 | extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev); | ||
24 | extern void au1xpsc_pcm_destroy(struct platform_device *dmapd); | ||
25 | |||
26 | struct au1xpsc_audio_data { | 22 | struct au1xpsc_audio_data { |
27 | void __iomem *mmio; | 23 | void __iomem *mmio; |
28 | 24 | ||
@@ -34,7 +30,6 @@ struct au1xpsc_audio_data { | |||
34 | unsigned long pm[2]; | 30 | unsigned long pm[2]; |
35 | struct mutex lock; | 31 | struct mutex lock; |
36 | int dmaids[2]; | 32 | int dmaids[2]; |
37 | struct platform_device *dmapd; | ||
38 | }; | 33 | }; |
39 | 34 | ||
40 | /* easy access macros */ | 35 | /* easy access macros */ |