1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/dma-mapping.h>
21#include <linux/interrupt.h>
22#include <linux/delay.h>
23#include <linux/gfp.h>
24#include <linux/of_address.h>
25#include <linux/of_irq.h>
26#include <linux/of_platform.h>
27#include <linux/list.h>
28#include <linux/slab.h>
29
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34
35#include <asm/io.h>
36
37#include "fsl_dma.h"
38#include "fsl_ssi.h"
39
40
41
42
43
44#define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
45 SNDRV_PCM_FMTBIT_U8 | \
46 SNDRV_PCM_FMTBIT_S16_LE | \
47 SNDRV_PCM_FMTBIT_S16_BE | \
48 SNDRV_PCM_FMTBIT_U16_LE | \
49 SNDRV_PCM_FMTBIT_U16_BE | \
50 SNDRV_PCM_FMTBIT_S24_LE | \
51 SNDRV_PCM_FMTBIT_S24_BE | \
52 SNDRV_PCM_FMTBIT_U24_LE | \
53 SNDRV_PCM_FMTBIT_U24_BE | \
54 SNDRV_PCM_FMTBIT_S32_LE | \
55 SNDRV_PCM_FMTBIT_S32_BE | \
56 SNDRV_PCM_FMTBIT_U32_LE | \
57 SNDRV_PCM_FMTBIT_U32_BE)
58struct dma_object {
59 struct snd_soc_platform_driver dai;
60 dma_addr_t ssi_stx_phys;
61 dma_addr_t ssi_srx_phys;
62 unsigned int ssi_fifo_depth;
63 struct ccsr_dma_channel __iomem *channel;
64 unsigned int irq;
65 bool assigned;
66 char path[1];
67};
68
69
70
71
72
73#define NUM_DMA_LINKS 2
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96struct fsl_dma_private {
97 struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
98 struct ccsr_dma_channel __iomem *dma_channel;
99 unsigned int irq;
100 struct snd_pcm_substream *substream;
101 dma_addr_t ssi_sxx_phys;
102 unsigned int ssi_fifo_depth;
103 dma_addr_t ld_buf_phys;
104 unsigned int current_link;
105 dma_addr_t dma_buf_phys;
106 dma_addr_t dma_buf_next;
107 dma_addr_t dma_buf_end;
108 size_t period_size;
109 unsigned int num_periods;
110};
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131static const struct snd_pcm_hardware fsl_dma_hardware = {
132
133 .info = SNDRV_PCM_INFO_INTERLEAVED |
134 SNDRV_PCM_INFO_MMAP |
135 SNDRV_PCM_INFO_MMAP_VALID |
136 SNDRV_PCM_INFO_JOINT_DUPLEX |
137 SNDRV_PCM_INFO_PAUSE,
138 .formats = FSLDMA_PCM_FORMATS,
139 .period_bytes_min = 512,
140 .period_bytes_max = (u32) -1,
141 .periods_min = NUM_DMA_LINKS,
142 .periods_max = (unsigned int) -1,
143 .buffer_bytes_max = 128 * 1024,
144};
145
146
147
148
149
150
151
152static void fsl_dma_abort_stream(struct snd_pcm_substream *substream)
153{
154 snd_pcm_stop_xrun(substream);
155}
156
157
158
159
160
161
162
163static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private)
164{
165 struct fsl_dma_link_descriptor *link =
166 &dma_private->link[dma_private->current_link];
167
168
169
170
171
172 if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
173 link->source_addr = cpu_to_be32(dma_private->dma_buf_next);
174#ifdef CONFIG_PHYS_64BIT
175 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
176 upper_32_bits(dma_private->dma_buf_next));
177#endif
178 } else {
179 link->dest_addr = cpu_to_be32(dma_private->dma_buf_next);
180#ifdef CONFIG_PHYS_64BIT
181 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
182 upper_32_bits(dma_private->dma_buf_next));
183#endif
184 }
185
186
187 dma_private->dma_buf_next += dma_private->period_size;
188
189 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
190 dma_private->dma_buf_next = dma_private->dma_buf_phys;
191
192 if (++dma_private->current_link >= NUM_DMA_LINKS)
193 dma_private->current_link = 0;
194}
195
196
197
198
199
200
201
202static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
203{
204 struct fsl_dma_private *dma_private = dev_id;
205 struct snd_pcm_substream *substream = dma_private->substream;
206 struct snd_soc_pcm_runtime *rtd = substream->private_data;
207 struct device *dev = rtd->platform->dev;
208 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
209 irqreturn_t ret = IRQ_NONE;
210 u32 sr, sr2 = 0;
211
212
213
214
215 sr = in_be32(&dma_channel->sr);
216
217 if (sr & CCSR_DMA_SR_TE) {
218 dev_err(dev, "dma transmit error\n");
219 fsl_dma_abort_stream(substream);
220 sr2 |= CCSR_DMA_SR_TE;
221 ret = IRQ_HANDLED;
222 }
223
224 if (sr & CCSR_DMA_SR_CH)
225 ret = IRQ_HANDLED;
226
227 if (sr & CCSR_DMA_SR_PE) {
228 dev_err(dev, "dma programming error\n");
229 fsl_dma_abort_stream(substream);
230 sr2 |= CCSR_DMA_SR_PE;
231 ret = IRQ_HANDLED;
232 }
233
234 if (sr & CCSR_DMA_SR_EOLNI) {
235 sr2 |= CCSR_DMA_SR_EOLNI;
236 ret = IRQ_HANDLED;
237 }
238
239 if (sr & CCSR_DMA_SR_CB)
240 ret = IRQ_HANDLED;
241
242 if (sr & CCSR_DMA_SR_EOSI) {
243
244 snd_pcm_period_elapsed(substream);
245
246
247
248
249
250
251 if (dma_private->num_periods != NUM_DMA_LINKS)
252 fsl_dma_update_pointers(dma_private);
253
254 sr2 |= CCSR_DMA_SR_EOSI;
255 ret = IRQ_HANDLED;
256 }
257
258 if (sr & CCSR_DMA_SR_EOLSI) {
259 sr2 |= CCSR_DMA_SR_EOLSI;
260 ret = IRQ_HANDLED;
261 }
262
263
264 if (sr2)
265 out_be32(&dma_channel->sr, sr2);
266
267 return ret;
268}
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
286{
287 struct snd_card *card = rtd->card->snd_card;
288 struct snd_pcm *pcm = rtd->pcm;
289 int ret;
290
291 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(36));
292 if (ret)
293 return ret;
294
295
296
297
298
299 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
300 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
301 fsl_dma_hardware.buffer_bytes_max,
302 &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
303 if (ret) {
304 dev_err(card->dev, "can't alloc playback dma buffer\n");
305 return ret;
306 }
307 }
308
309 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
310 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
311 fsl_dma_hardware.buffer_bytes_max,
312 &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
313 if (ret) {
314 dev_err(card->dev, "can't alloc capture dma buffer\n");
315 snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
316 return ret;
317 }
318 }
319
320 return 0;
321}
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385static int fsl_dma_open(struct snd_pcm_substream *substream)
386{
387 struct snd_pcm_runtime *runtime = substream->runtime;
388 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct device *dev = rtd->platform->dev;
390 struct dma_object *dma =
391 container_of(rtd->platform->driver, struct dma_object, dai);
392 struct fsl_dma_private *dma_private;
393 struct ccsr_dma_channel __iomem *dma_channel;
394 dma_addr_t ld_buf_phys;
395 u64 temp_link;
396 u32 mr;
397 unsigned int channel;
398 int ret = 0;
399 unsigned int i;
400
401
402
403
404
405
406 ret = snd_pcm_hw_constraint_integer(runtime,
407 SNDRV_PCM_HW_PARAM_PERIODS);
408 if (ret < 0) {
409 dev_err(dev, "invalid buffer size\n");
410 return ret;
411 }
412
413 channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
414
415 if (dma->assigned) {
416 dev_err(dev, "dma channel already assigned\n");
417 return -EBUSY;
418 }
419
420 dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private),
421 &ld_buf_phys, GFP_KERNEL);
422 if (!dma_private) {
423 dev_err(dev, "can't allocate dma private data\n");
424 return -ENOMEM;
425 }
426 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
427 dma_private->ssi_sxx_phys = dma->ssi_stx_phys;
428 else
429 dma_private->ssi_sxx_phys = dma->ssi_srx_phys;
430
431 dma_private->ssi_fifo_depth = dma->ssi_fifo_depth;
432 dma_private->dma_channel = dma->channel;
433 dma_private->irq = dma->irq;
434 dma_private->substream = substream;
435 dma_private->ld_buf_phys = ld_buf_phys;
436 dma_private->dma_buf_phys = substream->dma_buffer.addr;
437
438 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio",
439 dma_private);
440 if (ret) {
441 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
442 dma_private->irq, ret);
443 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
444 dma_private, dma_private->ld_buf_phys);
445 return ret;
446 }
447
448 dma->assigned = 1;
449
450 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
451 snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
452 runtime->private_data = dma_private;
453
454
455
456 dma_channel = dma_private->dma_channel;
457
458 temp_link = dma_private->ld_buf_phys +
459 sizeof(struct fsl_dma_link_descriptor);
460
461 for (i = 0; i < NUM_DMA_LINKS; i++) {
462 dma_private->link[i].next = cpu_to_be64(temp_link);
463
464 temp_link += sizeof(struct fsl_dma_link_descriptor);
465 }
466
467 dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
468
469
470 out_be32(&dma_channel->clndar,
471 CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
472 out_be32(&dma_channel->eclndar,
473 CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
474
475
476 out_be32(&dma_channel->bcr, 0);
477
478
479
480
481
482 mr = in_be32(&dma_channel->mr) &
483 ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500 mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
501 CCSR_DMA_MR_EMS_EN;
502
503
504
505 mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
506 CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
507
508 out_be32(&dma_channel->mr, mr);
509
510 return 0;
511}
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
538 struct snd_pcm_hw_params *hw_params)
539{
540 struct snd_pcm_runtime *runtime = substream->runtime;
541 struct fsl_dma_private *dma_private = runtime->private_data;
542 struct snd_soc_pcm_runtime *rtd = substream->private_data;
543 struct device *dev = rtd->platform->dev;
544
545
546 unsigned int sample_bits =
547 snd_pcm_format_physical_width(params_format(hw_params));
548
549
550 unsigned int sample_bytes = sample_bits / 8;
551
552
553 dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys;
554
555
556 size_t buffer_size = params_buffer_bytes(hw_params);
557
558
559 size_t period_size = params_period_bytes(hw_params);
560
561
562 dma_addr_t temp_addr = substream->dma_buffer.addr;
563
564
565 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
566
567 u32 mr;
568
569 unsigned int i;
570
571
572 dma_private->period_size = period_size;
573 dma_private->num_periods = params_periods(hw_params);
574 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
575 dma_private->dma_buf_next = dma_private->dma_buf_phys +
576 (NUM_DMA_LINKS * period_size);
577
578 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
579
580 dma_private->dma_buf_next = dma_private->dma_buf_phys;
581
582 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK |
583 CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK);
584
585
586
587
588
589
590 switch (sample_bits) {
591 case 8:
592 mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1;
593 ssi_sxx_phys += 3;
594 break;
595 case 16:
596 mr |= CCSR_DMA_MR_DAHTS_2 | CCSR_DMA_MR_SAHTS_2;
597 ssi_sxx_phys += 2;
598 break;
599 case 32:
600 mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4;
601 break;
602 default:
603
604 dev_err(dev, "unsupported sample size %u\n", sample_bits);
605 return -EINVAL;
606 }
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639 mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes);
640
641 out_be32(&dma_channel->mr, mr);
642
643 for (i = 0; i < NUM_DMA_LINKS; i++) {
644 struct fsl_dma_link_descriptor *link = &dma_private->link[i];
645
646 link->count = cpu_to_be32(period_size);
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
666 link->source_addr = cpu_to_be32(temp_addr);
667 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
668 upper_32_bits(temp_addr));
669
670 link->dest_addr = cpu_to_be32(ssi_sxx_phys);
671 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
672 upper_32_bits(ssi_sxx_phys));
673 } else {
674 link->source_addr = cpu_to_be32(ssi_sxx_phys);
675 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
676 upper_32_bits(ssi_sxx_phys));
677
678 link->dest_addr = cpu_to_be32(temp_addr);
679 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
680 upper_32_bits(temp_addr));
681 }
682
683 temp_addr += period_size;
684 }
685
686 return 0;
687}
688
689
690
691
692
693
694
695
696
697
698
699
700
701static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
702{
703 struct snd_pcm_runtime *runtime = substream->runtime;
704 struct fsl_dma_private *dma_private = runtime->private_data;
705 struct snd_soc_pcm_runtime *rtd = substream->private_data;
706 struct device *dev = rtd->platform->dev;
707 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
708 dma_addr_t position;
709 snd_pcm_uframes_t frames;
710
711
712
713
714
715 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
716 position = in_be32(&dma_channel->sar);
717#ifdef CONFIG_PHYS_64BIT
718 position |= (u64)(in_be32(&dma_channel->satr) &
719 CCSR_DMA_ATR_ESAD_MASK) << 32;
720#endif
721 } else {
722 position = in_be32(&dma_channel->dar);
723#ifdef CONFIG_PHYS_64BIT
724 position |= (u64)(in_be32(&dma_channel->datr) &
725 CCSR_DMA_ATR_ESAD_MASK) << 32;
726#endif
727 }
728
729
730
731
732
733
734
735
736 if (!position)
737 return 0;
738
739 if ((position < dma_private->dma_buf_phys) ||
740 (position > dma_private->dma_buf_end)) {
741 dev_err(dev, "dma pointer is out of range, halting stream\n");
742 return SNDRV_PCM_POS_XRUN;
743 }
744
745 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
746
747
748
749
750
751 if (frames == runtime->buffer_size)
752 frames = 0;
753
754 return frames;
755}
756
757
758
759
760
761
762
763
764
765static int fsl_dma_hw_free(struct snd_pcm_substream *substream)
766{
767 struct snd_pcm_runtime *runtime = substream->runtime;
768 struct fsl_dma_private *dma_private = runtime->private_data;
769
770 if (dma_private) {
771 struct ccsr_dma_channel __iomem *dma_channel;
772
773 dma_channel = dma_private->dma_channel;
774
775
776 out_be32(&dma_channel->mr, CCSR_DMA_MR_CA);
777 out_be32(&dma_channel->mr, 0);
778
779
780 out_be32(&dma_channel->sr, -1);
781 out_be32(&dma_channel->clndar, 0);
782 out_be32(&dma_channel->eclndar, 0);
783 out_be32(&dma_channel->satr, 0);
784 out_be32(&dma_channel->sar, 0);
785 out_be32(&dma_channel->datr, 0);
786 out_be32(&dma_channel->dar, 0);
787 out_be32(&dma_channel->bcr, 0);
788 out_be32(&dma_channel->nlndar, 0);
789 out_be32(&dma_channel->enlndar, 0);
790 }
791
792 return 0;
793}
794
795
796
797
798static int fsl_dma_close(struct snd_pcm_substream *substream)
799{
800 struct snd_pcm_runtime *runtime = substream->runtime;
801 struct fsl_dma_private *dma_private = runtime->private_data;
802 struct snd_soc_pcm_runtime *rtd = substream->private_data;
803 struct device *dev = rtd->platform->dev;
804 struct dma_object *dma =
805 container_of(rtd->platform->driver, struct dma_object, dai);
806
807 if (dma_private) {
808 if (dma_private->irq)
809 free_irq(dma_private->irq, dma_private);
810
811
812 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
813 dma_private, dma_private->ld_buf_phys);
814 substream->runtime->private_data = NULL;
815 }
816
817 dma->assigned = 0;
818
819 return 0;
820}
821
822
823
824
825static void fsl_dma_free_dma_buffers(struct snd_pcm *pcm)
826{
827 struct snd_pcm_substream *substream;
828 unsigned int i;
829
830 for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
831 substream = pcm->streams[i].substream;
832 if (substream) {
833 snd_dma_free_pages(&substream->dma_buffer);
834 substream->dma_buffer.area = NULL;
835 substream->dma_buffer.addr = 0;
836 }
837 }
838}
839
840
841
842
843
844
845
846
847
848
849
850
851static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
852{
853 struct device_node *ssi_np, *np;
854
855 for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") {
856
857
858
859 np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
860 of_node_put(np);
861 if (np == dma_channel_np)
862 return ssi_np;
863
864 np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
865 of_node_put(np);
866 if (np == dma_channel_np)
867 return ssi_np;
868 }
869
870 return NULL;
871}
872
873static struct snd_pcm_ops fsl_dma_ops = {
874 .open = fsl_dma_open,
875 .close = fsl_dma_close,
876 .ioctl = snd_pcm_lib_ioctl,
877 .hw_params = fsl_dma_hw_params,
878 .hw_free = fsl_dma_hw_free,
879 .pointer = fsl_dma_pointer,
880};
881
882static int fsl_soc_dma_probe(struct platform_device *pdev)
883 {
884 struct dma_object *dma;
885 struct device_node *np = pdev->dev.of_node;
886 struct device_node *ssi_np;
887 struct resource res;
888 const uint32_t *iprop;
889 int ret;
890
891
892 ssi_np = find_ssi_node(np);
893 if (!ssi_np) {
894 dev_err(&pdev->dev, "cannot find parent SSI node\n");
895 return -ENODEV;
896 }
897
898 ret = of_address_to_resource(ssi_np, 0, &res);
899 if (ret) {
900 dev_err(&pdev->dev, "could not determine resources for %s\n",
901 ssi_np->full_name);
902 of_node_put(ssi_np);
903 return ret;
904 }
905
906 dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL);
907 if (!dma) {
908 dev_err(&pdev->dev, "could not allocate dma object\n");
909 of_node_put(ssi_np);
910 return -ENOMEM;
911 }
912
913 strcpy(dma->path, np->full_name);
914 dma->dai.ops = &fsl_dma_ops;
915 dma->dai.pcm_new = fsl_dma_new;
916 dma->dai.pcm_free = fsl_dma_free_dma_buffers;
917
918
919 dma->ssi_stx_phys = res.start + CCSR_SSI_STX0;
920 dma->ssi_srx_phys = res.start + CCSR_SSI_SRX0;
921
922 iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
923 if (iprop)
924 dma->ssi_fifo_depth = be32_to_cpup(iprop);
925 else
926
927 dma->ssi_fifo_depth = 8;
928
929 of_node_put(ssi_np);
930
931 ret = snd_soc_register_platform(&pdev->dev, &dma->dai);
932 if (ret) {
933 dev_err(&pdev->dev, "could not register platform\n");
934 kfree(dma);
935 return ret;
936 }
937
938 dma->channel = of_iomap(np, 0);
939 dma->irq = irq_of_parse_and_map(np, 0);
940
941 dev_set_drvdata(&pdev->dev, dma);
942
943 return 0;
944}
945
946static int fsl_soc_dma_remove(struct platform_device *pdev)
947{
948 struct dma_object *dma = dev_get_drvdata(&pdev->dev);
949
950 snd_soc_unregister_platform(&pdev->dev);
951 iounmap(dma->channel);
952 irq_dispose_mapping(dma->irq);
953 kfree(dma);
954
955 return 0;
956}
957
958static const struct of_device_id fsl_soc_dma_ids[] = {
959 { .compatible = "fsl,ssi-dma-channel", },
960 {}
961};
962MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids);
963
964static struct platform_driver fsl_soc_dma_driver = {
965 .driver = {
966 .name = "fsl-pcm-audio",
967 .of_match_table = fsl_soc_dma_ids,
968 },
969 .probe = fsl_soc_dma_probe,
970 .remove = fsl_soc_dma_remove,
971};
972
973module_platform_driver(fsl_soc_dma_driver);
974
975MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
976MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
977MODULE_LICENSE("GPL v2");
978