aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2015-09-30 16:51:52 -0400
committerMark Brown <broonie@kernel.org>2015-09-30 18:21:16 -0400
commit58ceb57ec1be928bec2faeca11fe0752f930669d (patch)
tree398273b3be0584f5ea59039776a2017b433dd98d
parent5c0e869357454c2aab3d02d002ffc1f0a0ab2782 (diff)
ASoC: pxa: pxa-pcm-lib: switch over to snd-soc-dmaengine-pcm
This patch removes the old PXA DMA API usage and switches over to generic functions provided by snd-soc-dmaengine-pcm. More cleanups may be done on top of this, and some function stubs can now be removed completetly. However, the intention here was to keep the transition as small as possible. This was tested on the mioa701 pxa27x board. Signed-off-by: Daniel Mack <zonque@gmail.com> [trivial change from mmp-dma to pxa-dma] Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/pxa2xx-lib.h1
-rw-r--r--sound/arm/pxa2xx-ac97.c13
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c201
-rw-r--r--sound/arm/pxa2xx-pcm.c12
-rw-r--r--sound/arm/pxa2xx-pcm.h2
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c49
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c3
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c32
8 files changed, 85 insertions, 228 deletions
diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h
index 56e818e4a1cb..6ef629bde164 100644
--- a/include/sound/pxa2xx-lib.h
+++ b/include/sound/pxa2xx-lib.h
@@ -12,7 +12,6 @@ extern int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
12extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd); 12extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
13extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream); 13extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream);
14extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream); 14extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
15extern void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id);
16extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream); 15extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream);
17extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream); 16extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream);
18extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, 17extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 38590b322c54..fbd5dad0c484 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/dma/pxa-dma.h>
18 19
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
@@ -43,7 +44,11 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
43 .reset = pxa2xx_ac97_reset, 44 .reset = pxa2xx_ac97_reset,
44}; 45};
45 46
46static unsigned long pxa2xx_ac97_pcm_out_req = 12; 47static struct pxad_param pxa2xx_ac97_pcm_out_req = {
48 .prio = PXAD_PRIO_LOWEST,
49 .drcmr = 12,
50};
51
47static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = { 52static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
48 .addr = __PREG(PCDR), 53 .addr = __PREG(PCDR),
49 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 54 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -51,7 +56,11 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
51 .filter_data = &pxa2xx_ac97_pcm_out_req, 56 .filter_data = &pxa2xx_ac97_pcm_out_req,
52}; 57};
53 58
54static unsigned long pxa2xx_ac97_pcm_in_req = 11; 59static struct pxad_param pxa2xx_ac97_pcm_in_req = {
60 .prio = PXAD_PRIO_LOWEST,
61 .drcmr = 11,
62};
63
55static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = { 64static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = {
56 .addr = __PREG(PCDR), 65 .addr = __PREG(PCDR),
57 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 66 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 01f8fdc42b1b..e9b98af6b52c 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -8,6 +8,7 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
10#include <linux/dmaengine.h> 10#include <linux/dmaengine.h>
11#include <linux/dma/pxa-dma.h>
11 12
12#include <sound/core.h> 13#include <sound/core.h>
13#include <sound/pcm.h> 14#include <sound/pcm.h>
@@ -15,8 +16,6 @@
15#include <sound/pxa2xx-lib.h> 16#include <sound/pxa2xx-lib.h>
16#include <sound/dmaengine_pcm.h> 17#include <sound/dmaengine_pcm.h>
17 18
18#include <mach/dma.h>
19
20#include "pxa2xx-pcm.h" 19#include "pxa2xx-pcm.h"
21 20
22static const struct snd_pcm_hardware pxa2xx_pcm_hardware = { 21static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
@@ -31,7 +30,7 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
31 .period_bytes_min = 32, 30 .period_bytes_min = 32,
32 .period_bytes_max = 8192 - 32, 31 .period_bytes_max = 8192 - 32,
33 .periods_min = 1, 32 .periods_min = 1,
34 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), 33 .periods_max = 256,
35 .buffer_bytes_max = 128 * 1024, 34 .buffer_bytes_max = 128 * 1024,
36 .fifo_size = 32, 35 .fifo_size = 32,
37}; 36};
@@ -39,65 +38,29 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
39int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 38int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
41{ 40{
42 struct snd_pcm_runtime *runtime = substream->runtime; 41 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
43 struct pxa2xx_runtime_data *rtd = runtime->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 size_t totsize = params_buffer_bytes(params); 43 struct snd_dmaengine_dai_dma_data *dma_params;
45 size_t period = params_period_bytes(params); 44 struct dma_slave_config config;
46 pxa_dma_desc *dma_desc; 45 int ret;
47 dma_addr_t dma_buff_phys, next_desc_phys;
48 u32 dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
49 46
50 /* temporary transition hack */ 47 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
51 switch (rtd->params->addr_width) { 48 if (!dma_params)
52 case DMA_SLAVE_BUSWIDTH_1_BYTE: 49 return 0;
53 dcmd |= DCMD_WIDTH1;
54 break;
55 case DMA_SLAVE_BUSWIDTH_2_BYTES:
56 dcmd |= DCMD_WIDTH2;
57 break;
58 case DMA_SLAVE_BUSWIDTH_4_BYTES:
59 dcmd |= DCMD_WIDTH4;
60 break;
61 default:
62 /* can't happen */
63 break;
64 }
65 50
66 switch (rtd->params->maxburst) { 51 ret = snd_hwparams_to_dma_slave_config(substream, params, &config);
67 case 8: 52 if (ret)
68 dcmd |= DCMD_BURST8; 53 return ret;
69 break;
70 case 16:
71 dcmd |= DCMD_BURST16;
72 break;
73 case 32:
74 dcmd |= DCMD_BURST32;
75 break;
76 }
77 54
78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 55 snd_dmaengine_pcm_set_config_from_dai_data(substream,
79 runtime->dma_bytes = totsize; 56 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
57 &config);
80 58
81 dma_desc = rtd->dma_desc_array; 59 ret = dmaengine_slave_config(chan, &config);
82 next_desc_phys = rtd->dma_desc_array_phys; 60 if (ret)
83 dma_buff_phys = runtime->dma_addr; 61 return ret;
84 do { 62
85 next_desc_phys += sizeof(pxa_dma_desc); 63 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
86 dma_desc->ddadr = next_desc_phys;
87 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
88 dma_desc->dsadr = dma_buff_phys;
89 dma_desc->dtadr = rtd->params->addr;
90 } else {
91 dma_desc->dsadr = rtd->params->addr;
92 dma_desc->dtadr = dma_buff_phys;
93 }
94 if (period > totsize)
95 period = totsize;
96 dma_desc->dcmd = dcmd | period | DCMD_ENDIRQEN;
97 dma_desc++;
98 dma_buff_phys += period;
99 } while (totsize -= period);
100 dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
101 64
102 return 0; 65 return 0;
103} 66}
@@ -105,13 +68,6 @@ EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
105 68
106int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 69int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
107{ 70{
108 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
109
110 if (rtd && rtd->params && rtd->params->filter_data) {
111 unsigned long req = *(unsigned long *) rtd->params->filter_data;
112 DRCMR(req) = 0;
113 }
114
115 snd_pcm_set_runtime_buffer(substream, NULL); 71 snd_pcm_set_runtime_buffer(substream, NULL);
116 return 0; 72 return 0;
117} 73}
@@ -119,100 +75,36 @@ EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
119 75
120int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 76int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
121{ 77{
122 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 78 return snd_dmaengine_pcm_trigger(substream, cmd);
123 int ret = 0;
124
125 switch (cmd) {
126 case SNDRV_PCM_TRIGGER_START:
127 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
128 DCSR(prtd->dma_ch) = DCSR_RUN;
129 break;
130
131 case SNDRV_PCM_TRIGGER_STOP:
132 case SNDRV_PCM_TRIGGER_SUSPEND:
133 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
134 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
135 break;
136
137 case SNDRV_PCM_TRIGGER_RESUME:
138 DCSR(prtd->dma_ch) |= DCSR_RUN;
139 break;
140 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
141 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
142 DCSR(prtd->dma_ch) |= DCSR_RUN;
143 break;
144
145 default:
146 ret = -EINVAL;
147 }
148
149 return ret;
150} 79}
151EXPORT_SYMBOL(pxa2xx_pcm_trigger); 80EXPORT_SYMBOL(pxa2xx_pcm_trigger);
152 81
153snd_pcm_uframes_t 82snd_pcm_uframes_t
154pxa2xx_pcm_pointer(struct snd_pcm_substream *substream) 83pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
155{ 84{
156 struct snd_pcm_runtime *runtime = substream->runtime; 85 return snd_dmaengine_pcm_pointer(substream);
157 struct pxa2xx_runtime_data *prtd = runtime->private_data;
158
159 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
160 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
161 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
162
163 if (x == runtime->buffer_size)
164 x = 0;
165 return x;
166} 86}
167EXPORT_SYMBOL(pxa2xx_pcm_pointer); 87EXPORT_SYMBOL(pxa2xx_pcm_pointer);
168 88
169int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) 89int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
170{ 90{
171 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
172 unsigned long req;
173
174 if (!prtd || !prtd->params)
175 return 0;
176
177 if (prtd->dma_ch == -1)
178 return -EINVAL;
179
180 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
181 DCSR(prtd->dma_ch) = 0;
182 DCMD(prtd->dma_ch) = 0;
183 req = *(unsigned long *) prtd->params->filter_data;
184 DRCMR(req) = prtd->dma_ch | DRCMR_MAPVLD;
185
186 return 0; 91 return 0;
187} 92}
188EXPORT_SYMBOL(__pxa2xx_pcm_prepare); 93EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
189 94
190void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
191{
192 struct snd_pcm_substream *substream = dev_id;
193 int dcsr;
194
195 dcsr = DCSR(dma_ch);
196 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
197
198 if (dcsr & DCSR_ENDINTR) {
199 snd_pcm_period_elapsed(substream);
200 } else {
201 printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n",
202 dma_ch, dcsr);
203 snd_pcm_stop_xrun(substream);
204 }
205}
206EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
207
208int __pxa2xx_pcm_open(struct snd_pcm_substream *substream) 95int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
209{ 96{
97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
210 struct snd_pcm_runtime *runtime = substream->runtime; 98 struct snd_pcm_runtime *runtime = substream->runtime;
211 struct pxa2xx_runtime_data *rtd; 99 struct snd_dmaengine_dai_dma_data *dma_params;
212 int ret; 100 int ret;
213 101
214 runtime->hw = pxa2xx_pcm_hardware; 102 runtime->hw = pxa2xx_pcm_hardware;
215 103
104 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
105 if (!dma_params)
106 return 0;
107
216 /* 108 /*
217 * For mysterious reasons (and despite what the manual says) 109 * For mysterious reasons (and despite what the manual says)
218 * playback samples are lost if the DMA count is not a multiple 110 * playback samples are lost if the DMA count is not a multiple
@@ -221,48 +113,27 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
221 ret = snd_pcm_hw_constraint_step(runtime, 0, 113 ret = snd_pcm_hw_constraint_step(runtime, 0,
222 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 114 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
223 if (ret) 115 if (ret)
224 goto out; 116 return ret;
225 117
226 ret = snd_pcm_hw_constraint_step(runtime, 0, 118 ret = snd_pcm_hw_constraint_step(runtime, 0,
227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 119 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
228 if (ret) 120 if (ret)
229 goto out; 121 return ret;
230 122
231 ret = snd_pcm_hw_constraint_integer(runtime, 123 ret = snd_pcm_hw_constraint_integer(runtime,
232 SNDRV_PCM_HW_PARAM_PERIODS); 124 SNDRV_PCM_HW_PARAM_PERIODS);
233 if (ret < 0) 125 if (ret < 0)
234 goto out; 126 return ret;
235
236 ret = -ENOMEM;
237 rtd = kzalloc(sizeof(*rtd), GFP_KERNEL);
238 if (!rtd)
239 goto out;
240 rtd->dma_desc_array =
241 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
242 &rtd->dma_desc_array_phys, GFP_KERNEL);
243 if (!rtd->dma_desc_array)
244 goto err1;
245 127
246 rtd->dma_ch = -1; 128 return snd_dmaengine_pcm_open_request_chan(substream,
247 runtime->private_data = rtd; 129 pxad_filter_fn,
248 return 0; 130 dma_params->filter_data);
249
250 err1:
251 kfree(rtd);
252 out:
253 return ret;
254} 131}
255EXPORT_SYMBOL(__pxa2xx_pcm_open); 132EXPORT_SYMBOL(__pxa2xx_pcm_open);
256 133
257int __pxa2xx_pcm_close(struct snd_pcm_substream *substream) 134int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
258{ 135{
259 struct snd_pcm_runtime *runtime = substream->runtime; 136 return snd_dmaengine_pcm_close_release_chan(substream);
260 struct pxa2xx_runtime_data *rtd = runtime->private_data;
261
262 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
263 rtd->dma_desc_array, rtd->dma_desc_array_phys);
264 kfree(rtd);
265 return 0;
266} 137}
267EXPORT_SYMBOL(__pxa2xx_pcm_close); 138EXPORT_SYMBOL(__pxa2xx_pcm_close);
268 139
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index 83be8e3f095e..83fcfac97739 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -46,17 +46,13 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
46 46
47 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 47 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
48 client->playback_params : client->capture_params; 48 client->playback_params : client->capture_params;
49 ret = pxa_request_dma("dma", DMA_PRIO_LOW,
50 pxa2xx_pcm_dma_irq, substream);
51 if (ret < 0)
52 goto err2;
53 rtd->dma_ch = ret;
54 49
55 ret = client->startup(substream); 50 ret = client->startup(substream);
56 if (!ret) 51 if (!ret)
57 goto out; 52 goto err2;
53
54 return 0;
58 55
59 pxa_free_dma(rtd->dma_ch);
60 err2: 56 err2:
61 __pxa2xx_pcm_close(substream); 57 __pxa2xx_pcm_close(substream);
62 out: 58 out:
@@ -66,9 +62,7 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
66static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) 62static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
67{ 63{
68 struct pxa2xx_pcm_client *client = substream->private_data; 64 struct pxa2xx_pcm_client *client = substream->private_data;
69 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
70 65
71 pxa_free_dma(rtd->dma_ch);
72 client->shutdown(substream); 66 client->shutdown(substream);
73 67
74 return __pxa2xx_pcm_close(substream); 68 return __pxa2xx_pcm_close(substream);
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 00330985beec..8fa2b7c9e6b8 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -13,8 +13,6 @@
13struct pxa2xx_runtime_data { 13struct pxa2xx_runtime_data {
14 int dma_ch; 14 int dma_ch;
15 struct snd_dmaengine_dai_dma_data *params; 15 struct snd_dmaengine_dai_dma_data *params;
16 struct pxa_dma_desc *dma_desc_array;
17 dma_addr_t dma_desc_array_phys;
18}; 16};
19 17
20struct pxa2xx_pcm_client { 18struct pxa2xx_pcm_client {
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 9e4b04e0fbd1..f3de615aacd7 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/dma/pxa-dma.h>
18 19
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
@@ -49,7 +50,11 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
49 .reset = pxa2xx_ac97_cold_reset, 50 .reset = pxa2xx_ac97_cold_reset,
50}; 51};
51 52
52static unsigned long pxa2xx_ac97_pcm_stereo_in_req = 11; 53static struct pxad_param pxa2xx_ac97_pcm_stereo_in_req = {
54 .prio = PXAD_PRIO_LOWEST,
55 .drcmr = 11,
56};
57
53static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = { 58static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
54 .addr = __PREG(PCDR), 59 .addr = __PREG(PCDR),
55 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 60 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -57,7 +62,11 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
57 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req, 62 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req,
58}; 63};
59 64
60static unsigned long pxa2xx_ac97_pcm_stereo_out_req = 12; 65static struct pxad_param pxa2xx_ac97_pcm_stereo_out_req = {
66 .prio = PXAD_PRIO_LOWEST,
67 .drcmr = 12,
68};
69
61static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = { 70static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
62 .addr = __PREG(PCDR), 71 .addr = __PREG(PCDR),
63 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 72 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -65,7 +74,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
65 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req, 74 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req,
66}; 75};
67 76
68static unsigned long pxa2xx_ac97_pcm_aux_mono_out_req = 10; 77static struct pxad_param pxa2xx_ac97_pcm_aux_mono_out_req = {
78 .prio = PXAD_PRIO_LOWEST,
79 .drcmr = 10,
80};
69static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = { 81static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
70 .addr = __PREG(MODR), 82 .addr = __PREG(MODR),
71 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 83 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -73,7 +85,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
73 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req, 85 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req,
74}; 86};
75 87
76static unsigned long pxa2xx_ac97_pcm_aux_mono_in_req = 9; 88static struct pxad_param pxa2xx_ac97_pcm_aux_mono_in_req = {
89 .prio = PXAD_PRIO_LOWEST,
90 .drcmr = 9,
91};
77static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = { 92static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
78 .addr = __PREG(MODR), 93 .addr = __PREG(MODR),
79 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 94 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -81,7 +96,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
81 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req, 96 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req,
82}; 97};
83 98
84static unsigned long pxa2xx_ac97_pcm_aux_mic_mono_req = 8; 99static struct pxad_param pxa2xx_ac97_pcm_aux_mic_mono_req = {
100 .prio = PXAD_PRIO_LOWEST,
101 .drcmr = 8,
102};
85static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = { 103static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
86 .addr = __PREG(MCDR), 104 .addr = __PREG(MCDR),
87 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 105 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -89,9 +107,8 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
89 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req, 107 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req,
90}; 108};
91 109
92static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 110static int pxa2xx_ac97_hifi_startup(struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params, 111 struct snd_soc_dai *cpu_dai)
94 struct snd_soc_dai *cpu_dai)
95{ 112{
96 struct snd_dmaengine_dai_dma_data *dma_data; 113 struct snd_dmaengine_dai_dma_data *dma_data;
97 114
@@ -105,9 +122,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
105 return 0; 122 return 0;
106} 123}
107 124
108static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 125static int pxa2xx_ac97_aux_startup(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params, 126 struct snd_soc_dai *cpu_dai)
110 struct snd_soc_dai *cpu_dai)
111{ 127{
112 struct snd_dmaengine_dai_dma_data *dma_data; 128 struct snd_dmaengine_dai_dma_data *dma_data;
113 129
@@ -121,9 +137,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
121 return 0; 137 return 0;
122} 138}
123 139
124static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 140static int pxa2xx_ac97_mic_startup(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params, 141 struct snd_soc_dai *cpu_dai)
126 struct snd_soc_dai *cpu_dai)
127{ 142{
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
129 return -ENODEV; 144 return -ENODEV;
@@ -139,15 +154,15 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
139 SNDRV_PCM_RATE_48000) 154 SNDRV_PCM_RATE_48000)
140 155
141static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { 156static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
142 .hw_params = pxa2xx_ac97_hw_params, 157 .startup = pxa2xx_ac97_hifi_startup,
143}; 158};
144 159
145static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { 160static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
146 .hw_params = pxa2xx_ac97_hw_aux_params, 161 .startup = pxa2xx_ac97_aux_startup,
147}; 162};
148 163
149static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { 164static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
150 .hw_params = pxa2xx_ac97_hw_mic_params, 165 .startup = pxa2xx_ac97_mic_startup,
151}; 166};
152 167
153/* 168/*
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b4e40036910..0389cf7b4b1e 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -319,6 +319,9 @@ static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
319 /* Along with FIFO servicing */ 319 /* Along with FIFO servicing */
320 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS); 320 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
321 321
322 snd_soc_dai_init_dma_data(dai, &pxa2xx_i2s_pcm_stereo_out,
323 &pxa2xx_i2s_pcm_stereo_in);
324
322 return 0; 325 return 0;
323} 326}
324 327
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 29a3fdbb7b59..9f390398d518 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -15,8 +15,6 @@
15#include <linux/dmaengine.h> 15#include <linux/dmaengine.h>
16#include <linux/of.h> 16#include <linux/of.h>
17 17
18#include <mach/dma.h>
19
20#include <sound/core.h> 18#include <sound/core.h>
21#include <sound/soc.h> 19#include <sound/soc.h>
22#include <sound/pxa2xx-lib.h> 20#include <sound/pxa2xx-lib.h>
@@ -27,11 +25,8 @@
27static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 25static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
28 struct snd_pcm_hw_params *params) 26 struct snd_pcm_hw_params *params)
29{ 27{
30 struct snd_pcm_runtime *runtime = substream->runtime;
31 struct pxa2xx_runtime_data *prtd = runtime->private_data;
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 28 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_dmaengine_dai_dma_data *dma; 29 struct snd_dmaengine_dai_dma_data *dma;
34 int ret;
35 30
36 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 31 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
37 32
@@ -40,40 +35,13 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
40 if (!dma) 35 if (!dma)
41 return 0; 36 return 0;
42 37
43 /* this may get called several times by oss emulation
44 * with different params */
45 if (prtd->params == NULL) {
46 prtd->params = dma;
47 ret = pxa_request_dma("name", DMA_PRIO_LOW,
48 pxa2xx_pcm_dma_irq, substream);
49 if (ret < 0)
50 return ret;
51 prtd->dma_ch = ret;
52 } else if (prtd->params != dma) {
53 pxa_free_dma(prtd->dma_ch);
54 prtd->params = dma;
55 ret = pxa_request_dma("name", DMA_PRIO_LOW,
56 pxa2xx_pcm_dma_irq, substream);
57 if (ret < 0)
58 return ret;
59 prtd->dma_ch = ret;
60 }
61
62 return __pxa2xx_pcm_hw_params(substream, params); 38 return __pxa2xx_pcm_hw_params(substream, params);
63} 39}
64 40
65static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 41static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
66{ 42{
67 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
68
69 __pxa2xx_pcm_hw_free(substream); 43 __pxa2xx_pcm_hw_free(substream);
70 44
71 if (prtd->dma_ch >= 0) {
72 pxa_free_dma(prtd->dma_ch);
73 prtd->dma_ch = -1;
74 prtd->params = NULL;
75 }
76
77 return 0; 45 return 0;
78} 46}
79 47