sound: lpc32xx: Fix Audio suspend/resume function
[linux-2.6.34-lpc32xx.git] / sound / soc / lpc3xxx / lpc3xxx-pcm.c
1 /*
2  * sound/soc/lpc3xxx/lpc3xxx-pcm.c
3  *
4  * Author: Kevin Wells <kevin.wells@nxp.com>
5  *
6  * Copyright (C) 2008 NXP Semiconductors
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 as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26 #include <linux/dma-mapping.h>
27
28 #include <sound/core.h>
29 #include <sound/pcm.h>
30 #include <sound/pcm_params.h>
31 #include <sound/soc.h>
32
33 #include <mach/dma.h>
34 #include <mach/dmac.h>
35 #include <mach/i2s.h>
36 #include "lpc3xxx-pcm.h"
37
38 #define SND_NAME "lpc3xxx-audio"
39 static u64 lpc3xxx_pcm_dmamask = 0xffffffff;
40
41 #define NUMLINKS (3) /* 3 DMA buffers */
42
43 static const struct snd_pcm_hardware lpc3xxx_pcm_hardware = {
44         .info = (SNDRV_PCM_INFO_MMAP |
45                  SNDRV_PCM_INFO_MMAP_VALID |
46                  SNDRV_PCM_INFO_INTERLEAVED |
47                  SNDRV_PCM_INFO_BLOCK_TRANSFER |
48                  SNDRV_PCM_INFO_PAUSE |
49                  SNDRV_PCM_INFO_RESUME),
50         .formats = (SND_SOC_DAIFMT_I2S),
51         .period_bytes_min = 128,
52         .period_bytes_max = 2048,
53         .periods_min = 2,
54         .periods_max = 1024,
55         .buffer_bytes_max = 128 * 1024
56 };
57
58 struct lpc3xxx_dma_data {
59         dma_addr_t dma_buffer;  /* physical address of DMA buffer */
60         dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
61         size_t period_size;
62
63         /* DMA configuration and support */
64         int dmach;
65         struct dma_config dmacfg;
66         volatile dma_addr_t period_ptr; /* physical address of next period */
67         volatile dma_addr_t dma_cur;
68         u32 llptr;              /* Saved for debug only, not used */
69 };
70
71 static int lpc3xxx_pcm_allocate_dma_buffer(struct snd_pcm *pcm, int stream)
72 {
73         struct snd_pcm_substream *substream = pcm->streams[stream].substream;
74         struct snd_dma_buffer *dmabuf = &substream->dma_buffer;
75         size_t size = lpc3xxx_pcm_hardware.buffer_bytes_max;
76
77         dmabuf->dev.type = SNDRV_DMA_TYPE_DEV;
78         dmabuf->dev.dev = pcm->card->dev;
79         dmabuf->private_data = NULL;
80         dmabuf->area = dma_alloc_writecombine(pcm->card->dev, size,
81                                            &dmabuf->addr, GFP_KERNEL);
82
83         if (!dmabuf->area)
84                 return -ENOMEM;
85
86         dmabuf->bytes = size;
87         return 0;
88 }
89
90 /*
91  * DMA ISR - occurs when a new DMA buffer is needed
92  */
93 static void lpc3xxx_pcm_dma_irq(int channel, int cause,
94                                 struct snd_pcm_substream *substream) {
95         struct snd_pcm_runtime *rtd = substream->runtime;
96         struct lpc3xxx_dma_data *prtd = rtd->private_data;
97         static int count = 0;
98
99         count++;
100
101         /* A DMA interrupt occurred - for most cases, this will be the end
102            of a transmitted buffer in the DMA link list, but errors are also
103            handled. */
104         if (cause & DMA_ERR_INT) {
105                 /* DMA error - this should never happen, but you just never
106                    know. If it does happen, the driver will continue without
107                    any problems except for maybe an audio glitch or pop. */
108                 pr_debug("%s: DMA error %s (count=%d)\n", SND_NAME,
109                            substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
110                            "underrun" : "overrun", count);
111         }
112         /* Dequeue buffer from linked list */
113         lpc32xx_get_free_llist_entry(channel);
114         prtd->dma_cur += prtd->period_size;
115         if (prtd->dma_cur >= prtd->dma_buffer_end) {
116                 prtd->dma_cur = prtd->dma_buffer;
117         }
118
119         /* Re-queue buffer another buffer */
120         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
121                 lpc32xx_dma_queue_llist_entry(prtd->dmach, (void *) prtd->period_ptr,
122 #if defined(CONFIG_SND_LPC32XX_USEI2S1)
123                         (void *) I2S_TX_FIFO(LPC32XX_I2S1_BASE),
124 #else
125                         (void *) I2S_TX_FIFO(LPC32XX_I2S0_BASE),
126 #endif
127                         prtd->period_size);
128         }
129         else {
130                 lpc32xx_dma_queue_llist_entry(prtd->dmach,
131 #if defined(CONFIG_SND_LPC32XX_USEI2S1)
132                         (void *) I2S_RX_FIFO(LPC32XX_I2S1_BASE),
133 #else
134                         (void *) I2S_RX_FIFO(LPC32XX_I2S0_BASE),
135 #endif
136                         (void *) prtd->period_ptr, prtd->period_size);
137         }
138         prtd->period_ptr += prtd->period_size;
139         if (prtd->period_ptr >= prtd->dma_buffer_end)
140                 prtd->period_ptr = prtd->dma_buffer;
141
142         /* This only needs to be called once, even if more than 1 period has passed */
143         snd_pcm_period_elapsed(substream);
144 }
145
146 /*
147  * PCM operations
148  */
149 static int lpc3xxx_pcm_hw_params(struct snd_pcm_substream *substream,
150                                  struct snd_pcm_hw_params *params)
151 {
152         struct snd_pcm_runtime *runtime = substream->runtime;
153         struct lpc3xxx_dma_data *prtd = runtime->private_data;
154
155         /* this may get called several times by oss emulation
156          * with different params
157          */
158         snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
159         runtime->dma_bytes = params_buffer_bytes(params);
160
161         prtd->dma_buffer = runtime->dma_addr;
162         prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
163         prtd->period_size = params_period_bytes(params);
164
165         return 0;
166 }
167
168 static int lpc3xxx_pcm_hw_free(struct snd_pcm_substream *substream)
169 {
170         struct lpc3xxx_dma_data *prtd = substream->runtime->private_data;
171
172         /* Return the DMA channel */
173         if (prtd->dmach != -1) {
174                 lpc32xx_dma_ch_disable(prtd->dmach);
175                 lpc32xx_dma_dealloc_llist(prtd->dmach);
176                 lpc32xx_dma_ch_put(prtd->dmach);
177                 prtd->dmach = -1;
178         }
179
180         return 0;
181 }
182
183 static int lpc3xxx_pcm_prepare(struct snd_pcm_substream *substream)
184 {
185         struct lpc3xxx_dma_data *prtd = substream->runtime->private_data;
186
187         /* Setup DMA channel */
188         if (prtd->dmach == -1) {
189                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
190                         prtd->dmach = DMA_CH_I2S_TX;
191                         prtd->dmacfg.ch = DMA_CH_I2S_TX;
192                         prtd->dmacfg.tc_inten = 1;
193                         prtd->dmacfg.err_inten = 1;
194                         prtd->dmacfg.src_size = 4;
195                         prtd->dmacfg.src_inc = 1;
196                         prtd->dmacfg.src_ahb1 = 1;
197                         prtd->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4;
198                         prtd->dmacfg.src_prph = 0;
199                         prtd->dmacfg.dst_size = 4;
200                         prtd->dmacfg.dst_inc = 0;
201                         prtd->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4;
202                         prtd->dmacfg.dst_ahb1 = 0;
203 #if defined(CONFIG_SND_LPC32XX_USEI2S1)
204                         prtd->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_I2S1_DMA1);
205 #else
206                         prtd->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_I2S0_DMA1);
207 #endif
208                         prtd->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_M2P;
209                         if (lpc32xx_dma_ch_get(&prtd->dmacfg, "dma_i2s_tx",
210                                 &lpc3xxx_pcm_dma_irq, substream) < 0) {
211                                 pr_debug(KERN_ERR "Error setting up I2S TX DMA channel\n");
212                                 return -ENODEV;
213                         }
214
215                         /* Allocate a linked list for audio buffers */
216                         prtd->llptr = lpc32xx_dma_alloc_llist(prtd->dmach, NUMLINKS);
217                         if (prtd->llptr == 0) {
218                                 lpc32xx_dma_ch_put(prtd->dmach);
219                                 prtd->dmach = -1;
220                                 pr_debug(KERN_ERR "Error allocating list buffer (I2S TX)\n");
221                                 return -ENOMEM;
222                         }
223                 }
224                 else {
225                         prtd->dmach = DMA_CH_I2S_RX;
226                         prtd->dmacfg.ch = DMA_CH_I2S_RX;
227                         prtd->dmacfg.tc_inten = 1;
228                         prtd->dmacfg.err_inten = 1;
229                         prtd->dmacfg.src_size = 4;
230                         prtd->dmacfg.src_inc = 0;
231                         prtd->dmacfg.src_ahb1 = 1;
232                         prtd->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4;
233 #if defined(CONFIG_SND_LPC32XX_USEI2S1)
234                         prtd->dmacfg.src_prph = DMAC_SRC_PERIP(DMA_PERID_I2S1_DMA0);
235 #else
236                         prtd->dmacfg.src_prph = DMAC_SRC_PERIP(DMA_PERID_I2S0_DMA0);
237 #endif
238                         prtd->dmacfg.dst_size = 4;
239                         prtd->dmacfg.dst_inc = 1;
240                         prtd->dmacfg.dst_ahb1 = 0;
241                         prtd->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4;
242                         prtd->dmacfg.dst_prph = 0;
243                         prtd->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_P2M;
244                         if (lpc32xx_dma_ch_get(&prtd->dmacfg, "dma_i2s_rx",
245                                 &lpc3xxx_pcm_dma_irq, substream) < 0) {
246                                 pr_debug(KERN_ERR "Error setting up I2S RX DMA channel\n");
247                                 return -ENODEV;
248                         }
249
250                         /* Allocate a linked list for audio buffers */
251                         prtd->llptr = lpc32xx_dma_alloc_llist(prtd->dmach, NUMLINKS);
252                         if (prtd->llptr == 0) {
253                                 lpc32xx_dma_ch_put(prtd->dmach);
254                                 prtd->dmach = -1;
255                                 pr_debug(KERN_ERR "Error allocating list buffer (I2S RX)\n");
256                                 return -ENOMEM;
257                         }
258                 }
259         }
260
261         return 0;
262 }
263
264 static int lpc3xxx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
265 {
266         struct snd_pcm_runtime *rtd = substream->runtime;
267         struct lpc3xxx_dma_data *prtd = rtd->private_data;
268         int i, ret = 0;
269
270         switch (cmd) {
271         case SNDRV_PCM_TRIGGER_START:
272                 prtd->period_ptr = prtd->dma_cur = prtd->dma_buffer;
273                 lpc32xx_dma_flush_llist(prtd->dmach);
274
275                 /* Queue a few buffers to start DMA */
276                 for (i = 0; i < NUMLINKS; i++) {
277                         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
278                                 lpc32xx_dma_queue_llist_entry(prtd->dmach, (void *) prtd->period_ptr,
279 #if defined(CONFIG_SND_LPC32XX_USEI2S1)
280                                         (void *) I2S_TX_FIFO(LPC32XX_I2S1_BASE),
281 #else
282                                         (void *) I2S_TX_FIFO(LPC32XX_I2S0_BASE),
283 #endif
284                                         prtd->period_size);
285                         }
286                         else {
287                                 lpc32xx_dma_queue_llist_entry(prtd->dmach,
288 #if defined(CONFIG_SND_LPC32XX_USEI2S1)
289                                 (void *) I2S_RX_FIFO(LPC32XX_I2S1_BASE),
290 #else
291                                 (void *) I2S_RX_FIFO(LPC32XX_I2S0_BASE),
292 #endif
293                                 (void *) prtd->period_ptr, prtd->period_size);
294
295                         }
296
297                         prtd->period_ptr += prtd->period_size;
298                 }
299                 break;
300
301         case SNDRV_PCM_TRIGGER_STOP:
302                 lpc32xx_dma_flush_llist(prtd->dmach);
303                 lpc32xx_dma_ch_disable(prtd->dmach);
304                 break;
305
306         case SNDRV_PCM_TRIGGER_SUSPEND:
307                 break;
308
309         case SNDRV_PCM_TRIGGER_RESUME:
310                 break;
311
312         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
313                 lpc32xx_dma_ch_pause_unpause(prtd->dmach, 1);
314                 break;
315
316         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
317                 lpc32xx_dma_ch_pause_unpause(prtd->dmach, 0);
318                 break;
319
320         default:
321                 ret = -EINVAL;
322         }
323
324         return ret;
325 }
326
327 static snd_pcm_uframes_t lpc3xxx_pcm_pointer(struct snd_pcm_substream *substream)
328 {
329         struct snd_pcm_runtime *runtime = substream->runtime;
330         struct lpc3xxx_dma_data *prtd = runtime->private_data;
331         snd_pcm_uframes_t x;
332
333         /* Return an offset into the DMA buffer for the next data */
334         x = bytes_to_frames(runtime, (prtd->dma_cur - runtime->dma_addr));
335         if (x >= runtime->buffer_size)
336                 x = 0;
337
338         return x;
339 }
340
341 static int lpc3xxx_pcm_open(struct snd_pcm_substream *substream)
342 {
343         struct snd_pcm_runtime *runtime = substream->runtime;
344         struct lpc3xxx_dma_data *prtd;
345         int ret = 0;
346
347         snd_soc_set_runtime_hwparams(substream, &lpc3xxx_pcm_hardware);
348
349         /* ensure that buffer size is a multiple of period size */
350         ret = snd_pcm_hw_constraint_integer(runtime,
351                                             SNDRV_PCM_HW_PARAM_PERIODS);
352         if (ret < 0)
353                 goto out;
354
355         prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
356         if (prtd == NULL) {
357                 ret = -ENOMEM;
358                 goto out;
359         }
360         runtime->private_data = prtd;
361         prtd->dmach = -1;
362
363 out:
364         return ret;
365 }
366
367 static int lpc3xxx_pcm_close(struct snd_pcm_substream *substream)
368 {
369         struct lpc3xxx_dma_data *prtd = substream->runtime->private_data;
370
371         kfree(prtd);
372         return 0;
373 }
374
375 static int lpc3xxx_pcm_mmap(struct snd_pcm_substream *substream,
376                             struct vm_area_struct *vma)
377 {
378         struct snd_pcm_runtime *runtime = substream->runtime;
379
380         return dma_mmap_writecombine(substream->pcm->card->dev, vma,
381                                      runtime->dma_area,
382                                      runtime->dma_addr,
383                                      runtime->dma_bytes);
384 }
385
386 static struct snd_pcm_ops lpc3xxx_pcm_ops = {
387         .open = lpc3xxx_pcm_open,
388         .close = lpc3xxx_pcm_close,
389         .ioctl = snd_pcm_lib_ioctl,
390         .hw_params = lpc3xxx_pcm_hw_params,
391         .hw_free = lpc3xxx_pcm_hw_free,
392         .prepare = lpc3xxx_pcm_prepare,
393         .trigger = lpc3xxx_pcm_trigger,
394         .pointer = lpc3xxx_pcm_pointer,
395         .mmap = lpc3xxx_pcm_mmap,
396 };
397
398 /*
399  * ASoC platform driver
400  */
401 static int lpc3xxx_pcm_new(struct snd_card *card,
402                            struct snd_soc_dai *dai,
403                            struct snd_pcm *pcm)
404 {
405         int ret = 0;
406
407         if (!card->dev->dma_mask)
408                 card->dev->dma_mask = &lpc3xxx_pcm_dmamask;
409         if (!card->dev->coherent_dma_mask)
410                 card->dev->coherent_dma_mask = 0xffffffff;
411
412         if (dai->playback.channels_min) {
413                 ret = lpc3xxx_pcm_allocate_dma_buffer(
414                           pcm, SNDRV_PCM_STREAM_PLAYBACK);
415                 if (ret)
416                         goto out;
417         }
418
419         if (dai->capture.channels_min) {
420                 pr_debug("%s: Allocating PCM capture DMA buffer\n", SND_NAME);
421                 ret = lpc3xxx_pcm_allocate_dma_buffer(
422                           pcm, SNDRV_PCM_STREAM_CAPTURE);
423                 if (ret)
424                         goto out;
425         }
426
427 out:
428         return ret;
429 }
430
431 static void lpc3xxx_pcm_free_dma_buffers(struct snd_pcm *pcm)
432 {
433         struct snd_pcm_substream *substream;
434         struct snd_dma_buffer *buf;
435         int stream;
436
437         for (stream = 0; stream < 2; stream++) {
438                 substream = pcm->streams[stream].substream;
439                 if (substream == NULL)
440                         continue;
441
442                 buf = &substream->dma_buffer;
443                 if (!buf->area)
444                         continue;
445                 dma_free_writecombine(pcm->card->dev, buf->bytes,
446                                       buf->area, buf->addr);
447
448                 buf->area = NULL;
449         }
450 }
451
452 #if defined(CONFIG_PM)
453 static int lpc3xxx_pcm_suspend(struct snd_soc_dai *dai)
454 {
455         struct snd_pcm_runtime *runtime = dai->runtime;
456         struct lpc3xxx_dma_data *prtd;
457
458         if (runtime == NULL)
459                 return 0;
460
461         prtd = runtime->private_data;
462
463         /* Disable the DMA channel */
464         lpc32xx_dma_ch_disable(prtd->dmach);
465
466         return 0;
467 }
468
469 static int lpc3xxx_pcm_resume(struct snd_soc_dai *dai)
470 {
471         struct snd_pcm_runtime *runtime = dai->runtime;
472         struct lpc3xxx_dma_data *prtd;
473
474         if (runtime == NULL)
475                 return 0;
476
477         prtd = runtime->private_data;
478
479         /* Enable the DMA channel */
480         lpc32xx_dma_ch_enable(prtd->dmach);
481
482         return 0;
483 }
484
485 #else
486 #define lpc3xxx_pcm_suspend     NULL
487 #define lpc3xxx_pcm_resume      NULL
488 #endif
489
490 struct snd_soc_platform lpc3xxx_soc_platform = {
491         .name = SND_NAME,
492         .pcm_ops = &lpc3xxx_pcm_ops,
493         .pcm_new = lpc3xxx_pcm_new,
494         .pcm_free = lpc3xxx_pcm_free_dma_buffers,
495         .suspend = lpc3xxx_pcm_suspend,
496         .resume = lpc3xxx_pcm_resume,
497 };
498 EXPORT_SYMBOL_GPL(lpc3xxx_soc_platform);
499
500 static int __init lpc3xxx_soc_platform_init(void)
501 {
502         return snd_soc_register_platform(&lpc3xxx_soc_platform);
503 }
504 module_init(lpc3xxx_soc_platform_init);
505
506 static void __exit lpc3xxx_soc_platform_exit(void)
507 {
508         snd_soc_unregister_platform(&lpc3xxx_soc_platform);
509 }
510 module_exit(lpc3xxx_soc_platform_exit)
511
512 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
513 MODULE_DESCRIPTION("NXP LPC3XXX PCM module");
514 MODULE_LICENSE("GPL");