summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorSumit Bhattacharya <sumitb@nvidia.com>2012-04-20 17:26:35 +0530
committerSimone Willett <swillett@nvidia.com>2012-04-26 14:53:34 -0700
commitf61271a07333c0177346716e9a85da2dfea3f73e (patch)
treebd86e5832175aeb5768ae9f0e829bed0af609b07 /sound
parent167ad9e2cb758aedaf778e6ba2c631878ff2dd68 (diff)
ASoC: Tegra: Make dma_req count easily configurable
Instead of always using 2 dma_req count pass max dma_req_count through a macro. Ensure dma_req_count does not cross period_count. Bug 968814 Change-Id: Iddfbd77017992ccb8c90441213e191133dadb347 Signed-off-by: Sumit Bhattacharya <sumitb@nvidia.com> Reviewed-on: http://git-master/r/97915 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com> Reviewed-by: Scott Peterson <speterson@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_pcm.c39
-rw-r--r--sound/soc/tegra/tegra_pcm.h5
2 files changed, 28 insertions, 16 deletions
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 00bd7aa2e59d..65d89c8b1280 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -66,7 +66,8 @@ static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
unsigned long addr;
dma_req = &prtd->dma_req[prtd->dma_req_idx];
- prtd->dma_req_idx = 1 - prtd->dma_req_idx;
+ if (++prtd->dma_req_idx >= prtd->dma_req_count)
+ prtd->dma_req_idx -= prtd->dma_req_count;
addr = buf->addr + prtd->dma_pos;
prtd->dma_pos += dma_req->size;
@@ -137,6 +138,7 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct tegra_pcm_dma_params * dmap;
int ret = 0;
+ int i = 0;
prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
if (prtd == NULL)
@@ -148,10 +150,11 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
spin_lock_init(&prtd->lock);
dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ prtd->dma_req_count = MAX_DMA_REQ_COUNT;
if (dmap) {
- prtd->dma_req[0].dev = prtd;
- prtd->dma_req[1].dev = prtd;
+ for (i = 0; i < prtd->dma_req_count; i++)
+ prtd->dma_req[i].dev = prtd;
prtd->dma_chan = tegra_dma_allocate_channel(
TEGRA_DMA_MODE_CONTINUOUS_SINGLE,
@@ -209,21 +212,25 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
struct tegra_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct tegra_pcm_dma_params * dmap;
+ int i;
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ /* Limit dma_req_count to period count */
+ if (prtd->dma_req_count > params_periods(params))
+ prtd->dma_req_count = params_periods(params);
dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
if (dmap) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- setup_dma_tx_request(&prtd->dma_req[0], dmap);
- setup_dma_tx_request(&prtd->dma_req[1], dmap);
+ for (i = 0; i < prtd->dma_req_count; i++)
+ setup_dma_tx_request(&prtd->dma_req[i], dmap);
} else {
- setup_dma_rx_request(&prtd->dma_req[0], dmap);
- setup_dma_rx_request(&prtd->dma_req[1], dmap);
+ for (i = 0; i < prtd->dma_req_count; i++)
+ setup_dma_rx_request(&prtd->dma_req[i], dmap);
}
}
- prtd->dma_req[0].size = params_period_bytes(params);
- prtd->dma_req[1].size = prtd->dma_req[0].size;
+ for (i = 0; i < prtd->dma_req_count; i++)
+ prtd->dma_req[i].size = params_period_bytes(params);
return 0;
}
@@ -240,6 +247,7 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct snd_pcm_runtime *runtime = substream->runtime;
struct tegra_runtime_data *prtd = runtime->private_data;
unsigned long flags;
+ int i;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -253,8 +261,8 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
spin_lock_irqsave(&prtd->lock, flags);
prtd->running = 1;
spin_unlock_irqrestore(&prtd->lock, flags);
- tegra_pcm_queue_dma(prtd);
- tegra_pcm_queue_dma(prtd);
+ for (i = 0; i < prtd->dma_req_count; i++)
+ tegra_pcm_queue_dma(prtd);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -263,10 +271,11 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
prtd->running = 0;
spin_unlock_irqrestore(&prtd->lock, flags);
tegra_dma_cancel(prtd->dma_chan);
- if (prtd->dma_req[0].status == -TEGRA_DMA_REQ_ERROR_ABORTED)
- prtd->dma_req[0].complete(&prtd->dma_req[0]);
- if (prtd->dma_req[1].status == -TEGRA_DMA_REQ_ERROR_ABORTED)
- prtd->dma_req[1].complete(&prtd->dma_req[1]);
+ for (i = 0; i < prtd->dma_req_count; i++) {
+ if (prtd->dma_req[i].status ==
+ -TEGRA_DMA_REQ_ERROR_ABORTED)
+ prtd->dma_req[i].complete(&prtd->dma_req[i]);
+ }
break;
default:
return -EINVAL;
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index dbb90339fe0d..5737ea7ca0bc 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -33,6 +33,8 @@
#include <mach/dma.h>
+#define MAX_DMA_REQ_COUNT 2
+
struct tegra_pcm_dma_params {
unsigned long addr;
unsigned long wrap;
@@ -48,8 +50,9 @@ struct tegra_runtime_data {
int dma_pos_end;
int period_index;
int dma_req_idx;
- struct tegra_dma_req dma_req[2];
+ struct tegra_dma_req dma_req[MAX_DMA_REQ_COUNT];
struct tegra_dma_channel *dma_chan;
+ int dma_req_count;
};
#endif