]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - sound/soc/tegra/tegra30_i2s.c
Merge remote-tracking branch 'sound-asoc/for-next'
[karo-tx-linux.git] / sound / soc / tegra / tegra30_i2s.c
index 02247fee1cf7e1450fb4bbcdf2e58cf5ee76c7e8..49ad9366add86b008823f6091315d74d78f13aeb 100644 (file)
@@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
        return 0;
 }
 
-static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
-                       struct snd_soc_dai *dai)
-{
-       struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-       int ret;
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
-                                       &i2s->playback_dma_data.addr,
-                                       &i2s->playback_dma_data.slave_id);
-               i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-               i2s->playback_dma_data.maxburst = 4;
-               tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
-                                              i2s->playback_fifo_cif);
-       } else {
-               ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
-                                       &i2s->capture_dma_data.addr,
-                                       &i2s->capture_dma_data.slave_id);
-               i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-               i2s->capture_dma_data.maxburst = 4;
-               tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
-                                              i2s->capture_i2s_cif);
-       }
-
-       return ret;
-}
-
-static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
-                       struct snd_soc_dai *dai)
-{
-       struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
-               tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
-       } else {
-               tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
-               tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
-       }
-}
-
 static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
                                unsigned int fmt)
 {
@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai)
 }
 
 static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
-       .startup        = tegra30_i2s_startup,
-       .shutdown       = tegra30_i2s_shutdown,
        .set_fmt        = tegra30_i2s_set_fmt,
        .hw_params      = tegra30_i2s_hw_params,
        .trigger        = tegra30_i2s_trigger,
@@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
                        goto err_pm_disable;
        }
 
+       i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       i2s->playback_dma_data.maxburst = 4;
+       ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
+                                           i2s->playback_dma_chan,
+                                           sizeof(i2s->playback_dma_chan),
+                                           &i2s->playback_dma_data.addr);
+       if (ret) {
+               dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
+               goto err_suspend;
+       }
+       ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
+                                            i2s->playback_fifo_cif);
+       if (ret) {
+               dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
+               goto err_free_tx_fifo;
+       }
+
+       i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       i2s->capture_dma_data.maxburst = 4;
+       ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
+                                           i2s->capture_dma_chan,
+                                           sizeof(i2s->capture_dma_chan),
+                                           &i2s->capture_dma_data.addr);
+       if (ret) {
+               dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
+               goto err_unroute_tx_fifo;
+       }
+       ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
+                                            i2s->capture_i2s_cif);
+       if (ret) {
+               dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
+               goto err_free_rx_fifo;
+       }
+
        ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
                                   &i2s->dai, 1);
        if (ret) {
                dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
                ret = -ENOMEM;
-               goto err_suspend;
+               goto err_unroute_rx_fifo;
        }
 
-       ret = tegra_pcm_platform_register(&pdev->dev);
+       ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev,
+                               &i2s->dma_config, i2s->playback_dma_chan,
+                               i2s->capture_dma_chan);
        if (ret) {
                dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
                goto err_unregister_component;
@@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
 
 err_unregister_component:
        snd_soc_unregister_component(&pdev->dev);
+err_unroute_rx_fifo:
+       tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
+err_free_rx_fifo:
+       tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
+err_unroute_tx_fifo:
+       tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
+err_free_tx_fifo:
+       tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
 err_suspend:
        if (!pm_runtime_status_suspended(&pdev->dev))
                tegra30_i2s_runtime_suspend(&pdev->dev);
@@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
        tegra_pcm_platform_unregister(&pdev->dev);
        snd_soc_unregister_component(&pdev->dev);
 
+       tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
+       tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
+
+       tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
+       tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
+
        clk_put(i2s->clk_i2s);
 
        return 0;