Merge branch 'topic/snd-printk' into for-linus
[pandora-kernel.git] / sound / soc / imx / mx1_mx2-pcm.c
1 /*
2  * mx1_mx2-pcm.c -- ALSA SoC interface for Freescale i.MX1x, i.MX2x CPUs
3  *
4  * Copyright 2009 Vista Silicon S.L.
5  * Author: Javier Martin
6  *         javier.martin@vista-silicon.com
7  *
8  * Based on mxc-pcm.c by Liam Girdwood.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/platform_device.h>
20 #include <linux/slab.h>
21 #include <linux/dma-mapping.h>
22 #include <sound/core.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
26 #include <asm/dma.h>
27 #include <mach/hardware.h>
28 #include <mach/dma-mx1-mx2.h>
29
30 #include "mx1_mx2-pcm.h"
31
32
33 static const struct snd_pcm_hardware mx1_mx2_pcm_hardware = {
34         .info                   = (SNDRV_PCM_INFO_INTERLEAVED |
35                                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
36                                    SNDRV_PCM_INFO_MMAP |
37                                    SNDRV_PCM_INFO_MMAP_VALID),
38         .formats                = SNDRV_PCM_FMTBIT_S16_LE,
39         .buffer_bytes_max       = 32 * 1024,
40         .period_bytes_min       = 64,
41         .period_bytes_max       = 8 * 1024,
42         .periods_min            = 2,
43         .periods_max            = 255,
44         .fifo_size              = 0,
45 };
46
47 struct mx1_mx2_runtime_data {
48         int dma_ch;
49         int active;
50         unsigned int period;
51         unsigned int periods;
52         int tx_spin;
53         spinlock_t dma_lock;
54         struct mx1_mx2_pcm_dma_params *dma_params;
55 };
56
57
58 /**
59   * This function stops the current dma transfer for playback
60   * and clears the dma pointers.
61   *
62   * @param      substream       pointer to the structure of the current stream.
63   *
64   */
65 static int audio_stop_dma(struct snd_pcm_substream *substream)
66 {
67         struct snd_pcm_runtime *runtime = substream->runtime;
68         struct mx1_mx2_runtime_data *prtd = runtime->private_data;
69         unsigned long flags;
70
71         spin_lock_irqsave(&prtd->dma_lock, flags);
72
73         pr_debug("%s\n", __func__);
74
75         prtd->active = 0;
76         prtd->period = 0;
77         prtd->periods = 0;
78
79         /* this stops the dma channel and clears the buffer ptrs */
80
81         imx_dma_disable(prtd->dma_ch);
82
83         spin_unlock_irqrestore(&prtd->dma_lock, flags);
84
85         return 0;
86 }
87
88 /**
89   * This function is called whenever a new audio block needs to be
90   * transferred to the codec. The function receives the address and the size
91   * of the new block and start a new DMA transfer.
92   *
93   * @param      substream       pointer to the structure of the current stream.
94   *
95   */
96 static int dma_new_period(struct snd_pcm_substream *substream)
97 {
98         struct snd_pcm_runtime *runtime =  substream->runtime;
99         struct mx1_mx2_runtime_data *prtd = runtime->private_data;
100         unsigned int dma_size;
101         unsigned int offset;
102         int ret = 0;
103         dma_addr_t mem_addr;
104         unsigned int dev_addr;
105
106         if (prtd->active) {
107                 dma_size = frames_to_bytes(runtime, runtime->period_size);
108                 offset = dma_size * prtd->period;
109
110                 pr_debug("%s: period (%d) out of (%d)\n", __func__,
111                         prtd->period,
112                         runtime->periods);
113                 pr_debug("period_size %d frames\n offset %d bytes\n",
114                         (unsigned int)runtime->period_size,
115                         offset);
116                 pr_debug("dma_size %d bytes\n", dma_size);
117
118                 snd_BUG_ON(dma_size > mx1_mx2_pcm_hardware.period_bytes_max);
119
120                 mem_addr = (dma_addr_t)(runtime->dma_addr + offset);
121                 dev_addr = prtd->dma_params->per_address;
122                 pr_debug("%s: mem_addr is %x\n dev_addr is %x\n",
123                                  __func__, mem_addr, dev_addr);
124
125                 ret = imx_dma_setup_single(prtd->dma_ch, mem_addr,
126                                         dma_size, dev_addr,
127                                         prtd->dma_params->transfer_type);
128                 if (ret < 0) {
129                         printk(KERN_ERR "Error %d configuring DMA\n", ret);
130                         return ret;
131                 }
132                 imx_dma_enable(prtd->dma_ch);
133
134                 pr_debug("%s: transfer enabled\nmem_addr = %x\n",
135                         __func__, (unsigned int) mem_addr);
136                 pr_debug("dev_addr = %x\ndma_size = %d\n",
137                         (unsigned int) dev_addr, dma_size);
138
139                 prtd->tx_spin = 1; /* FGA little trick to retrieve DMA pos */
140                 prtd->period++;
141                 prtd->period %= runtime->periods;
142     }
143         return ret;
144 }
145
146
147 /**
148   * This is a callback which will be called
149   * when a TX transfer finishes. The call occurs
150   * in interrupt context.
151   *
152   * @param      dat     pointer to the structure of the current stream.
153   *
154   */
155 static void audio_dma_irq(int channel, void *data)
156 {
157         struct snd_pcm_substream *substream;
158         struct snd_pcm_runtime *runtime;
159         struct mx1_mx2_runtime_data *prtd;
160         unsigned int dma_size;
161         unsigned int previous_period;
162         unsigned int offset;
163
164         substream = data;
165         runtime = substream->runtime;
166         prtd = runtime->private_data;
167         previous_period  = prtd->periods;
168         dma_size = frames_to_bytes(runtime, runtime->period_size);
169         offset = dma_size * previous_period;
170
171         prtd->tx_spin = 0;
172         prtd->periods++;
173         prtd->periods %= runtime->periods;
174
175         pr_debug("%s: irq per %d offset %x\n", __func__, prtd->periods, offset);
176
177         /*
178           * If we are getting a callback for an active stream then we inform
179           * the PCM middle layer we've finished a period
180           */
181         if (prtd->active)
182                 snd_pcm_period_elapsed(substream);
183
184         /*
185           * Trig next DMA transfer
186           */
187         dma_new_period(substream);
188 }
189
190 /**
191   * This function configures the hardware to allow audio
192   * playback operations. It is called by ALSA framework.
193   *
194   * @param      substream       pointer to the structure of the current stream.
195   *
196   * @return              0 on success, -1 otherwise.
197   */
198 static int
199 snd_mx1_mx2_prepare(struct snd_pcm_substream *substream)
200 {
201         struct snd_pcm_runtime *runtime =  substream->runtime;
202         struct mx1_mx2_runtime_data *prtd = runtime->private_data;
203
204         prtd->period = 0;
205         prtd->periods = 0;
206
207         return 0;
208 }
209
210 static int mx1_mx2_pcm_hw_params(struct snd_pcm_substream *substream,
211         struct snd_pcm_hw_params *hw_params)
212 {
213         struct snd_pcm_runtime *runtime = substream->runtime;
214         int ret;
215
216         ret = snd_pcm_lib_malloc_pages(substream,
217                                         params_buffer_bytes(hw_params));
218         if (ret < 0) {
219                 printk(KERN_ERR "%s: Error %d failed to malloc pcm pages \n",
220                 __func__, ret);
221                 return ret;
222         }
223
224         pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_addr 0x(%x)\n",
225                 __func__, (unsigned int)runtime->dma_addr);
226         pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_area 0x(%x)\n",
227                 __func__, (unsigned int)runtime->dma_area);
228         pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_bytes 0x(%x)\n",
229                 __func__, (unsigned int)runtime->dma_bytes);
230
231         return ret;
232 }
233
234 static int mx1_mx2_pcm_hw_free(struct snd_pcm_substream *substream)
235 {
236         struct snd_pcm_runtime *runtime = substream->runtime;
237         struct mx1_mx2_runtime_data *prtd = runtime->private_data;
238
239         imx_dma_free(prtd->dma_ch);
240
241         snd_pcm_lib_free_pages(substream);
242
243         return 0;
244 }
245
246 static int mx1_mx2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
247 {
248         struct mx1_mx2_runtime_data *prtd = substream->runtime->private_data;
249         int ret = 0;
250
251         switch (cmd) {
252         case SNDRV_PCM_TRIGGER_START:
253                 prtd->tx_spin = 0;
254                 /* requested stream startup */
255                 prtd->active = 1;
256                 pr_debug("%s: starting dma_new_period\n", __func__);
257                 ret = dma_new_period(substream);
258                 break;
259         case SNDRV_PCM_TRIGGER_STOP:
260                 /* requested stream shutdown */
261                 pr_debug("%s: stopping dma transfer\n", __func__);
262                 ret = audio_stop_dma(substream);
263                 break;
264         default:
265                 ret = -EINVAL;
266                 break;
267         }
268
269         return ret;
270 }
271
272 static snd_pcm_uframes_t
273 mx1_mx2_pcm_pointer(struct snd_pcm_substream *substream)
274 {
275         struct snd_pcm_runtime *runtime = substream->runtime;
276         struct mx1_mx2_runtime_data *prtd = runtime->private_data;
277         unsigned int offset = 0;
278
279         /* tx_spin value is used here to check if a transfer is active */
280         if (prtd->tx_spin) {
281                 offset = (runtime->period_size * (prtd->periods)) +
282                                                 (runtime->period_size >> 1);
283                 if (offset >= runtime->buffer_size)
284                         offset = runtime->period_size >> 1;
285         } else {
286                 offset = (runtime->period_size * (prtd->periods));
287                 if (offset >= runtime->buffer_size)
288                         offset = 0;
289         }
290         pr_debug("%s: pointer offset %x\n", __func__, offset);
291
292         return offset;
293 }
294
295 static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream)
296 {
297         struct snd_pcm_runtime *runtime = substream->runtime;
298         struct mx1_mx2_runtime_data *prtd;
299         struct snd_soc_pcm_runtime *rtd = substream->private_data;
300         struct mx1_mx2_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
301         int ret;
302
303         snd_soc_set_runtime_hwparams(substream, &mx1_mx2_pcm_hardware);
304
305         ret = snd_pcm_hw_constraint_integer(runtime,
306                                         SNDRV_PCM_HW_PARAM_PERIODS);
307         if (ret < 0)
308                 return ret;
309
310         prtd = kzalloc(sizeof(struct mx1_mx2_runtime_data), GFP_KERNEL);
311         if (prtd == NULL) {
312                 ret = -ENOMEM;
313                 goto out;
314         }
315
316         runtime->private_data = prtd;
317
318         if (!dma_data)
319                 return -ENODEV;
320
321         prtd->dma_params = dma_data;
322
323         pr_debug("%s: Requesting dma channel (%s)\n", __func__,
324                                                 prtd->dma_params->name);
325         prtd->dma_ch = imx_dma_request_by_prio(prtd->dma_params->name,
326                                                 DMA_PRIO_HIGH);
327         if (prtd->dma_ch < 0) {
328                 printk(KERN_ERR "Error %d requesting dma channel\n", ret);
329                 return ret;
330         }
331         imx_dma_config_burstlen(prtd->dma_ch,
332                                 prtd->dma_params->watermark_level);
333
334         ret = imx_dma_config_channel(prtd->dma_ch,
335                         prtd->dma_params->per_config,
336                         prtd->dma_params->mem_config,
337                         prtd->dma_params->event_id, 0);
338
339         if (ret) {
340                 pr_debug(KERN_ERR "Error %d configuring dma channel %d\n",
341                         ret, prtd->dma_ch);
342                 return ret;
343         }
344
345         pr_debug("%s: Setting tx dma callback function\n", __func__);
346         ret = imx_dma_setup_handlers(prtd->dma_ch,
347                                 audio_dma_irq, NULL,
348                                 (void *)substream);
349         if (ret < 0) {
350                 printk(KERN_ERR "Error %d setting dma callback function\n", ret);
351                 return ret;
352         }
353         return 0;
354
355  out:
356         return ret;
357 }
358
359 static int mx1_mx2_pcm_close(struct snd_pcm_substream *substream)
360 {
361         struct snd_pcm_runtime *runtime = substream->runtime;
362         struct mx1_mx2_runtime_data *prtd = runtime->private_data;
363
364         kfree(prtd);
365
366         return 0;
367 }
368
369 static int mx1_mx2_pcm_mmap(struct snd_pcm_substream *substream,
370                                 struct vm_area_struct *vma)
371 {
372         struct snd_pcm_runtime *runtime = substream->runtime;
373         return dma_mmap_writecombine(substream->pcm->card->dev, vma,
374                                      runtime->dma_area,
375                                      runtime->dma_addr,
376                                      runtime->dma_bytes);
377 }
378
379 static struct snd_pcm_ops mx1_mx2_pcm_ops = {
380         .open           = mx1_mx2_pcm_open,
381         .close          = mx1_mx2_pcm_close,
382         .ioctl          = snd_pcm_lib_ioctl,
383         .hw_params      = mx1_mx2_pcm_hw_params,
384         .hw_free        = mx1_mx2_pcm_hw_free,
385         .prepare        = snd_mx1_mx2_prepare,
386         .trigger        = mx1_mx2_pcm_trigger,
387         .pointer        = mx1_mx2_pcm_pointer,
388         .mmap           = mx1_mx2_pcm_mmap,
389 };
390
391 static u64 mx1_mx2_pcm_dmamask = 0xffffffff;
392
393 static int mx1_mx2_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
394 {
395         struct snd_pcm_substream *substream = pcm->streams[stream].substream;
396         struct snd_dma_buffer *buf = &substream->dma_buffer;
397         size_t size = mx1_mx2_pcm_hardware.buffer_bytes_max;
398         buf->dev.type = SNDRV_DMA_TYPE_DEV;
399         buf->dev.dev = pcm->card->dev;
400         buf->private_data = NULL;
401
402         /* Reserve uncached-buffered memory area for DMA */
403         buf->area = dma_alloc_writecombine(pcm->card->dev, size,
404                                            &buf->addr, GFP_KERNEL);
405
406         pr_debug("%s: preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
407                 __func__, (void *) buf->area, (void *) buf->addr, size);
408
409         if (!buf->area)
410                 return -ENOMEM;
411
412         buf->bytes = size;
413         return 0;
414 }
415
416 static void mx1_mx2_pcm_free_dma_buffers(struct snd_pcm *pcm)
417 {
418         struct snd_pcm_substream *substream;
419         struct snd_dma_buffer *buf;
420         int stream;
421
422         for (stream = 0; stream < 2; stream++) {
423                 substream = pcm->streams[stream].substream;
424                 if (!substream)
425                         continue;
426
427                 buf = &substream->dma_buffer;
428                 if (!buf->area)
429                         continue;
430
431                 dma_free_writecombine(pcm->card->dev, buf->bytes,
432                                       buf->area, buf->addr);
433                 buf->area = NULL;
434         }
435 }
436
437 static int mx1_mx2_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
438         struct snd_pcm *pcm)
439 {
440         int ret = 0;
441
442         if (!card->dev->dma_mask)
443                 card->dev->dma_mask = &mx1_mx2_pcm_dmamask;
444         if (!card->dev->coherent_dma_mask)
445                 card->dev->coherent_dma_mask = 0xffffffff;
446
447         if (dai->playback.channels_min) {
448                 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
449                         SNDRV_PCM_STREAM_PLAYBACK);
450                 pr_debug("%s: preallocate playback buffer\n", __func__);
451                 if (ret)
452                         goto out;
453         }
454
455         if (dai->capture.channels_min) {
456                 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
457                         SNDRV_PCM_STREAM_CAPTURE);
458                 pr_debug("%s: preallocate capture buffer\n", __func__);
459                 if (ret)
460                         goto out;
461         }
462  out:
463         return ret;
464 }
465
466 struct snd_soc_platform mx1_mx2_soc_platform = {
467         .name           = "mx1_mx2-audio",
468         .pcm_ops        = &mx1_mx2_pcm_ops,
469         .pcm_new        = mx1_mx2_pcm_new,
470         .pcm_free       = mx1_mx2_pcm_free_dma_buffers,
471 };
472 EXPORT_SYMBOL_GPL(mx1_mx2_soc_platform);
473
474 static int __init mx1_mx2_soc_platform_init(void)
475 {
476         return snd_soc_register_platform(&mx1_mx2_soc_platform);
477 }
478 module_init(mx1_mx2_soc_platform_init);
479
480 static void __exit mx1_mx2_soc_platform_exit(void)
481 {
482         snd_soc_unregister_platform(&mx1_mx2_soc_platform);
483 }
484 module_exit(mx1_mx2_soc_platform_exit);
485
486 MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
487 MODULE_DESCRIPTION("Freescale i.MX2x, i.MX1x PCM DMA module");
488 MODULE_LICENSE("GPL");