Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

Linux/sound/soc/davinci/davinci-pcm.c

  1 /*
  2  * ALSA PCM interface for the TI DAVINCI processor
  3  *
  4  * Author:      Vladimir Barinov, <vbarinov@embeddedalley.com>
  5  * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
  6  * added SRAM ping/pong (C) 2008 Troy Kisky <troy.kisky@boundarydevices.com>
  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 #include <linux/kernel.h>
 19 #include <linux/genalloc.h>
 20 #include <linux/platform_data/edma.h>
 21 
 22 #include <sound/core.h>
 23 #include <sound/pcm.h>
 24 #include <sound/pcm_params.h>
 25 #include <sound/soc.h>
 26 
 27 #include <asm/dma.h>
 28 
 29 #include "davinci-pcm.h"
 30 
 31 #ifdef DEBUG
 32 static void print_buf_info(int slot, char *name)
 33 {
 34         struct edmacc_param p;
 35         if (slot < 0)
 36                 return;
 37         edma_read_slot(slot, &p);
 38         printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
 39                         name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
 40         printk(KERN_DEBUG "    src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
 41                         p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
 42 }
 43 #else
 44 static void print_buf_info(int slot, char *name)
 45 {
 46 }
 47 #endif
 48 
 49 static struct snd_pcm_hardware pcm_hardware_playback = {
 50         .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
 51                  SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
 52                  SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
 53                  SNDRV_PCM_INFO_BATCH),
 54         .buffer_bytes_max = 128 * 1024,
 55         .period_bytes_min = 32,
 56         .period_bytes_max = 8 * 1024,
 57         .periods_min = 16,
 58         .periods_max = 255,
 59         .fifo_size = 0,
 60 };
 61 
 62 static struct snd_pcm_hardware pcm_hardware_capture = {
 63         .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
 64                  SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
 65                  SNDRV_PCM_INFO_PAUSE |
 66                  SNDRV_PCM_INFO_BATCH),
 67         .buffer_bytes_max = 128 * 1024,
 68         .period_bytes_min = 32,
 69         .period_bytes_max = 8 * 1024,
 70         .periods_min = 16,
 71         .periods_max = 255,
 72         .fifo_size = 0,
 73 };
 74 
 75 /*
 76  * How ping/pong works....
 77  *
 78  * Playback:
 79  * ram_params - copys 2*ping_size from start of SDRAM to iram,
 80  *      links to ram_link2
 81  * ram_link2 - copys rest of SDRAM to iram in ping_size units,
 82  *      links to ram_link
 83  * ram_link - copys entire SDRAM to iram in ping_size uints,
 84  *      links to self
 85  *
 86  * asp_params - same as asp_link[0]
 87  * asp_link[0] - copys from lower half of iram to asp port
 88  *      links to asp_link[1], triggers iram copy event on completion
 89  * asp_link[1] - copys from upper half of iram to asp port
 90  *      links to asp_link[0], triggers iram copy event on completion
 91  *      triggers interrupt only needed to let upper SOC levels update position
 92  *      in stream on completion
 93  *
 94  * When playback is started:
 95  *      ram_params started
 96  *      asp_params started
 97  *
 98  * Capture:
 99  * ram_params - same as ram_link,
100  *      links to ram_link
101  * ram_link - same as playback
102  *      links to self
103  *
104  * asp_params - same as playback
105  * asp_link[0] - same as playback
106  * asp_link[1] - same as playback
107  *
108  * When capture is started:
109  *      asp_params started
110  */
111 struct davinci_runtime_data {
112         spinlock_t lock;
113         int period;             /* current DMA period */
114         int asp_channel;        /* Master DMA channel */
115         int asp_link[2];        /* asp parameter link channel, ping/pong */
116         struct davinci_pcm_dma_params *params;  /* DMA params */
117         int ram_channel;
118         int ram_link;
119         int ram_link2;
120         struct edmacc_param asp_params;
121         struct edmacc_param ram_params;
122 };
123 
124 static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
125 {
126         struct davinci_runtime_data *prtd = substream->runtime->private_data;
127         struct snd_pcm_runtime *runtime = substream->runtime;
128 
129         prtd->period++;
130         if (unlikely(prtd->period >= runtime->periods))
131                 prtd->period = 0;
132 }
133 
134 static void davinci_pcm_period_reset(struct snd_pcm_substream *substream)
135 {
136         struct davinci_runtime_data *prtd = substream->runtime->private_data;
137 
138         prtd->period = 0;
139 }
140 /*
141  * Not used with ping/pong
142  */
143 static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
144 {
145         struct davinci_runtime_data *prtd = substream->runtime->private_data;
146         struct snd_pcm_runtime *runtime = substream->runtime;
147         unsigned int period_size;
148         unsigned int dma_offset;
149         dma_addr_t dma_pos;
150         dma_addr_t src, dst;
151         unsigned short src_bidx, dst_bidx;
152         unsigned short src_cidx, dst_cidx;
153         unsigned int data_type;
154         unsigned short acnt;
155         unsigned int count;
156         unsigned int fifo_level;
157 
158         period_size = snd_pcm_lib_period_bytes(substream);
159         dma_offset = prtd->period * period_size;
160         dma_pos = runtime->dma_addr + dma_offset;
161         fifo_level = prtd->params->fifo_level;
162 
163         pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
164                 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
165                 period_size);
166 
167         data_type = prtd->params->data_type;
168         count = period_size / data_type;
169         if (fifo_level)
170                 count /= fifo_level;
171 
172         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
173                 src = dma_pos;
174                 dst = prtd->params->dma_addr;
175                 src_bidx = data_type;
176                 dst_bidx = 4;
177                 src_cidx = data_type * fifo_level;
178                 dst_cidx = 0;
179         } else {
180                 src = prtd->params->dma_addr;
181                 dst = dma_pos;
182                 src_bidx = 0;
183                 dst_bidx = data_type;
184                 src_cidx = 0;
185                 dst_cidx = data_type * fifo_level;
186         }
187 
188         acnt = prtd->params->acnt;
189         edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
190         edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
191 
192         edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
193         edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
194 
195         if (!fifo_level)
196                 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
197                                                         ASYNC);
198         else
199                 edma_set_transfer_params(prtd->asp_link[0], acnt,
200                                                 fifo_level,
201                                                 count, fifo_level,
202                                                 ABSYNC);
203 }
204 
205 static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
206 {
207         struct snd_pcm_substream *substream = data;
208         struct davinci_runtime_data *prtd = substream->runtime->private_data;
209 
210         print_buf_info(prtd->ram_channel, "i ram_channel");
211         pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
212 
213         if (unlikely(ch_status != EDMA_DMA_COMPLETE))
214                 return;
215 
216         if (snd_pcm_running(substream)) {
217                 spin_lock(&prtd->lock);
218                 if (prtd->ram_channel < 0) {
219                         /* No ping/pong must fix up link dma data*/
220                         davinci_pcm_enqueue_dma(substream);
221                 }
222                 davinci_pcm_period_elapsed(substream);
223                 spin_unlock(&prtd->lock);
224                 snd_pcm_period_elapsed(substream);
225         }
226 }
227 
228 #ifdef CONFIG_GENERIC_ALLOCATOR
229 static int allocate_sram(struct snd_pcm_substream *substream,
230                 struct gen_pool *sram_pool, unsigned size,
231                 struct snd_pcm_hardware *ppcm)
232 {
233         struct snd_dma_buffer *buf = &substream->dma_buffer;
234         struct snd_dma_buffer *iram_dma = NULL;
235         dma_addr_t iram_phys = 0;
236         void *iram_virt = NULL;
237 
238         if (buf->private_data || !size)
239                 return 0;
240 
241         ppcm->period_bytes_max = size;
242         iram_virt = gen_pool_dma_alloc(sram_pool, size, &iram_phys);
243         if (!iram_virt)
244                 goto exit1;
245         iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
246         if (!iram_dma)
247                 goto exit2;
248         iram_dma->area = iram_virt;
249         iram_dma->addr = iram_phys;
250         memset(iram_dma->area, 0, size);
251         iram_dma->bytes = size;
252         buf->private_data = iram_dma;
253         return 0;
254 exit2:
255         if (iram_virt)
256                 gen_pool_free(sram_pool, (unsigned)iram_virt, size);
257 exit1:
258         return -ENOMEM;
259 }
260 
261 static void davinci_free_sram(struct snd_pcm_substream *substream,
262                               struct snd_dma_buffer *iram_dma)
263 {
264         struct davinci_runtime_data *prtd = substream->runtime->private_data;
265         struct gen_pool *sram_pool = prtd->params->sram_pool;
266 
267         gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes);
268 }
269 #else
270 static int allocate_sram(struct snd_pcm_substream *substream,
271                 struct gen_pool *sram_pool, unsigned size,
272                 struct snd_pcm_hardware *ppcm)
273 {
274         return 0;
275 }
276 
277 static void davinci_free_sram(struct snd_pcm_substream *substream,
278                               struct snd_dma_buffer *iram_dma)
279 {
280 }
281 #endif
282 
283 /*
284  * Only used with ping/pong.
285  * This is called after runtime->dma_addr, period_bytes and data_type are valid
286  */
287 static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
288 {
289         unsigned short ram_src_cidx, ram_dst_cidx;
290         struct snd_pcm_runtime *runtime = substream->runtime;
291         struct davinci_runtime_data *prtd = runtime->private_data;
292         struct snd_dma_buffer *iram_dma =
293                 (struct snd_dma_buffer *)substream->dma_buffer.private_data;
294         struct davinci_pcm_dma_params *params = prtd->params;
295         unsigned int data_type = params->data_type;
296         unsigned int acnt = params->acnt;
297         /* divide by 2 for ping/pong */
298         unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
299         unsigned int fifo_level = prtd->params->fifo_level;
300         unsigned int count;
301         if ((data_type == 0) || (data_type > 4)) {
302                 printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
303                 return -EINVAL;
304         }
305         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
306                 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
307                 ram_src_cidx = ping_size;
308                 ram_dst_cidx = -ping_size;
309                 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
310 
311                 edma_set_src_index(prtd->asp_link[0], data_type,
312                                 data_type * fifo_level);
313                 edma_set_src_index(prtd->asp_link[1], data_type,
314                                 data_type * fifo_level);
315 
316                 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
317         } else {
318                 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
319                 ram_src_cidx = -ping_size;
320                 ram_dst_cidx = ping_size;
321                 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
322 
323                 edma_set_dest_index(prtd->asp_link[0], data_type,
324                                 data_type * fifo_level);
325                 edma_set_dest_index(prtd->asp_link[1], data_type,
326                                 data_type * fifo_level);
327 
328                 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
329         }
330 
331         if (!fifo_level) {
332                 count = ping_size / data_type;
333                 edma_set_transfer_params(prtd->asp_link[0], acnt, count,
334                                 1, 0, ASYNC);
335                 edma_set_transfer_params(prtd->asp_link[1], acnt, count,
336                                 1, 0, ASYNC);
337         } else {
338                 count = ping_size / (data_type * fifo_level);
339                 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
340                                 count, fifo_level, ABSYNC);
341                 edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
342                                 count, fifo_level, ABSYNC);
343         }
344 
345         edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
346         edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
347         edma_set_transfer_params(prtd->ram_link, ping_size, 2,
348                         runtime->periods, 2, ASYNC);
349 
350         /* init master params */
351         edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
352         edma_read_slot(prtd->ram_link, &prtd->ram_params);
353         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
354                 struct edmacc_param p_ram;
355                 /* Copy entire iram buffer before playback started */
356                 prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
357                 /* 0 dst_bidx */
358                 prtd->ram_params.src_dst_bidx = (ping_size << 1);
359                 /* 0 dst_cidx */
360                 prtd->ram_params.src_dst_cidx = (ping_size << 1);
361                 prtd->ram_params.ccnt = 1;
362 
363                 /* Skip 1st period */
364                 edma_read_slot(prtd->ram_link, &p_ram);
365                 p_ram.src += (ping_size << 1);
366                 p_ram.ccnt -= 1;
367                 edma_write_slot(prtd->ram_link2, &p_ram);
368                 /*
369                  * When 1st started, ram -> iram dma channel will fill the
370                  * entire iram.  Then, whenever a ping/pong asp buffer finishes,
371                  * 1/2 iram will be filled.
372                  */
373                 prtd->ram_params.link_bcntrld =
374                         EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
375         }
376         return 0;
377 }
378 
379 /* 1 asp tx or rx channel using 2 parameter channels
380  * 1 ram to/from iram channel using 1 parameter channel
381  *
382  * Playback
383  * ram copy channel kicks off first,
384  * 1st ram copy of entire iram buffer completion kicks off asp channel
385  * asp tcc always kicks off ram copy of 1/2 iram buffer
386  *
387  * Record
388  * asp channel starts, tcc kicks off ram copy
389  */
390 static int request_ping_pong(struct snd_pcm_substream *substream,
391                 struct davinci_runtime_data *prtd,
392                 struct snd_dma_buffer *iram_dma)
393 {
394         dma_addr_t asp_src_ping;
395         dma_addr_t asp_dst_ping;
396         int ret;
397         struct davinci_pcm_dma_params *params = prtd->params;
398 
399         /* Request ram master channel */
400         ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
401                                   davinci_pcm_dma_irq, substream,
402                                   prtd->params->ram_chan_q);
403         if (ret < 0)
404                 goto exit1;
405 
406         /* Request ram link channel */
407         ret = prtd->ram_link = edma_alloc_slot(
408                         EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
409         if (ret < 0)
410                 goto exit2;
411 
412         ret = prtd->asp_link[1] = edma_alloc_slot(
413                         EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
414         if (ret < 0)
415                 goto exit3;
416 
417         prtd->ram_link2 = -1;
418         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
419                 ret = prtd->ram_link2 = edma_alloc_slot(
420                         EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
421                 if (ret < 0)
422                         goto exit4;
423         }
424         /* circle ping-pong buffers */
425         edma_link(prtd->asp_link[0], prtd->asp_link[1]);
426         edma_link(prtd->asp_link[1], prtd->asp_link[0]);
427         /* circle ram buffers */
428         edma_link(prtd->ram_link, prtd->ram_link);
429 
430         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
431                 asp_src_ping = iram_dma->addr;
432                 asp_dst_ping = params->dma_addr;        /* fifo */
433         } else {
434                 asp_src_ping = params->dma_addr;        /* fifo */
435                 asp_dst_ping = iram_dma->addr;
436         }
437         /* ping */
438         edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
439         edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
440         edma_set_src_index(prtd->asp_link[0], 0, 0);
441         edma_set_dest_index(prtd->asp_link[0], 0, 0);
442 
443         edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
444         prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
445         prtd->asp_params.opt |= TCCHEN |
446                 EDMA_TCC(prtd->ram_channel & 0x3f);
447         edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
448 
449         /* pong */
450         edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
451         edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
452         edma_set_src_index(prtd->asp_link[1], 0, 0);
453         edma_set_dest_index(prtd->asp_link[1], 0, 0);
454 
455         edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
456         prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
457         /* interrupt after every pong completion */
458         prtd->asp_params.opt |= TCINTEN | TCCHEN |
459                 EDMA_TCC(prtd->ram_channel & 0x3f);
460         edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
461 
462         /* ram */
463         edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
464         edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
465         pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
466                 "for asp:%u %u %u\n", __func__,
467                 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
468                 prtd->asp_channel, prtd->asp_link[0],
469                 prtd->asp_link[1]);
470         return 0;
471 exit4:
472         edma_free_channel(prtd->asp_link[1]);
473         prtd->asp_link[1] = -1;
474 exit3:
475         edma_free_channel(prtd->ram_link);
476         prtd->ram_link = -1;
477 exit2:
478         edma_free_channel(prtd->ram_channel);
479         prtd->ram_channel = -1;
480 exit1:
481         return ret;
482 }
483 
484 static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
485 {
486         struct snd_dma_buffer *iram_dma;
487         struct davinci_runtime_data *prtd = substream->runtime->private_data;
488         struct davinci_pcm_dma_params *params = prtd->params;
489         int ret;
490 
491         if (!params)
492                 return -ENODEV;
493 
494         /* Request asp master DMA channel */
495         ret = prtd->asp_channel = edma_alloc_channel(params->channel,
496                         davinci_pcm_dma_irq, substream,
497                         prtd->params->asp_chan_q);
498         if (ret < 0)
499                 goto exit1;
500 
501         /* Request asp link channels */
502         ret = prtd->asp_link[0] = edma_alloc_slot(
503                         EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
504         if (ret < 0)
505                 goto exit2;
506 
507         iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
508         if (iram_dma) {
509                 if (request_ping_pong(substream, prtd, iram_dma) == 0)
510                         return 0;
511                 printk(KERN_WARNING "%s: dma channel allocation failed,"
512                                 "not using sram\n", __func__);
513         }
514 
515         /* Issue transfer completion IRQ when the channel completes a
516          * transfer, then always reload from the same slot (by a kind
517          * of loopback link).  The completion IRQ handler will update
518          * the reload slot with a new buffer.
519          *
520          * REVISIT save p_ram here after setting up everything except
521          * the buffer and its length (ccnt) ... use it as a template
522          * so davinci_pcm_enqueue_dma() takes less time in IRQ.
523          */
524         edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
525         prtd->asp_params.opt |= TCINTEN |
526                 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
527         prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
528         edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
529         return 0;
530 exit2:
531         edma_free_channel(prtd->asp_channel);
532         prtd->asp_channel = -1;
533 exit1:
534         return ret;
535 }
536 
537 static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
538 {
539         struct davinci_runtime_data *prtd = substream->runtime->private_data;
540         int ret = 0;
541 
542         spin_lock(&prtd->lock);
543 
544         switch (cmd) {
545         case SNDRV_PCM_TRIGGER_START:
546                 edma_start(prtd->asp_channel);
547                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
548                     prtd->ram_channel >= 0) {
549                         /* copy 1st iram buffer */
550                         edma_start(prtd->ram_channel);
551                 }
552                 break;
553         case SNDRV_PCM_TRIGGER_RESUME:
554         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
555                 edma_resume(prtd->asp_channel);
556                 break;
557         case SNDRV_PCM_TRIGGER_STOP:
558         case SNDRV_PCM_TRIGGER_SUSPEND:
559         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
560                 edma_pause(prtd->asp_channel);
561                 break;
562         default:
563                 ret = -EINVAL;
564                 break;
565         }
566 
567         spin_unlock(&prtd->lock);
568 
569         return ret;
570 }
571 
572 static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
573 {
574         struct davinci_runtime_data *prtd = substream->runtime->private_data;
575 
576         davinci_pcm_period_reset(substream);
577         if (prtd->ram_channel >= 0) {
578                 int ret = ping_pong_dma_setup(substream);
579                 if (ret < 0)
580                         return ret;
581 
582                 edma_write_slot(prtd->ram_channel, &prtd->ram_params);
583                 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
584 
585                 print_buf_info(prtd->ram_channel, "ram_channel");
586                 print_buf_info(prtd->ram_link, "ram_link");
587                 print_buf_info(prtd->ram_link2, "ram_link2");
588                 print_buf_info(prtd->asp_channel, "asp_channel");
589                 print_buf_info(prtd->asp_link[0], "asp_link[0]");
590                 print_buf_info(prtd->asp_link[1], "asp_link[1]");
591 
592                 /*
593                  * There is a phase offset of 2 periods between the position
594                  * used by dma setup and the position reported in the pointer
595                  * function.
596                  *
597                  * The phase offset, when not using ping-pong buffers, is due to
598                  * the two consecutive calls to davinci_pcm_enqueue_dma() below.
599                  *
600                  * Whereas here, with ping-pong buffers, the phase is due to
601                  * there being an entire buffer transfer complete before the
602                  * first dma completion event triggers davinci_pcm_dma_irq().
603                  */
604                 davinci_pcm_period_elapsed(substream);
605                 davinci_pcm_period_elapsed(substream);
606 
607                 return 0;
608         }
609         davinci_pcm_enqueue_dma(substream);
610         davinci_pcm_period_elapsed(substream);
611 
612         /* Copy self-linked parameter RAM entry into master channel */
613         edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
614         edma_write_slot(prtd->asp_channel, &prtd->asp_params);
615         davinci_pcm_enqueue_dma(substream);
616         davinci_pcm_period_elapsed(substream);
617 
618         return 0;
619 }
620 
621 static snd_pcm_uframes_t
622 davinci_pcm_pointer(struct snd_pcm_substream *substream)
623 {
624         struct snd_pcm_runtime *runtime = substream->runtime;
625         struct davinci_runtime_data *prtd = runtime->private_data;
626         unsigned int offset;
627         int asp_count;
628         unsigned int period_size = snd_pcm_lib_period_bytes(substream);
629 
630         /*
631          * There is a phase offset of 2 periods between the position used by dma
632          * setup and the position reported in the pointer function. Either +2 in
633          * the dma setup or -2 here in the pointer function (with wrapping,
634          * both) accounts for this offset -- choose the latter since it makes
635          * the first-time setup clearer.
636          */
637         spin_lock(&prtd->lock);
638         asp_count = prtd->period - 2;
639         spin_unlock(&prtd->lock);
640 
641         if (asp_count < 0)
642                 asp_count += runtime->periods;
643         asp_count *= period_size;
644 
645         offset = bytes_to_frames(runtime, asp_count);
646         if (offset >= runtime->buffer_size)
647                 offset = 0;
648 
649         return offset;
650 }
651 
652 static int davinci_pcm_open(struct snd_pcm_substream *substream)
653 {
654         struct snd_pcm_runtime *runtime = substream->runtime;
655         struct davinci_runtime_data *prtd;
656         struct snd_pcm_hardware *ppcm;
657         int ret = 0;
658         struct snd_soc_pcm_runtime *rtd = substream->private_data;
659         struct davinci_pcm_dma_params *pa;
660         struct davinci_pcm_dma_params *params;
661 
662         pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
663         if (!pa)
664                 return -ENODEV;
665         params = &pa[substream->stream];
666 
667         ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
668                         &pcm_hardware_playback : &pcm_hardware_capture;
669         allocate_sram(substream, params->sram_pool, params->sram_size, ppcm);
670         snd_soc_set_runtime_hwparams(substream, ppcm);
671         /* ensure that buffer size is a multiple of period size */
672         ret = snd_pcm_hw_constraint_integer(runtime,
673                                                 SNDRV_PCM_HW_PARAM_PERIODS);
674         if (ret < 0)
675                 return ret;
676 
677         prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
678         if (prtd == NULL)
679                 return -ENOMEM;
680 
681         spin_lock_init(&prtd->lock);
682         prtd->params = params;
683         prtd->asp_channel = -1;
684         prtd->asp_link[0] = prtd->asp_link[1] = -1;
685         prtd->ram_channel = -1;
686         prtd->ram_link = -1;
687         prtd->ram_link2 = -1;
688 
689         runtime->private_data = prtd;
690 
691         ret = davinci_pcm_dma_request(substream);
692         if (ret) {
693                 printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n");
694                 kfree(prtd);
695         }
696 
697         return ret;
698 }
699 
700 static int davinci_pcm_close(struct snd_pcm_substream *substream)
701 {
702         struct snd_pcm_runtime *runtime = substream->runtime;
703         struct davinci_runtime_data *prtd = runtime->private_data;
704 
705         if (prtd->ram_channel >= 0)
706                 edma_stop(prtd->ram_channel);
707         if (prtd->asp_channel >= 0)
708                 edma_stop(prtd->asp_channel);
709         if (prtd->asp_link[0] >= 0)
710                 edma_unlink(prtd->asp_link[0]);
711         if (prtd->asp_link[1] >= 0)
712                 edma_unlink(prtd->asp_link[1]);
713         if (prtd->ram_link >= 0)
714                 edma_unlink(prtd->ram_link);
715 
716         if (prtd->asp_link[0] >= 0)
717                 edma_free_slot(prtd->asp_link[0]);
718         if (prtd->asp_link[1] >= 0)
719                 edma_free_slot(prtd->asp_link[1]);
720         if (prtd->asp_channel >= 0)
721                 edma_free_channel(prtd->asp_channel);
722         if (prtd->ram_link >= 0)
723                 edma_free_slot(prtd->ram_link);
724         if (prtd->ram_link2 >= 0)
725                 edma_free_slot(prtd->ram_link2);
726         if (prtd->ram_channel >= 0)
727                 edma_free_channel(prtd->ram_channel);
728 
729         kfree(prtd);
730 
731         return 0;
732 }
733 
734 static int davinci_pcm_hw_params(struct snd_pcm_substream *substream,
735                                  struct snd_pcm_hw_params *hw_params)
736 {
737         return snd_pcm_lib_malloc_pages(substream,
738                                         params_buffer_bytes(hw_params));
739 }
740 
741 static int davinci_pcm_hw_free(struct snd_pcm_substream *substream)
742 {
743         return snd_pcm_lib_free_pages(substream);
744 }
745 
746 static int davinci_pcm_mmap(struct snd_pcm_substream *substream,
747                             struct vm_area_struct *vma)
748 {
749         struct snd_pcm_runtime *runtime = substream->runtime;
750 
751         return dma_mmap_writecombine(substream->pcm->card->dev, vma,
752                                      runtime->dma_area,
753                                      runtime->dma_addr,
754                                      runtime->dma_bytes);
755 }
756 
757 static struct snd_pcm_ops davinci_pcm_ops = {
758         .open =         davinci_pcm_open,
759         .close =        davinci_pcm_close,
760         .ioctl =        snd_pcm_lib_ioctl,
761         .hw_params =    davinci_pcm_hw_params,
762         .hw_free =      davinci_pcm_hw_free,
763         .prepare =      davinci_pcm_prepare,
764         .trigger =      davinci_pcm_trigger,
765         .pointer =      davinci_pcm_pointer,
766         .mmap =         davinci_pcm_mmap,
767 };
768 
769 static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
770                 size_t size)
771 {
772         struct snd_pcm_substream *substream = pcm->streams[stream].substream;
773         struct snd_dma_buffer *buf = &substream->dma_buffer;
774 
775         buf->dev.type = SNDRV_DMA_TYPE_DEV;
776         buf->dev.dev = pcm->card->dev;
777         buf->private_data = NULL;
778         buf->area = dma_alloc_writecombine(pcm->card->dev, size,
779                                            &buf->addr, GFP_KERNEL);
780 
781         pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
782                 "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
783 
784         if (!buf->area)
785                 return -ENOMEM;
786 
787         buf->bytes = size;
788         return 0;
789 }
790 
791 static void davinci_pcm_free(struct snd_pcm *pcm)
792 {
793         struct snd_pcm_substream *substream;
794         struct snd_dma_buffer *buf;
795         int stream;
796 
797         for (stream = 0; stream < 2; stream++) {
798                 struct snd_dma_buffer *iram_dma;
799                 substream = pcm->streams[stream].substream;
800                 if (!substream)
801                         continue;
802 
803                 buf = &substream->dma_buffer;
804                 if (!buf->area)
805                         continue;
806 
807                 dma_free_writecombine(pcm->card->dev, buf->bytes,
808                                       buf->area, buf->addr);
809                 buf->area = NULL;
810                 iram_dma = buf->private_data;
811                 if (iram_dma) {
812                         davinci_free_sram(substream, iram_dma);
813                         kfree(iram_dma);
814                 }
815         }
816 }
817 
818 static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
819 {
820         struct snd_card *card = rtd->card->snd_card;
821         struct snd_pcm *pcm = rtd->pcm;
822         int ret;
823 
824         ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
825         if (ret)
826                 return ret;
827 
828         if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
829                 ret = davinci_pcm_preallocate_dma_buffer(pcm,
830                         SNDRV_PCM_STREAM_PLAYBACK,
831                         pcm_hardware_playback.buffer_bytes_max);
832                 if (ret)
833                         return ret;
834         }
835 
836         if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
837                 ret = davinci_pcm_preallocate_dma_buffer(pcm,
838                         SNDRV_PCM_STREAM_CAPTURE,
839                         pcm_hardware_capture.buffer_bytes_max);
840                 if (ret)
841                         return ret;
842         }
843 
844         return 0;
845 }
846 
847 static struct snd_soc_platform_driver davinci_soc_platform = {
848         .ops =          &davinci_pcm_ops,
849         .pcm_new =      davinci_pcm_new,
850         .pcm_free =     davinci_pcm_free,
851 };
852 
853 int davinci_soc_platform_register(struct device *dev)
854 {
855         return snd_soc_register_platform(dev, &davinci_soc_platform);
856 }
857 EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
858 
859 void davinci_soc_platform_unregister(struct device *dev)
860 {
861         snd_soc_unregister_platform(dev);
862 }
863 EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister);
864 
865 MODULE_AUTHOR("Vladimir Barinov");
866 MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
867 MODULE_LICENSE("GPL");
868 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us