[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1341219273-7439-3-git-send-email-ldewangan@nvidia.com>
Date: Mon, 2 Jul 2012 14:24:33 +0530
From: Laxman Dewangan <ldewangan@...dia.com>
To: <tiwai@...e.de>, <lrg@...com>,
<broonie@...nsource.wolfsonmicro.com>, <lars@...afoo.de>,
<swarren@...dia.com>, <perex@...ex.cz>, <clemens@...isch.de>
CC: <alsa-devel@...a-project.org>, <linux-kernel@...r.kernel.org>,
Laxman Dewangan <ldewangan@...dia.com>
Subject: [PATCH 2/2] ASoC: tegra: use sound pcm library for substream dma buffer
The sound pcm library support the writecombine DMA buffer
allocation/deallocation/mapping and hence using the APIs
form sound pcm library inplace of implementing the same
locally.
Signed-off-by: Laxman Dewangan <ldewangan@...dia.com>
---
Changes from V1:
Changes done to use the existing APIs for sound pcm memory management
which is now supporting writecombine.
sound/soc/tegra/tegra_pcm.c | 112 ++++++++++--------------------------------
1 files changed, 27 insertions(+), 85 deletions(-)
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 127348d..ec1fa25 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -202,8 +202,14 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct tegra_runtime_data *prtd = runtime->private_data;
+ int ret;
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(params));
+ if (ret < 0) {
+ pr_err("page allocation failed, err %d\n", ret);
+ return ret;
+ }
prtd->dma_req[0].size = params_period_bytes(params);
prtd->dma_req[1].size = prtd->dma_req[0].size;
@@ -213,9 +219,7 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
{
- snd_pcm_set_runtime_buffer(substream, NULL);
-
- return 0;
+ return snd_pcm_lib_free_pages(substream);
}
static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -263,18 +267,6 @@ static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
return prtd->period_index * runtime->period_size;
}
-
-static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
static struct snd_pcm_ops tegra_pcm_ops = {
.open = tegra_pcm_open,
.close = tegra_pcm_close,
@@ -283,87 +275,37 @@ static struct snd_pcm_ops tegra_pcm_ops = {
.hw_free = tegra_pcm_hw_free,
.trigger = tegra_pcm_trigger,
.pointer = tegra_pcm_pointer,
- .mmap = tegra_pcm_mmap,
+ .mmap = snd_pcm_lib_default_mmap,
};
-static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = tegra_pcm_hardware.buffer_bytes_max;
-
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->bytes = size;
-
- return 0;
-}
-
-static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
-
- substream = pcm->streams[stream].substream;
- if (!substream)
- return;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- return;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
-}
-
-static u64 tegra_dma_mask = DMA_BIT_MASK(32);
-
+#define TEGRA_PCM_PREALLOC_BUFFER (32 * 1024)
+#define TEGRA_PCM_PREALLOC_BUFFER_MAX (32 * 1024)
static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
- struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &tegra_dma_mask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = tegra_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto err;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = tegra_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto err_free_play;
+ struct snd_card *card = rtd->card->snd_card;
+ int retval = 0;
+
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
+ pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+ retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
+ SNDRV_DMA_TYPE_DEV_WC,
+ card->dev,
+ TEGRA_PCM_PREALLOC_BUFFER,
+ TEGRA_PCM_PREALLOC_BUFFER_MAX);
+ if (retval < 0)
+ dev_err(card->dev,
+ "dma buffer pre-alloc failied %d\n", retval);
}
-
- return 0;
-
-err_free_play:
- tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
-err:
- return ret;
+ return retval;
}
static void tegra_pcm_free(struct snd_pcm *pcm)
{
- tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE);
- tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
+ snd_pcm_lib_preallocate_free_for_all(pcm);
}
+
static struct snd_soc_platform_driver tegra_pcm_platform = {
.ops = &tegra_pcm_ops,
.pcm_new = tegra_pcm_new,
--
1.7.1.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists