diff options
author | Mirko Vogt <mirko@openwrt.org> | 2012-04-08 12:09:52 +0000 |
---|---|---|
committer | Mirko Vogt <mirko@openwrt.org> | 2012-04-08 12:09:52 +0000 |
commit | 377233f931ec781fac67ae2bead81f6d5183d0c7 (patch) | |
tree | b872c6f7e0c9a79aa3ccbeb29bdfaacb94f236cc /target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch | |
parent | 75df536d1b94ccfa536be64bd7605efafce24872 (diff) | |
download | master-187ad058-377233f931ec781fac67ae2bead81f6d5183d0c7.tar.gz master-187ad058-377233f931ec781fac67ae2bead81f6d5183d0c7.tar.bz2 master-187ad058-377233f931ec781fac67ae2bead81f6d5183d0c7.zip |
[target/xburst] level up target xburst to linux kernel version 3.2.1
Thanks to the qi-hardware project - especially to Lars, Maarten and Xiangfu
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31218 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch')
-rw-r--r-- | target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch b/target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch new file mode 100644 index 0000000000..5c300a24bf --- /dev/null +++ b/target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch @@ -0,0 +1,94 @@ +From 8a5087fe59e31efb8641e704058328997c3c8ff1 Mon Sep 17 00:00:00 2001 +From: Maarten ter Huurne <maarten@treewalker.org> +Date: Wed, 10 Aug 2011 00:25:11 +0200 +Subject: [PATCH 16/21] ASoC: JZ4740: Support buffer size that is not a + multiple of period size. + +This fixes glitches triggered by libao, which sets time-based intervals +instead of byte-based intervals like SDL does. + +Thanks to Paul Cercueil for figuring out that the buffer size was causing +the glitches and to Lars Clausen for helping me write the fix. +--- + 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 d1989cd..1f9a005 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.5.4 + |