aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;