diff options
-rw-r--r-- | include/sound/pxa2xx-lib.h | 1 | ||||
-rw-r--r-- | sound/arm/pxa2xx-ac97.c | 13 | ||||
-rw-r--r-- | sound/arm/pxa2xx-pcm-lib.c | 201 | ||||
-rw-r--r-- | sound/arm/pxa2xx-pcm.c | 12 | ||||
-rw-r--r-- | sound/arm/pxa2xx-pcm.h | 2 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-ac97.c | 49 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-i2s.c | 3 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-pcm.c | 32 |
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); | |||
12 | extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd); | 12 | extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd); |
13 | extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream); | 13 | extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream); |
14 | extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream); | 14 | extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream); |
15 | extern void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id); | ||
16 | extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream); | 15 | extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream); |
17 | extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream); | 16 | extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream); |
18 | extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, | 17 | extern 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 | ||
46 | static unsigned long pxa2xx_ac97_pcm_out_req = 12; | 47 | static struct pxad_param pxa2xx_ac97_pcm_out_req = { |
48 | .prio = PXAD_PRIO_LOWEST, | ||
49 | .drcmr = 12, | ||
50 | }; | ||
51 | |||
47 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = { | 52 | static 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 | ||
54 | static unsigned long pxa2xx_ac97_pcm_in_req = 11; | 59 | static struct pxad_param pxa2xx_ac97_pcm_in_req = { |
60 | .prio = PXAD_PRIO_LOWEST, | ||
61 | .drcmr = 11, | ||
62 | }; | ||
63 | |||
55 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = { | 64 | static 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 | ||
22 | static const struct snd_pcm_hardware pxa2xx_pcm_hardware = { | 21 | static 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 = { | |||
39 | int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, | 38 | int __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 | ||
106 | int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) | 69 | int __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 | ||
120 | int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 76 | int 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 | } |
151 | EXPORT_SYMBOL(pxa2xx_pcm_trigger); | 80 | EXPORT_SYMBOL(pxa2xx_pcm_trigger); |
152 | 81 | ||
153 | snd_pcm_uframes_t | 82 | snd_pcm_uframes_t |
154 | pxa2xx_pcm_pointer(struct snd_pcm_substream *substream) | 83 | pxa2xx_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 | } |
167 | EXPORT_SYMBOL(pxa2xx_pcm_pointer); | 87 | EXPORT_SYMBOL(pxa2xx_pcm_pointer); |
168 | 88 | ||
169 | int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) | 89 | int __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 | } |
188 | EXPORT_SYMBOL(__pxa2xx_pcm_prepare); | 93 | EXPORT_SYMBOL(__pxa2xx_pcm_prepare); |
189 | 94 | ||
190 | void 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 | } | ||
206 | EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); | ||
207 | |||
208 | int __pxa2xx_pcm_open(struct snd_pcm_substream *substream) | 95 | int __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 | } |
255 | EXPORT_SYMBOL(__pxa2xx_pcm_open); | 132 | EXPORT_SYMBOL(__pxa2xx_pcm_open); |
256 | 133 | ||
257 | int __pxa2xx_pcm_close(struct snd_pcm_substream *substream) | 134 | int __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 | } |
267 | EXPORT_SYMBOL(__pxa2xx_pcm_close); | 138 | EXPORT_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) | |||
66 | static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) | 62 | static 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 @@ | |||
13 | struct pxa2xx_runtime_data { | 13 | struct 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 | ||
20 | struct pxa2xx_pcm_client { | 18 | struct 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 | ||
52 | static unsigned long pxa2xx_ac97_pcm_stereo_in_req = 11; | 53 | static struct pxad_param pxa2xx_ac97_pcm_stereo_in_req = { |
54 | .prio = PXAD_PRIO_LOWEST, | ||
55 | .drcmr = 11, | ||
56 | }; | ||
57 | |||
53 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = { | 58 | static 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 | ||
60 | static unsigned long pxa2xx_ac97_pcm_stereo_out_req = 12; | 65 | static struct pxad_param pxa2xx_ac97_pcm_stereo_out_req = { |
66 | .prio = PXAD_PRIO_LOWEST, | ||
67 | .drcmr = 12, | ||
68 | }; | ||
69 | |||
61 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = { | 70 | static 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 | ||
68 | static unsigned long pxa2xx_ac97_pcm_aux_mono_out_req = 10; | 77 | static struct pxad_param pxa2xx_ac97_pcm_aux_mono_out_req = { |
78 | .prio = PXAD_PRIO_LOWEST, | ||
79 | .drcmr = 10, | ||
80 | }; | ||
69 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = { | 81 | static 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 | ||
76 | static unsigned long pxa2xx_ac97_pcm_aux_mono_in_req = 9; | 88 | static struct pxad_param pxa2xx_ac97_pcm_aux_mono_in_req = { |
89 | .prio = PXAD_PRIO_LOWEST, | ||
90 | .drcmr = 9, | ||
91 | }; | ||
77 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = { | 92 | static 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 | ||
84 | static unsigned long pxa2xx_ac97_pcm_aux_mic_mono_req = 8; | 99 | static struct pxad_param pxa2xx_ac97_pcm_aux_mic_mono_req = { |
100 | .prio = PXAD_PRIO_LOWEST, | ||
101 | .drcmr = 8, | ||
102 | }; | ||
85 | static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = { | 103 | static 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 | ||
92 | static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, | 110 | static 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 | ||
108 | static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, | 125 | static 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 | ||
124 | static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, | 140 | static 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 | ||
141 | static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { | 156 | static 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 | ||
145 | static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { | 160 | static 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 | ||
149 | static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { | 164 | static 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 @@ | |||
27 | static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, | 25 | static 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 | ||
65 | static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) | 41 | static 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 | ||