Root/target/linux/xburst/patches-3.0/0026-sound-update-DMA-code.patch

1From 5e689acca07bccdced123f82e8dde5459eca0d97 Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
3Date: Wed, 14 Sep 2011 14:30:01 +0800
4Subject: [PATCH 26/32] sound: update DMA code
5
6---
7 sound/soc/jz4740/jz4740-pcm.c | 21 ++++++++++++++++++---
8 1 files changed, 18 insertions(+), 3 deletions(-)
9
10diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
11index fb1483f..71c455d 100644
12--- a/sound/soc/jz4740/jz4740-pcm.c
13+++ b/sound/soc/jz4740/jz4740-pcm.c
14@@ -31,6 +31,7 @@
15 
16 struct jz4740_runtime_data {
17     unsigned long dma_period;
18+ unsigned long dma_period_left;
19     dma_addr_t dma_start;
20     dma_addr_t dma_pos;
21     dma_addr_t dma_end;
22@@ -67,10 +68,13 @@ static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd,
23     if (prtd->dma_pos == prtd->dma_end)
24         prtd->dma_pos = prtd->dma_start;
25 
26- if (prtd->dma_pos + prtd->dma_period > prtd->dma_end)
27+ if (prtd->dma_period_left == 0)
28+ prtd->dma_period_left = prtd->dma_period;
29+
30+ if (prtd->dma_pos + prtd->dma_period_left > prtd->dma_end)
31         count = prtd->dma_end - prtd->dma_pos;
32     else
33- count = prtd->dma_period;
34+ count = prtd->dma_period_left;
35 
36     jz4740_dma_disable(prtd->dma);
37 
38@@ -85,6 +89,7 @@ static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd,
39     jz4740_dma_set_transfer_count(prtd->dma, count);
40 
41     prtd->dma_pos += count;
42+ prtd->dma_period_left -= count;
43 
44     jz4740_dma_enable(prtd->dma);
45 }
46@@ -96,7 +101,8 @@ static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err,
47     struct snd_pcm_runtime *runtime = substream->runtime;
48     struct jz4740_runtime_data *prtd = runtime->private_data;
49 
50- snd_pcm_period_elapsed(substream);
51+ if (prtd->dma_period_left == 0)
52+ snd_pcm_period_elapsed(substream);
53 
54     jz4740_pcm_start_transfer(prtd, substream);
55 }
56@@ -133,6 +139,7 @@ static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream,
57     runtime->dma_bytes = params_buffer_bytes(params);
58 
59     prtd->dma_period = params_period_bytes(params);
60+ prtd->dma_period_left = 0;
61     prtd->dma_start = runtime->dma_addr;
62     prtd->dma_pos = prtd->dma_start;
63     prtd->dma_end = prtd->dma_start + runtime->dma_bytes;
64@@ -160,6 +167,7 @@ static int jz4740_pcm_prepare(struct snd_pcm_substream *substream)
65     if (!prtd->dma)
66         return -EBUSY;
67 
68+ prtd->dma_period_left = 0;
69     prtd->dma_pos = prtd->dma_start;
70 
71     return 0;
72@@ -219,6 +227,13 @@ static int jz4740_pcm_open(struct snd_pcm_substream *substream)
73     if (prtd == NULL)
74         return -ENOMEM;
75 
76+ /* Force period and buffer size to be a multiple of the DMA transfer
77+ * size, which is 16 bytes. */
78+ snd_pcm_hw_constraint_step(runtime, 0,
79+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);
80+ snd_pcm_hw_constraint_step(runtime, 0,
81+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
82+
83     snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware);
84 
85     runtime->private_data = prtd;
86--
871.7.4.1
88
89

Archive Download this file



interactive