mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-01-01 05:28:58 +02:00
9a1322f91d
take from qi-kernel.git thanks to Werner
89 lines
2.8 KiB
Diff
89 lines
2.8 KiB
Diff
From 5e689acca07bccdced123f82e8dde5459eca0d97 Mon Sep 17 00:00:00 2001
|
|
From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
|
|
Date: Wed, 14 Sep 2011 14:30:01 +0800
|
|
Subject: [PATCH 26/32] sound: update DMA code
|
|
|
|
---
|
|
sound/soc/jz4740/jz4740-pcm.c | 21 ++++++++++++++++++---
|
|
1 files changed, 18 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
|
|
index fb1483f..71c455d 100644
|
|
--- a/sound/soc/jz4740/jz4740-pcm.c
|
|
+++ b/sound/soc/jz4740/jz4740-pcm.c
|
|
@@ -31,6 +31,7 @@
|
|
|
|
struct jz4740_runtime_data {
|
|
unsigned long dma_period;
|
|
+ unsigned long dma_period_left;
|
|
dma_addr_t dma_start;
|
|
dma_addr_t dma_pos;
|
|
dma_addr_t dma_end;
|
|
@@ -67,10 +68,13 @@ static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd,
|
|
if (prtd->dma_pos == prtd->dma_end)
|
|
prtd->dma_pos = prtd->dma_start;
|
|
|
|
- if (prtd->dma_pos + prtd->dma_period > prtd->dma_end)
|
|
+ if (prtd->dma_period_left == 0)
|
|
+ prtd->dma_period_left = prtd->dma_period;
|
|
+
|
|
+ if (prtd->dma_pos + prtd->dma_period_left > prtd->dma_end)
|
|
count = prtd->dma_end - prtd->dma_pos;
|
|
else
|
|
- count = prtd->dma_period;
|
|
+ count = prtd->dma_period_left;
|
|
|
|
jz4740_dma_disable(prtd->dma);
|
|
|
|
@@ -85,6 +89,7 @@ static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd,
|
|
jz4740_dma_set_transfer_count(prtd->dma, count);
|
|
|
|
prtd->dma_pos += count;
|
|
+ prtd->dma_period_left -= count;
|
|
|
|
jz4740_dma_enable(prtd->dma);
|
|
}
|
|
@@ -96,7 +101,8 @@ static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err,
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
struct jz4740_runtime_data *prtd = runtime->private_data;
|
|
|
|
- snd_pcm_period_elapsed(substream);
|
|
+ if (prtd->dma_period_left == 0)
|
|
+ snd_pcm_period_elapsed(substream);
|
|
|
|
jz4740_pcm_start_transfer(prtd, substream);
|
|
}
|
|
@@ -133,6 +139,7 @@ static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
runtime->dma_bytes = params_buffer_bytes(params);
|
|
|
|
prtd->dma_period = params_period_bytes(params);
|
|
+ prtd->dma_period_left = 0;
|
|
prtd->dma_start = runtime->dma_addr;
|
|
prtd->dma_pos = prtd->dma_start;
|
|
prtd->dma_end = prtd->dma_start + runtime->dma_bytes;
|
|
@@ -160,6 +167,7 @@ static int jz4740_pcm_prepare(struct snd_pcm_substream *substream)
|
|
if (!prtd->dma)
|
|
return -EBUSY;
|
|
|
|
+ prtd->dma_period_left = 0;
|
|
prtd->dma_pos = prtd->dma_start;
|
|
|
|
return 0;
|
|
@@ -219,6 +227,13 @@ static int jz4740_pcm_open(struct snd_pcm_substream *substream)
|
|
if (prtd == NULL)
|
|
return -ENOMEM;
|
|
|
|
+ /* Force period and buffer size to be a multiple of the DMA transfer
|
|
+ * size, which is 16 bytes. */
|
|
+ snd_pcm_hw_constraint_step(runtime, 0,
|
|
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);
|
|
+ snd_pcm_hw_constraint_step(runtime, 0,
|
|
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
|
|
+
|
|
snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware);
|
|
|
|
runtime->private_data = prtd;
|
|
--
|
|
1.7.4.1
|
|
|