Pull battery into release branch
[linux-2.6] / sound / soc / pxa / pxa2xx-pcm.c
1 /*
2  * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip
3  *
4  * Author:      Nicolas Pitre
5  * Created:     Nov 30, 2004
6  * Copyright:   (C) 2004 MontaVista Software, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
17 #include <linux/dma-mapping.h>
18
19 #include <sound/driver.h>
20 #include <sound/core.h>
21 #include <sound/pcm.h>
22 #include <sound/pcm_params.h>
23 #include <sound/soc.h>
24
25 #include <asm/dma.h>
26 #include <asm/hardware.h>
27 #include <asm/arch/pxa-regs.h>
28 #include <asm/arch/audio.h>
29
30 #include "pxa2xx-pcm.h"
31
32 static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
33         .info                   = SNDRV_PCM_INFO_MMAP |
34                                   SNDRV_PCM_INFO_MMAP_VALID |
35                                   SNDRV_PCM_INFO_INTERLEAVED |
36                                   SNDRV_PCM_INFO_PAUSE |
37                                   SNDRV_PCM_INFO_RESUME,
38         .formats                = SNDRV_PCM_FMTBIT_S16_LE |
39                                         SNDRV_PCM_FMTBIT_S24_LE |
40                                         SNDRV_PCM_FMTBIT_S32_LE,
41         .period_bytes_min       = 32,
42         .period_bytes_max       = 8192 - 32,
43         .periods_min            = 1,
44         .periods_max            = PAGE_SIZE/sizeof(pxa_dma_desc),
45         .buffer_bytes_max       = 128 * 1024,
46         .fifo_size              = 32,
47 };
48
49 struct pxa2xx_runtime_data {
50         int dma_ch;
51         struct pxa2xx_pcm_dma_params *params;
52         pxa_dma_desc *dma_desc_array;
53         dma_addr_t dma_desc_array_phys;
54 };
55
56 static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
57 {
58         struct snd_pcm_substream *substream = dev_id;
59         struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
60         int dcsr;
61
62         dcsr = DCSR(dma_ch);
63         DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
64
65         if (dcsr & DCSR_ENDINTR) {
66                 snd_pcm_period_elapsed(substream);
67         } else {
68                 printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
69                         prtd->params->name, dma_ch, dcsr );
70         }
71 }
72
73 static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
74         struct snd_pcm_hw_params *params)
75 {
76         struct snd_pcm_runtime *runtime = substream->runtime;
77         struct pxa2xx_runtime_data *prtd = runtime->private_data;
78         struct snd_soc_pcm_runtime *rtd = substream->private_data;
79         struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
80         size_t totsize = params_buffer_bytes(params);
81         size_t period = params_period_bytes(params);
82         pxa_dma_desc *dma_desc;
83         dma_addr_t dma_buff_phys, next_desc_phys;
84         int ret;
85
86         /* return if this is a bufferless transfer e.g.
87          * codec <--> BT codec or GSM modem -- lg FIXME */
88          if (!dma)
89                 return 0;
90
91         /* this may get called several times by oss emulation
92          * with different params */
93         if (prtd->params == NULL) {
94                 prtd->params = dma;
95                 ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW,
96                               pxa2xx_pcm_dma_irq, substream);
97                 if (ret < 0)
98                         return ret;
99                 prtd->dma_ch = ret;
100         } else if (prtd->params != dma) {
101                 pxa_free_dma(prtd->dma_ch);
102                 prtd->params = dma;
103                 ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW,
104                               pxa2xx_pcm_dma_irq, substream);
105                 if (ret < 0)
106                         return ret;
107                 prtd->dma_ch = ret;
108         }
109
110         snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
111         runtime->dma_bytes = totsize;
112
113         dma_desc = prtd->dma_desc_array;
114         next_desc_phys = prtd->dma_desc_array_phys;
115         dma_buff_phys = runtime->dma_addr;
116         do {
117                 next_desc_phys += sizeof(pxa_dma_desc);
118                 dma_desc->ddadr = next_desc_phys;
119                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
120                         dma_desc->dsadr = dma_buff_phys;
121                         dma_desc->dtadr = prtd->params->dev_addr;
122                 } else {
123                         dma_desc->dsadr = prtd->params->dev_addr;
124                         dma_desc->dtadr = dma_buff_phys;
125                 }
126                 if (period > totsize)
127                         period = totsize;
128                 dma_desc->dcmd = prtd->params->dcmd | period | DCMD_ENDIRQEN;
129                 dma_desc++;
130                 dma_buff_phys += period;
131         } while (totsize -= period);
132         dma_desc[-1].ddadr = prtd->dma_desc_array_phys;
133
134         return 0;
135 }
136
137 static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
138 {
139         struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
140
141         if (prtd && prtd->params)
142                 *prtd->params->drcmr = 0;
143
144         if (prtd->dma_ch) {
145                 snd_pcm_set_runtime_buffer(substream, NULL);
146                 pxa_free_dma(prtd->dma_ch);
147                 prtd->dma_ch = 0;
148         }
149
150         return 0;
151 }
152
153 static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
154 {
155         struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
156
157         DCSR(prtd->dma_ch) &= ~DCSR_RUN;
158         DCSR(prtd->dma_ch) = 0;
159         DCMD(prtd->dma_ch) = 0;
160         *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
161
162         return 0;
163 }
164
165 static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
166 {
167         struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
168         int ret = 0;
169
170         switch (cmd) {
171         case SNDRV_PCM_TRIGGER_START:
172                 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
173                 DCSR(prtd->dma_ch) = DCSR_RUN;
174                 break;
175
176         case SNDRV_PCM_TRIGGER_STOP:
177         case SNDRV_PCM_TRIGGER_SUSPEND:
178         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
179                 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
180                 break;
181
182         case SNDRV_PCM_TRIGGER_RESUME:
183                 DCSR(prtd->dma_ch) |= DCSR_RUN;
184                 break;
185         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
186                 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
187                 DCSR(prtd->dma_ch) |= DCSR_RUN;
188                 break;
189
190         default:
191                 ret = -EINVAL;
192         }
193
194         return ret;
195 }
196
197 static snd_pcm_uframes_t
198 pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
199 {
200         struct snd_pcm_runtime *runtime = substream->runtime;
201         struct pxa2xx_runtime_data *prtd = runtime->private_data;
202
203         dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
204                          DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
205         snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
206
207         if (x == runtime->buffer_size)
208                 x = 0;
209         return x;
210 }
211
212 static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
213 {
214         struct snd_pcm_runtime *runtime = substream->runtime;
215         struct pxa2xx_runtime_data *prtd;
216         int ret;
217
218         snd_soc_set_runtime_hwparams(substream, &pxa2xx_pcm_hardware);
219
220         /*
221          * For mysterious reasons (and despite what the manual says)
222          * playback samples are lost if the DMA count is not a multiple
223          * of the DMA burst size.  Let's add a rule to enforce that.
224          */
225         ret = snd_pcm_hw_constraint_step(runtime, 0,
226                 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
227         if (ret)
228                 goto out;
229
230         ret = snd_pcm_hw_constraint_step(runtime, 0,
231                 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
232         if (ret)
233                 goto out;
234
235         ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
236         if (ret < 0)
237                 goto out;
238
239         prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL);
240         if (prtd == NULL) {
241                 ret = -ENOMEM;
242                 goto out;
243         }
244
245         prtd->dma_desc_array =
246                 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
247                                        &prtd->dma_desc_array_phys, GFP_KERNEL);
248         if (!prtd->dma_desc_array) {
249                 ret = -ENOMEM;
250                 goto err1;
251         }
252
253         runtime->private_data = prtd;
254         return 0;
255
256  err1:
257         kfree(prtd);
258  out:
259         return ret;
260 }
261
262 static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
263 {
264         struct snd_pcm_runtime *runtime = substream->runtime;
265         struct pxa2xx_runtime_data *prtd = runtime->private_data;
266
267         dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
268                               prtd->dma_desc_array, prtd->dma_desc_array_phys);
269         kfree(prtd);
270         return 0;
271 }
272
273 static int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
274         struct vm_area_struct *vma)
275 {
276         struct snd_pcm_runtime *runtime = substream->runtime;
277         return dma_mmap_writecombine(substream->pcm->card->dev, vma,
278                                      runtime->dma_area,
279                                      runtime->dma_addr,
280                                      runtime->dma_bytes);
281 }
282
283 struct snd_pcm_ops pxa2xx_pcm_ops = {
284         .open           = pxa2xx_pcm_open,
285         .close          = pxa2xx_pcm_close,
286         .ioctl          = snd_pcm_lib_ioctl,
287         .hw_params      = pxa2xx_pcm_hw_params,
288         .hw_free        = pxa2xx_pcm_hw_free,
289         .prepare        = pxa2xx_pcm_prepare,
290         .trigger        = pxa2xx_pcm_trigger,
291         .pointer        = pxa2xx_pcm_pointer,
292         .mmap           = pxa2xx_pcm_mmap,
293 };
294
295 static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
296 {
297         struct snd_pcm_substream *substream = pcm->streams[stream].substream;
298         struct snd_dma_buffer *buf = &substream->dma_buffer;
299         size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
300         buf->dev.type = SNDRV_DMA_TYPE_DEV;
301         buf->dev.dev = pcm->card->dev;
302         buf->private_data = NULL;
303         buf->area = dma_alloc_writecombine(pcm->card->dev, size,
304                                            &buf->addr, GFP_KERNEL);
305         if (!buf->area)
306                 return -ENOMEM;
307         buf->bytes = size;
308         return 0;
309 }
310
311 static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
312 {
313         struct snd_pcm_substream *substream;
314         struct snd_dma_buffer *buf;
315         int stream;
316
317         for (stream = 0; stream < 2; stream++) {
318                 substream = pcm->streams[stream].substream;
319                 if (!substream)
320                         continue;
321
322                 buf = &substream->dma_buffer;
323                 if (!buf->area)
324                         continue;
325
326                 dma_free_writecombine(pcm->card->dev, buf->bytes,
327                                       buf->area, buf->addr);
328                 buf->area = NULL;
329         }
330 }
331
332 static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK;
333
334 int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai,
335         struct snd_pcm *pcm)
336 {
337         int ret = 0;
338
339         if (!card->dev->dma_mask)
340                 card->dev->dma_mask = &pxa2xx_pcm_dmamask;
341         if (!card->dev->coherent_dma_mask)
342                 card->dev->coherent_dma_mask = DMA_32BIT_MASK;
343
344         if (dai->playback.channels_min) {
345                 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
346                         SNDRV_PCM_STREAM_PLAYBACK);
347                 if (ret)
348                         goto out;
349         }
350
351         if (dai->capture.channels_min) {
352                 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
353                         SNDRV_PCM_STREAM_CAPTURE);
354                 if (ret)
355                         goto out;
356         }
357  out:
358         return ret;
359 }
360
361 struct snd_soc_platform pxa2xx_soc_platform = {
362         .name           = "pxa2xx-audio",
363         .pcm_ops        = &pxa2xx_pcm_ops,
364         .pcm_new        = pxa2xx_pcm_new,
365         .pcm_free       = pxa2xx_pcm_free_dma_buffers,
366 };
367
368 EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
369
370 MODULE_AUTHOR("Nicolas Pitre");
371 MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
372 MODULE_LICENSE("GPL");