aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-11-15 13:48:47 -0500
committerStephen Warren <swarren@nvidia.com>2013-12-11 18:43:50 -0500
commitd59afb6a961519d81557f6b13d04ec1498c074fe (patch)
tree2144f3e3a3ca3cfa6267c75275f2b5a8f905bf20 /sound/soc
parent768db0b93d6f0ed10f351b5eca34ef44b456369c (diff)
ASoC: tegra: allocate AHUB FIFO during probe() not startup()
The Tegra30 I2S driver currently allocates DMA FIFOs from the AHUB only when an audio stream starts playback. This is theoretically nice for resource sharing, but makes no practical difference for any configuration the drivers currently support. However, this deferral prevents conversion to the standard DMA DT bindings, since conversion requires knowledge of the specific DMA channel to be allocated, which in turn depends on which specific FIFO was allocated. For this reason, move the FIFO allocation into probe() to allow later conversion to the standard DMA DT bindings. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/tegra/tegra30_i2s.c91
1 files changed, 47 insertions, 44 deletions
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 231a785b3921..531a1ff2101d 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
73 return 0; 73 return 0;
74} 74}
75 75
76static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
77 struct snd_soc_dai *dai)
78{
79 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
80 int ret;
81
82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
83 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
84 &i2s->playback_dma_data.addr,
85 &i2s->playback_dma_data.slave_id);
86 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
87 i2s->playback_dma_data.maxburst = 4;
88 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
89 i2s->playback_fifo_cif);
90 } else {
91 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
92 &i2s->capture_dma_data.addr,
93 &i2s->capture_dma_data.slave_id);
94 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
95 i2s->capture_dma_data.maxburst = 4;
96 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
97 i2s->capture_i2s_cif);
98 }
99
100 return ret;
101}
102
103static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
104 struct snd_soc_dai *dai)
105{
106 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
107
108 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
109 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
110 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
111 } else {
112 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
113 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
114 }
115}
116
117static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, 76static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
118 unsigned int fmt) 77 unsigned int fmt)
119{ 78{
@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai)
317} 276}
318 277
319static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { 278static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
320 .startup = tegra30_i2s_startup,
321 .shutdown = tegra30_i2s_shutdown,
322 .set_fmt = tegra30_i2s_set_fmt, 279 .set_fmt = tegra30_i2s_set_fmt,
323 .hw_params = tegra30_i2s_hw_params, 280 .hw_params = tegra30_i2s_hw_params,
324 .trigger = tegra30_i2s_trigger, 281 .trigger = tegra30_i2s_trigger,
@@ -499,12 +456,44 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
499 goto err_pm_disable; 456 goto err_pm_disable;
500 } 457 }
501 458
459 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
460 i2s->playback_dma_data.maxburst = 4;
461 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
462 &i2s->playback_dma_data.addr,
463 &i2s->playback_dma_data.slave_id);
464 if (ret) {
465 dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
466 goto err_suspend;
467 }
468 ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
469 i2s->playback_fifo_cif);
470 if (ret) {
471 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
472 goto err_free_tx_fifo;
473 }
474
475 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
476 i2s->capture_dma_data.maxburst = 4;
477 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
478 &i2s->capture_dma_data.addr,
479 &i2s->capture_dma_data.slave_id);
480 if (ret) {
481 dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
482 goto err_unroute_tx_fifo;
483 }
484 ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
485 i2s->capture_i2s_cif);
486 if (ret) {
487 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
488 goto err_free_rx_fifo;
489 }
490
502 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, 491 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
503 &i2s->dai, 1); 492 &i2s->dai, 1);
504 if (ret) { 493 if (ret) {
505 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 494 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
506 ret = -ENOMEM; 495 ret = -ENOMEM;
507 goto err_suspend; 496 goto err_unroute_rx_fifo;
508 } 497 }
509 498
510 ret = tegra_pcm_platform_register(&pdev->dev); 499 ret = tegra_pcm_platform_register(&pdev->dev);
@@ -517,6 +506,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
517 506
518err_unregister_component: 507err_unregister_component:
519 snd_soc_unregister_component(&pdev->dev); 508 snd_soc_unregister_component(&pdev->dev);
509err_unroute_rx_fifo:
510 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
511err_free_rx_fifo:
512 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
513err_unroute_tx_fifo:
514 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
515err_free_tx_fifo:
516 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
520err_suspend: 517err_suspend:
521 if (!pm_runtime_status_suspended(&pdev->dev)) 518 if (!pm_runtime_status_suspended(&pdev->dev))
522 tegra30_i2s_runtime_suspend(&pdev->dev); 519 tegra30_i2s_runtime_suspend(&pdev->dev);
@@ -539,6 +536,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
539 tegra_pcm_platform_unregister(&pdev->dev); 536 tegra_pcm_platform_unregister(&pdev->dev);
540 snd_soc_unregister_component(&pdev->dev); 537 snd_soc_unregister_component(&pdev->dev);
541 538
539 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
540 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
541
542 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
543 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
544
542 clk_put(i2s->clk_i2s); 545 clk_put(i2s->clk_i2s);
543 546
544 return 0; 547 return 0;