summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorVinod G <vinodg@nvidia.com>2011-03-29 18:19:32 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-04-26 15:54:46 -0700
commit437622a591e552169ba7b7443432d081c83a8f73 (patch)
tree3fa95bb44db6e6bb6ffeeaec417b20b032357cfe /sound
parentbe27dfe98c8b7441ff1c521d66e336efbcedde60 (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.c29
-rw-r--r--sound/soc/tegra/tegra_pcm.c4
-rw-r--r--sound/soc/tegra/tegra_soc.h1
-rw-r--r--sound/soc/tegra/tegra_spdif.c4
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,