diff options
author | Vinod G <vinodg@nvidia.com> | 2011-03-29 18:19:32 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-04-26 15:54:46 -0700 |
commit | 437622a591e552169ba7b7443432d081c83a8f73 (patch) | |
tree | 3fa95bb44db6e6bb6ffeeaec417b20b032357cfe /sound | |
parent | be27dfe98c8b7441ff1c521d66e336efbcedde60 (diff) |
arm: tegra: Add Dynamic apbif channel allocation
Big 804696
Added the dynamic apbif channel allocation to be used among
various controller. Support added to more apbif function calls
Original-Change-Id: I5420751037eebb07e4c9a3be339ce5c72174d1be
Reviewed-on: http://git-master/r/24774
Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
Tested-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
Reviewed-by: Scott Peterson <speterson@nvidia.com>
Change-Id: If38be7a842ed7684978a8853106dcadf04e6520d
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_i2s.c | 29 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_pcm.c | 4 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc.h | 1 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_spdif.c | 4 |
4 files changed, 30 insertions, 8 deletions
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 3474857cf5cb..33a2c4a1ff1e 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c @@ -43,6 +43,19 @@ struct tegra_i2s_info { struct das_regs_cache das_regs; }; +void free_dma_request(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + + int fifo_mode = I2S_FIFO_RX; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + fifo_mode = I2S_FIFO_TX; + + i2s_free_dma_requestor(cpu_dai->id, fifo_mode); +} + void setup_i2s_dma_request(struct snd_pcm_substream *substream, struct tegra_dma_req *req, void (*dma_callback)(struct tegra_dma_req *req), @@ -52,10 +65,17 @@ void setup_i2s_dma_request(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct tegra_i2s_info *info = cpu_dai->private_data; + int fifo_mode = I2S_FIFO_RX; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + fifo_mode = I2S_FIFO_TX; + + req->req_sel = i2s_get_dma_requestor(cpu_dai->id, fifo_mode); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { req->to_memory = false; req->dest_addr = - i2s_get_fifo_phy_base(cpu_dai->id, I2S_FIFO_TX); + i2s_get_fifo_phy_base(cpu_dai->id, fifo_mode); req->dest_wrap = 4; req->source_wrap = 0; if (info->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP) @@ -66,7 +86,7 @@ void setup_i2s_dma_request(struct snd_pcm_substream *substream, } else { req->to_memory = true; req->source_addr = - i2s_get_fifo_phy_base(cpu_dai->id, I2S_FIFO_RX); + i2s_get_fifo_phy_base(cpu_dai->id, fifo_mode); req->dest_wrap = 0; req->source_wrap = 4; if (info->bit_format == TEGRA_AUDIO_BIT_FORMAT_DSP) @@ -78,7 +98,6 @@ void setup_i2s_dma_request(struct snd_pcm_substream *substream, req->complete = dma_callback; req->dev = dma_data; - req->req_sel = info->dma_req_sel; return; } @@ -121,7 +140,7 @@ static inline void stop_i2s_playback(struct snd_soc_dai *cpu_dai) i2s_set_fifo_irq_on_err(cpu_dai->id, I2S_FIFO_TX, 0); i2s_set_fifo_irq_on_qe(cpu_dai->id, I2S_FIFO_TX, 0); i2s_fifo_enable(cpu_dai->id, I2S_FIFO_TX, 0); - while (i2s_get_status(cpu_dai->id) & I2S_I2S_FIFO_TX_BUSY); + while (i2s_get_status(cpu_dai->id, I2S_FIFO_TX) & I2S_I2S_FIFO_TX_BUSY); } /* recording */ @@ -139,7 +158,7 @@ static inline void stop_i2s_capture(struct snd_soc_dai *cpu_dai) i2s_set_fifo_irq_on_err(cpu_dai->id, I2S_FIFO_RX, 0); i2s_set_fifo_irq_on_qe(cpu_dai->id, I2S_FIFO_RX, 0); i2s_fifo_enable(cpu_dai->id, I2S_FIFO_RX, 0); - while (i2s_get_status(cpu_dai->id) & I2S_I2S_FIFO_RX_BUSY); + while (i2s_get_status(cpu_dai->id, I2S_FIFO_RX) & I2S_I2S_FIFO_RX_BUSY); } diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 3c1abacf2165..25a8c553e5ed 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -304,8 +304,10 @@ static int tegra_pcm_close(struct snd_pcm_substream *substream) if (prtd->dma_chan) { prtd->dma_state = STATE_EXIT; - for (i = 0; i < DMA_REQ_QCOUNT; i++) + for (i = 0; i < DMA_REQ_QCOUNT; i++) { tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[i]); + free_dma_request(substream); + } tegra_dma_flush(prtd->dma_chan); tegra_dma_free_channel(prtd->dma_chan); prtd->dma_chan = NULL; diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h index 05c9e18ccb43..cf054286b5be 100644 --- a/sound/soc/tegra/tegra_soc.h +++ b/sound/soc/tegra/tegra_soc.h @@ -145,6 +145,7 @@ void setup_dma_request(struct snd_pcm_substream *substream, struct tegra_dma_req *req, void (*dma_callback)(struct tegra_dma_req *req), void *dma_data); +void free_dma_request(struct snd_pcm_substream *substream); void set_fifo_attention(struct snd_pcm_substream *substream, int buffersize); diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c index 53c0b19c15d2..99e275db8d3e 100644 --- a/sound/soc/tegra/tegra_spdif.c +++ b/sound/soc/tegra/tegra_spdif.c @@ -83,7 +83,7 @@ static inline void stop_spdif_playback(struct snd_soc_dai *dai) struct tegra_spdif_info *info = dai->private_data; spdif_fifo_enable(info->spdif_base, AUDIO_TX_MODE, false); - while (spdif_get_status(info->spdif_base) & SPDIF_STATUS_0_TX_BSY); + while (spdif_get_status(info->spdif_base, AUDIO_TX_MODE) & SPDIF_STATUS_0_TX_BSY); } /* capture */ @@ -101,7 +101,7 @@ static inline void stop_spdif_capture(struct snd_soc_dai *dai) struct tegra_spdif_info *info = dai->private_data; spdif_fifo_enable(info->spdif_base, AUDIO_RX_MODE, false); - while (spdif_get_status(info->spdif_base) & SPDIF_STATUS_0_RX_BSY); + while (spdif_get_status(info->spdif_base, AUDIO_RX_MODE) & SPDIF_STATUS_0_RX_BSY); } static int tegra_spdif_hw_params(struct snd_pcm_substream *substream, |