1
2
3
4
5
6
7
8
9
10
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
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 <mach/edma.h>
27#include <mach/sram.h>
28
29#include "davinci-pcm.h"
30
31#ifdef DEBUG
32static 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
44static void print_buf_info(int slot, char *name)
45{
46}
47#endif
48
49#define DAVINCI_PCM_FMTBITS (\
50 SNDRV_PCM_FMTBIT_S8 |\
51 SNDRV_PCM_FMTBIT_U8 |\
52 SNDRV_PCM_FMTBIT_S16_LE |\
53 SNDRV_PCM_FMTBIT_S16_BE |\
54 SNDRV_PCM_FMTBIT_U16_LE |\
55 SNDRV_PCM_FMTBIT_U16_BE |\
56 SNDRV_PCM_FMTBIT_S24_LE |\
57 SNDRV_PCM_FMTBIT_S24_BE |\
58 SNDRV_PCM_FMTBIT_U24_LE |\
59 SNDRV_PCM_FMTBIT_U24_BE |\
60 SNDRV_PCM_FMTBIT_S32_LE |\
61 SNDRV_PCM_FMTBIT_S32_BE |\
62 SNDRV_PCM_FMTBIT_U32_LE |\
63 SNDRV_PCM_FMTBIT_U32_BE)
64
65static struct snd_pcm_hardware pcm_hardware_playback = {
66 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
67 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
68 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
69 SNDRV_PCM_INFO_BATCH),
70 .formats = DAVINCI_PCM_FMTBITS,
71 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
72 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
73 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
74 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
75 SNDRV_PCM_RATE_KNOT),
76 .rate_min = 8000,
77 .rate_max = 96000,
78 .channels_min = 2,
79 .channels_max = 384,
80 .buffer_bytes_max = 128 * 1024,
81 .period_bytes_min = 32,
82 .period_bytes_max = 8 * 1024,
83 .periods_min = 16,
84 .periods_max = 255,
85 .fifo_size = 0,
86};
87
88static struct snd_pcm_hardware pcm_hardware_capture = {
89 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
90 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
91 SNDRV_PCM_INFO_PAUSE |
92 SNDRV_PCM_INFO_BATCH),
93 .formats = DAVINCI_PCM_FMTBITS,
94 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
95 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
96 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
97 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
98 SNDRV_PCM_RATE_KNOT),
99 .rate_min = 8000,
100 .rate_max = 96000,
101 .channels_min = 2,
102 .channels_max = 384,
103 .buffer_bytes_max = 128 * 1024,
104 .period_bytes_min = 32,
105 .period_bytes_max = 8 * 1024,
106 .periods_min = 16,
107 .periods_max = 255,
108 .fifo_size = 0,
109};
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147struct davinci_runtime_data {
148 spinlock_t lock;
149 int period;
150 int asp_channel;
151 int asp_link[2];
152 struct davinci_pcm_dma_params *params;
153 int ram_channel;
154 int ram_link;
155 int ram_link2;
156 struct edmacc_param asp_params;
157 struct edmacc_param ram_params;
158};
159
160static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
161{
162 struct davinci_runtime_data *prtd = substream->runtime->private_data;
163 struct snd_pcm_runtime *runtime = substream->runtime;
164
165 prtd->period++;
166 if (unlikely(prtd->period >= runtime->periods))
167 prtd->period = 0;
168}
169
170static void davinci_pcm_period_reset(struct snd_pcm_substream *substream)
171{
172 struct davinci_runtime_data *prtd = substream->runtime->private_data;
173
174 prtd->period = 0;
175}
176
177
178
179static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
180{
181 struct davinci_runtime_data *prtd = substream->runtime->private_data;
182 struct snd_pcm_runtime *runtime = substream->runtime;
183 unsigned int period_size;
184 unsigned int dma_offset;
185 dma_addr_t dma_pos;
186 dma_addr_t src, dst;
187 unsigned short src_bidx, dst_bidx;
188 unsigned short src_cidx, dst_cidx;
189 unsigned int data_type;
190 unsigned short acnt;
191 unsigned int count;
192 unsigned int fifo_level;
193
194 period_size = snd_pcm_lib_period_bytes(substream);
195 dma_offset = prtd->period * period_size;
196 dma_pos = runtime->dma_addr + dma_offset;
197 fifo_level = prtd->params->fifo_level;
198
199 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
200 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
201 period_size);
202
203 data_type = prtd->params->data_type;
204 count = period_size / data_type;
205 if (fifo_level)
206 count /= fifo_level;
207
208 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
209 src = dma_pos;
210 dst = prtd->params->dma_addr;
211 src_bidx = data_type;
212 dst_bidx = 0;
213 src_cidx = data_type * fifo_level;
214 dst_cidx = 0;
215 } else {
216 src = prtd->params->dma_addr;
217 dst = dma_pos;
218 src_bidx = 0;
219 dst_bidx = data_type;
220 src_cidx = 0;
221 dst_cidx = data_type * fifo_level;
222 }
223
224 acnt = prtd->params->acnt;
225 edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
226 edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
227
228 edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
229 edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
230
231 if (!fifo_level)
232 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
233 ASYNC);
234 else
235 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
236 count, fifo_level,
237 ABSYNC);
238}
239
240static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
241{
242 struct snd_pcm_substream *substream = data;
243 struct davinci_runtime_data *prtd = substream->runtime->private_data;
244
245 print_buf_info(prtd->ram_channel, "i ram_channel");
246 pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
247
248 if (unlikely(ch_status != DMA_COMPLETE))
249 return;
250
251 if (snd_pcm_running(substream)) {
252 spin_lock(&prtd->lock);
253 if (prtd->ram_channel < 0) {
254
255 davinci_pcm_enqueue_dma(substream);
256 }
257 davinci_pcm_period_elapsed(substream);
258 spin_unlock(&prtd->lock);
259 snd_pcm_period_elapsed(substream);
260 }
261}
262
263static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
264 struct snd_pcm_hardware *ppcm)
265{
266 struct snd_dma_buffer *buf = &substream->dma_buffer;
267 struct snd_dma_buffer *iram_dma = NULL;
268 dma_addr_t iram_phys = 0;
269 void *iram_virt = NULL;
270
271 if (buf->private_data || !size)
272 return 0;
273
274 ppcm->period_bytes_max = size;
275 iram_virt = sram_alloc(size, &iram_phys);
276 if (!iram_virt)
277 goto exit1;
278 iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
279 if (!iram_dma)
280 goto exit2;
281 iram_dma->area = iram_virt;
282 iram_dma->addr = iram_phys;
283 memset(iram_dma->area, 0, size);
284 iram_dma->bytes = size;
285 buf->private_data = iram_dma;
286 return 0;
287exit2:
288 if (iram_virt)
289 sram_free(iram_virt, size);
290exit1:
291 return -ENOMEM;
292}
293
294
295
296
297
298static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
299{
300 unsigned short ram_src_cidx, ram_dst_cidx;
301 struct snd_pcm_runtime *runtime = substream->runtime;
302 struct davinci_runtime_data *prtd = runtime->private_data;
303 struct snd_dma_buffer *iram_dma =
304 (struct snd_dma_buffer *)substream->dma_buffer.private_data;
305 struct davinci_pcm_dma_params *params = prtd->params;
306 unsigned int data_type = params->data_type;
307 unsigned int acnt = params->acnt;
308
309 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
310 unsigned int fifo_level = prtd->params->fifo_level;
311 unsigned int count;
312 if ((data_type == 0) || (data_type > 4)) {
313 printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
314 return -EINVAL;
315 }
316 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
317 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
318 ram_src_cidx = ping_size;
319 ram_dst_cidx = -ping_size;
320 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
321
322 edma_set_src_index(prtd->asp_link[0], data_type,
323 data_type * fifo_level);
324 edma_set_src_index(prtd->asp_link[1], data_type,
325 data_type * fifo_level);
326
327 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
328 } else {
329 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
330 ram_src_cidx = -ping_size;
331 ram_dst_cidx = ping_size;
332 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
333
334 edma_set_dest_index(prtd->asp_link[0], data_type,
335 data_type * fifo_level);
336 edma_set_dest_index(prtd->asp_link[1], data_type,
337 data_type * fifo_level);
338
339 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
340 }
341
342 if (!fifo_level) {
343 count = ping_size / data_type;
344 edma_set_transfer_params(prtd->asp_link[0], acnt, count,
345 1, 0, ASYNC);
346 edma_set_transfer_params(prtd->asp_link[1], acnt, count,
347 1, 0, ASYNC);
348 } else {
349 count = ping_size / (data_type * fifo_level);
350 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
351 count, fifo_level, ABSYNC);
352 edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
353 count, fifo_level, ABSYNC);
354 }
355
356 edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
357 edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
358 edma_set_transfer_params(prtd->ram_link, ping_size, 2,
359 runtime->periods, 2, ASYNC);
360
361
362 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
363 edma_read_slot(prtd->ram_link, &prtd->ram_params);
364 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
365 struct edmacc_param p_ram;
366
367 prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
368
369 prtd->ram_params.src_dst_bidx = (ping_size << 1);
370
371 prtd->ram_params.src_dst_cidx = (ping_size << 1);
372 prtd->ram_params.ccnt = 1;
373
374
375 edma_read_slot(prtd->ram_link, &p_ram);
376 p_ram.src += (ping_size << 1);
377 p_ram.ccnt -= 1;
378 edma_write_slot(prtd->ram_link2, &p_ram);
379
380
381
382
383
384 prtd->ram_params.link_bcntrld =
385 EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
386 }
387 return 0;
388}
389
390
391
392
393
394
395
396
397
398
399
400
401static int request_ping_pong(struct snd_pcm_substream *substream,
402 struct davinci_runtime_data *prtd,
403 struct snd_dma_buffer *iram_dma)
404{
405 dma_addr_t asp_src_ping;
406 dma_addr_t asp_dst_ping;
407 int ret;
408 struct davinci_pcm_dma_params *params = prtd->params;
409
410
411 ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
412 davinci_pcm_dma_irq, substream,
413 prtd->params->ram_chan_q);
414 if (ret < 0)
415 goto exit1;
416
417
418 ret = prtd->ram_link = edma_alloc_slot(
419 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
420 if (ret < 0)
421 goto exit2;
422
423 ret = prtd->asp_link[1] = edma_alloc_slot(
424 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
425 if (ret < 0)
426 goto exit3;
427
428 prtd->ram_link2 = -1;
429 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
430 ret = prtd->ram_link2 = edma_alloc_slot(
431 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
432 if (ret < 0)
433 goto exit4;
434 }
435
436 edma_link(prtd->asp_link[0], prtd->asp_link[1]);
437 edma_link(prtd->asp_link[1], prtd->asp_link[0]);
438
439 edma_link(prtd->ram_link, prtd->ram_link);
440
441 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
442 asp_src_ping = iram_dma->addr;
443 asp_dst_ping = params->dma_addr;
444 } else {
445 asp_src_ping = params->dma_addr;
446 asp_dst_ping = iram_dma->addr;
447 }
448
449 edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
450 edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
451 edma_set_src_index(prtd->asp_link[0], 0, 0);
452 edma_set_dest_index(prtd->asp_link[0], 0, 0);
453
454 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
455 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
456 prtd->asp_params.opt |= TCCHEN |
457 EDMA_TCC(prtd->ram_channel & 0x3f);
458 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
459
460
461 edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
462 edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
463 edma_set_src_index(prtd->asp_link[1], 0, 0);
464 edma_set_dest_index(prtd->asp_link[1], 0, 0);
465
466 edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
467 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
468
469 prtd->asp_params.opt |= TCINTEN | TCCHEN |
470 EDMA_TCC(prtd->ram_channel & 0x3f);
471 edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
472
473
474 edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
475 edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
476 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
477 "for asp:%u %u %u\n", __func__,
478 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
479 prtd->asp_channel, prtd->asp_link[0],
480 prtd->asp_link[1]);
481 return 0;
482exit4:
483 edma_free_channel(prtd->asp_link[1]);
484 prtd->asp_link[1] = -1;
485exit3:
486 edma_free_channel(prtd->ram_link);
487 prtd->ram_link = -1;
488exit2:
489 edma_free_channel(prtd->ram_channel);
490 prtd->ram_channel = -1;
491exit1:
492 return ret;
493}
494
495static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
496{
497 struct snd_dma_buffer *iram_dma;
498 struct davinci_runtime_data *prtd = substream->runtime->private_data;
499 struct davinci_pcm_dma_params *params = prtd->params;
500 int ret;
501
502 if (!params)
503 return -ENODEV;
504
505
506 ret = prtd->asp_channel = edma_alloc_channel(params->channel,
507 davinci_pcm_dma_irq, substream,
508 prtd->params->asp_chan_q);
509 if (ret < 0)
510 goto exit1;
511
512
513 ret = prtd->asp_link[0] = edma_alloc_slot(
514 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
515 if (ret < 0)
516 goto exit2;
517
518 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
519 if (iram_dma) {
520 if (request_ping_pong(substream, prtd, iram_dma) == 0)
521 return 0;
522 printk(KERN_WARNING "%s: dma channel allocation failed,"
523 "not using sram\n", __func__);
524 }
525
526
527
528
529
530
531
532
533
534
535 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
536 prtd->asp_params.opt |= TCINTEN |
537 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
538 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
539 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
540 return 0;
541exit2:
542 edma_free_channel(prtd->asp_channel);
543 prtd->asp_channel = -1;
544exit1:
545 return ret;
546}
547
548static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
549{
550 struct davinci_runtime_data *prtd = substream->runtime->private_data;
551 int ret = 0;
552
553 spin_lock(&prtd->lock);
554
555 switch (cmd) {
556 case SNDRV_PCM_TRIGGER_START:
557 edma_start(prtd->asp_channel);
558 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
559 prtd->ram_channel >= 0) {
560
561 edma_start(prtd->ram_channel);
562 }
563 break;
564 case SNDRV_PCM_TRIGGER_RESUME:
565 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
566 edma_resume(prtd->asp_channel);
567 break;
568 case SNDRV_PCM_TRIGGER_STOP:
569 case SNDRV_PCM_TRIGGER_SUSPEND:
570 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
571 edma_pause(prtd->asp_channel);
572 break;
573 default:
574 ret = -EINVAL;
575 break;
576 }
577
578 spin_unlock(&prtd->lock);
579
580 return ret;
581}
582
583static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
584{
585 struct davinci_runtime_data *prtd = substream->runtime->private_data;
586
587 davinci_pcm_period_reset(substream);
588 if (prtd->ram_channel >= 0) {
589 int ret = ping_pong_dma_setup(substream);
590 if (ret < 0)
591 return ret;
592
593 edma_write_slot(prtd->ram_channel, &prtd->ram_params);
594 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
595
596 print_buf_info(prtd->ram_channel, "ram_channel");
597 print_buf_info(prtd->ram_link, "ram_link");
598 print_buf_info(prtd->ram_link2, "ram_link2");
599 print_buf_info(prtd->asp_channel, "asp_channel");
600 print_buf_info(prtd->asp_link[0], "asp_link[0]");
601 print_buf_info(prtd->asp_link[1], "asp_link[1]");
602
603
604
605
606
607
608
609
610
611
612
613
614
615 davinci_pcm_period_elapsed(substream);
616 davinci_pcm_period_elapsed(substream);
617
618 return 0;
619 }
620 davinci_pcm_enqueue_dma(substream);
621 davinci_pcm_period_elapsed(substream);
622
623
624 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
625 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
626 davinci_pcm_enqueue_dma(substream);
627 davinci_pcm_period_elapsed(substream);
628
629 return 0;
630}
631
632static snd_pcm_uframes_t
633davinci_pcm_pointer(struct snd_pcm_substream *substream)
634{
635 struct snd_pcm_runtime *runtime = substream->runtime;
636 struct davinci_runtime_data *prtd = runtime->private_data;
637 unsigned int offset;
638 int asp_count;
639 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
640
641
642
643
644
645
646
647
648 spin_lock(&prtd->lock);
649 asp_count = prtd->period - 2;
650 spin_unlock(&prtd->lock);
651
652 if (asp_count < 0)
653 asp_count += runtime->periods;
654 asp_count *= period_size;
655
656 offset = bytes_to_frames(runtime, asp_count);
657 if (offset >= runtime->buffer_size)
658 offset = 0;
659
660 return offset;
661}
662
663static int davinci_pcm_open(struct snd_pcm_substream *substream)
664{
665 struct snd_pcm_runtime *runtime = substream->runtime;
666 struct davinci_runtime_data *prtd;
667 struct snd_pcm_hardware *ppcm;
668 int ret = 0;
669 struct snd_soc_pcm_runtime *rtd = substream->private_data;
670 struct davinci_pcm_dma_params *pa;
671 struct davinci_pcm_dma_params *params;
672
673 pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
674 if (!pa)
675 return -ENODEV;
676 params = &pa[substream->stream];
677
678 ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
679 &pcm_hardware_playback : &pcm_hardware_capture;
680 allocate_sram(substream, params->sram_size, ppcm);
681 snd_soc_set_runtime_hwparams(substream, ppcm);
682
683 ret = snd_pcm_hw_constraint_integer(runtime,
684 SNDRV_PCM_HW_PARAM_PERIODS);
685 if (ret < 0)
686 return ret;
687
688 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
689 if (prtd == NULL)
690 return -ENOMEM;
691
692 spin_lock_init(&prtd->lock);
693 prtd->params = params;
694 prtd->asp_channel = -1;
695 prtd->asp_link[0] = prtd->asp_link[1] = -1;
696 prtd->ram_channel = -1;
697 prtd->ram_link = -1;
698 prtd->ram_link2 = -1;
699
700 runtime->private_data = prtd;
701
702 ret = davinci_pcm_dma_request(substream);
703 if (ret) {
704 printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n");
705 kfree(prtd);
706 }
707
708 return ret;
709}
710
711static int davinci_pcm_close(struct snd_pcm_substream *substream)
712{
713 struct snd_pcm_runtime *runtime = substream->runtime;
714 struct davinci_runtime_data *prtd = runtime->private_data;
715
716 if (prtd->ram_channel >= 0)
717 edma_stop(prtd->ram_channel);
718 if (prtd->asp_channel >= 0)
719 edma_stop(prtd->asp_channel);
720 if (prtd->asp_link[0] >= 0)
721 edma_unlink(prtd->asp_link[0]);
722 if (prtd->asp_link[1] >= 0)
723 edma_unlink(prtd->asp_link[1]);
724 if (prtd->ram_link >= 0)
725 edma_unlink(prtd->ram_link);
726
727 if (prtd->asp_link[0] >= 0)
728 edma_free_slot(prtd->asp_link[0]);
729 if (prtd->asp_link[1] >= 0)
730 edma_free_slot(prtd->asp_link[1]);
731 if (prtd->asp_channel >= 0)
732 edma_free_channel(prtd->asp_channel);
733 if (prtd->ram_link >= 0)
734 edma_free_slot(prtd->ram_link);
735 if (prtd->ram_link2 >= 0)
736 edma_free_slot(prtd->ram_link2);
737 if (prtd->ram_channel >= 0)
738 edma_free_channel(prtd->ram_channel);
739
740 kfree(prtd);
741
742 return 0;
743}
744
745static int davinci_pcm_hw_params(struct snd_pcm_substream *substream,
746 struct snd_pcm_hw_params *hw_params)
747{
748 return snd_pcm_lib_malloc_pages(substream,
749 params_buffer_bytes(hw_params));
750}
751
752static int davinci_pcm_hw_free(struct snd_pcm_substream *substream)
753{
754 return snd_pcm_lib_free_pages(substream);
755}
756
757static int davinci_pcm_mmap(struct snd_pcm_substream *substream,
758 struct vm_area_struct *vma)
759{
760 struct snd_pcm_runtime *runtime = substream->runtime;
761
762 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
763 runtime->dma_area,
764 runtime->dma_addr,
765 runtime->dma_bytes);
766}
767
768static struct snd_pcm_ops davinci_pcm_ops = {
769 .open = davinci_pcm_open,
770 .close = davinci_pcm_close,
771 .ioctl = snd_pcm_lib_ioctl,
772 .hw_params = davinci_pcm_hw_params,
773 .hw_free = davinci_pcm_hw_free,
774 .prepare = davinci_pcm_prepare,
775 .trigger = davinci_pcm_trigger,
776 .pointer = davinci_pcm_pointer,
777 .mmap = davinci_pcm_mmap,
778};
779
780static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
781 size_t size)
782{
783 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
784 struct snd_dma_buffer *buf = &substream->dma_buffer;
785
786 buf->dev.type = SNDRV_DMA_TYPE_DEV;
787 buf->dev.dev = pcm->card->dev;
788 buf->private_data = NULL;
789 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
790 &buf->addr, GFP_KERNEL);
791
792 pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
793 "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
794
795 if (!buf->area)
796 return -ENOMEM;
797
798 buf->bytes = size;
799 return 0;
800}
801
802static void davinci_pcm_free(struct snd_pcm *pcm)
803{
804 struct snd_pcm_substream *substream;
805 struct snd_dma_buffer *buf;
806 int stream;
807
808 for (stream = 0; stream < 2; stream++) {
809 struct snd_dma_buffer *iram_dma;
810 substream = pcm->streams[stream].substream;
811 if (!substream)
812 continue;
813
814 buf = &substream->dma_buffer;
815 if (!buf->area)
816 continue;
817
818 dma_free_writecombine(pcm->card->dev, buf->bytes,
819 buf->area, buf->addr);
820 buf->area = NULL;
821 iram_dma = buf->private_data;
822 if (iram_dma) {
823 sram_free(iram_dma->area, iram_dma->bytes);
824 kfree(iram_dma);
825 }
826 }
827}
828
829static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32);
830
831static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
832{
833 struct snd_card *card = rtd->card->snd_card;
834 struct snd_pcm *pcm = rtd->pcm;
835 int ret;
836
837 if (!card->dev->dma_mask)
838 card->dev->dma_mask = &davinci_pcm_dmamask;
839 if (!card->dev->coherent_dma_mask)
840 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
841
842 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
843 ret = davinci_pcm_preallocate_dma_buffer(pcm,
844 SNDRV_PCM_STREAM_PLAYBACK,
845 pcm_hardware_playback.buffer_bytes_max);
846 if (ret)
847 return ret;
848 }
849
850 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
851 ret = davinci_pcm_preallocate_dma_buffer(pcm,
852 SNDRV_PCM_STREAM_CAPTURE,
853 pcm_hardware_capture.buffer_bytes_max);
854 if (ret)
855 return ret;
856 }
857
858 return 0;
859}
860
861static struct snd_soc_platform_driver davinci_soc_platform = {
862 .ops = &davinci_pcm_ops,
863 .pcm_new = davinci_pcm_new,
864 .pcm_free = davinci_pcm_free,
865};
866
867static int __devinit davinci_soc_platform_probe(struct platform_device *pdev)
868{
869 return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform);
870}
871
872static int __devexit davinci_soc_platform_remove(struct platform_device *pdev)
873{
874 snd_soc_unregister_platform(&pdev->dev);
875 return 0;
876}
877
878static struct platform_driver davinci_pcm_driver = {
879 .driver = {
880 .name = "davinci-pcm-audio",
881 .owner = THIS_MODULE,
882 },
883
884 .probe = davinci_soc_platform_probe,
885 .remove = __devexit_p(davinci_soc_platform_remove),
886};
887
888module_platform_driver(davinci_pcm_driver);
889
890MODULE_AUTHOR("Vladimir Barinov");
891MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
892MODULE_LICENSE("GPL");
893