diff options
author | Sumit Bhattacharya <sumitb@nvidia.com> | 2012-04-20 17:26:35 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-04-26 14:53:34 -0700 |
commit | f61271a07333c0177346716e9a85da2dfea3f73e (patch) | |
tree | bd86e5832175aeb5768ae9f0e829bed0af609b07 /sound | |
parent | 167ad9e2cb758aedaf778e6ba2c631878ff2dd68 (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.c | 39 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_pcm.h | 5 |
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 |