0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/init.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/dma-mapping.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/delay.h>
0019 #include <linux/gfp.h>
0020 #include <linux/of_address.h>
0021 #include <linux/of_irq.h>
0022 #include <linux/of_platform.h>
0023 #include <linux/list.h>
0024 #include <linux/slab.h>
0025
0026 #include <sound/core.h>
0027 #include <sound/pcm.h>
0028 #include <sound/pcm_params.h>
0029 #include <sound/soc.h>
0030
0031 #include <asm/io.h>
0032
0033 #include "fsl_dma.h"
0034 #include "fsl_ssi.h" /* For the offset of stx0 and srx0 */
0035
0036 #define DRV_NAME "fsl_dma"
0037
0038
0039
0040
0041
0042 #define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
0043 SNDRV_PCM_FMTBIT_U8 | \
0044 SNDRV_PCM_FMTBIT_S16_LE | \
0045 SNDRV_PCM_FMTBIT_S16_BE | \
0046 SNDRV_PCM_FMTBIT_U16_LE | \
0047 SNDRV_PCM_FMTBIT_U16_BE | \
0048 SNDRV_PCM_FMTBIT_S24_LE | \
0049 SNDRV_PCM_FMTBIT_S24_BE | \
0050 SNDRV_PCM_FMTBIT_U24_LE | \
0051 SNDRV_PCM_FMTBIT_U24_BE | \
0052 SNDRV_PCM_FMTBIT_S32_LE | \
0053 SNDRV_PCM_FMTBIT_S32_BE | \
0054 SNDRV_PCM_FMTBIT_U32_LE | \
0055 SNDRV_PCM_FMTBIT_U32_BE)
0056 struct dma_object {
0057 struct snd_soc_component_driver dai;
0058 dma_addr_t ssi_stx_phys;
0059 dma_addr_t ssi_srx_phys;
0060 unsigned int ssi_fifo_depth;
0061 struct ccsr_dma_channel __iomem *channel;
0062 unsigned int irq;
0063 bool assigned;
0064 };
0065
0066
0067
0068
0069
0070 #define NUM_DMA_LINKS 2
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 struct fsl_dma_private {
0094 struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
0095 struct ccsr_dma_channel __iomem *dma_channel;
0096 unsigned int irq;
0097 struct snd_pcm_substream *substream;
0098 dma_addr_t ssi_sxx_phys;
0099 unsigned int ssi_fifo_depth;
0100 dma_addr_t ld_buf_phys;
0101 unsigned int current_link;
0102 dma_addr_t dma_buf_phys;
0103 dma_addr_t dma_buf_next;
0104 dma_addr_t dma_buf_end;
0105 size_t period_size;
0106 unsigned int num_periods;
0107 };
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 static const struct snd_pcm_hardware fsl_dma_hardware = {
0129
0130 .info = SNDRV_PCM_INFO_INTERLEAVED |
0131 SNDRV_PCM_INFO_MMAP |
0132 SNDRV_PCM_INFO_MMAP_VALID |
0133 SNDRV_PCM_INFO_JOINT_DUPLEX |
0134 SNDRV_PCM_INFO_PAUSE,
0135 .formats = FSLDMA_PCM_FORMATS,
0136 .period_bytes_min = 512,
0137 .period_bytes_max = (u32) -1,
0138 .periods_min = NUM_DMA_LINKS,
0139 .periods_max = (unsigned int) -1,
0140 .buffer_bytes_max = 128 * 1024,
0141 };
0142
0143
0144
0145
0146
0147
0148
0149 static void fsl_dma_abort_stream(struct snd_pcm_substream *substream)
0150 {
0151 snd_pcm_stop_xrun(substream);
0152 }
0153
0154
0155
0156
0157
0158
0159
0160 static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private)
0161 {
0162 struct fsl_dma_link_descriptor *link =
0163 &dma_private->link[dma_private->current_link];
0164
0165
0166
0167
0168
0169 if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0170 link->source_addr = cpu_to_be32(dma_private->dma_buf_next);
0171 #ifdef CONFIG_PHYS_64BIT
0172 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
0173 upper_32_bits(dma_private->dma_buf_next));
0174 #endif
0175 } else {
0176 link->dest_addr = cpu_to_be32(dma_private->dma_buf_next);
0177 #ifdef CONFIG_PHYS_64BIT
0178 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
0179 upper_32_bits(dma_private->dma_buf_next));
0180 #endif
0181 }
0182
0183
0184 dma_private->dma_buf_next += dma_private->period_size;
0185
0186 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
0187 dma_private->dma_buf_next = dma_private->dma_buf_phys;
0188
0189 if (++dma_private->current_link >= NUM_DMA_LINKS)
0190 dma_private->current_link = 0;
0191 }
0192
0193
0194
0195
0196
0197
0198
0199 static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
0200 {
0201 struct fsl_dma_private *dma_private = dev_id;
0202 struct snd_pcm_substream *substream = dma_private->substream;
0203 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0204 struct device *dev = rtd->dev;
0205 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
0206 irqreturn_t ret = IRQ_NONE;
0207 u32 sr, sr2 = 0;
0208
0209
0210
0211
0212 sr = in_be32(&dma_channel->sr);
0213
0214 if (sr & CCSR_DMA_SR_TE) {
0215 dev_err(dev, "dma transmit error\n");
0216 fsl_dma_abort_stream(substream);
0217 sr2 |= CCSR_DMA_SR_TE;
0218 ret = IRQ_HANDLED;
0219 }
0220
0221 if (sr & CCSR_DMA_SR_CH)
0222 ret = IRQ_HANDLED;
0223
0224 if (sr & CCSR_DMA_SR_PE) {
0225 dev_err(dev, "dma programming error\n");
0226 fsl_dma_abort_stream(substream);
0227 sr2 |= CCSR_DMA_SR_PE;
0228 ret = IRQ_HANDLED;
0229 }
0230
0231 if (sr & CCSR_DMA_SR_EOLNI) {
0232 sr2 |= CCSR_DMA_SR_EOLNI;
0233 ret = IRQ_HANDLED;
0234 }
0235
0236 if (sr & CCSR_DMA_SR_CB)
0237 ret = IRQ_HANDLED;
0238
0239 if (sr & CCSR_DMA_SR_EOSI) {
0240
0241 snd_pcm_period_elapsed(substream);
0242
0243
0244
0245
0246
0247
0248 if (dma_private->num_periods != NUM_DMA_LINKS)
0249 fsl_dma_update_pointers(dma_private);
0250
0251 sr2 |= CCSR_DMA_SR_EOSI;
0252 ret = IRQ_HANDLED;
0253 }
0254
0255 if (sr & CCSR_DMA_SR_EOLSI) {
0256 sr2 |= CCSR_DMA_SR_EOLSI;
0257 ret = IRQ_HANDLED;
0258 }
0259
0260
0261 if (sr2)
0262 out_be32(&dma_channel->sr, sr2);
0263
0264 return ret;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282 static int fsl_dma_new(struct snd_soc_component *component,
0283 struct snd_soc_pcm_runtime *rtd)
0284 {
0285 struct snd_card *card = rtd->card->snd_card;
0286 struct snd_pcm *pcm = rtd->pcm;
0287 int ret;
0288
0289 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(36));
0290 if (ret)
0291 return ret;
0292
0293 return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
0294 card->dev,
0295 fsl_dma_hardware.buffer_bytes_max);
0296 }
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 static int fsl_dma_open(struct snd_soc_component *component,
0361 struct snd_pcm_substream *substream)
0362 {
0363 struct snd_pcm_runtime *runtime = substream->runtime;
0364 struct device *dev = component->dev;
0365 struct dma_object *dma =
0366 container_of(component->driver, struct dma_object, dai);
0367 struct fsl_dma_private *dma_private;
0368 struct ccsr_dma_channel __iomem *dma_channel;
0369 dma_addr_t ld_buf_phys;
0370 u64 temp_link;
0371 u32 mr;
0372 int ret = 0;
0373 unsigned int i;
0374
0375
0376
0377
0378
0379
0380 ret = snd_pcm_hw_constraint_integer(runtime,
0381 SNDRV_PCM_HW_PARAM_PERIODS);
0382 if (ret < 0) {
0383 dev_err(dev, "invalid buffer size\n");
0384 return ret;
0385 }
0386
0387 if (dma->assigned) {
0388 dev_err(dev, "dma channel already assigned\n");
0389 return -EBUSY;
0390 }
0391
0392 dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private),
0393 &ld_buf_phys, GFP_KERNEL);
0394 if (!dma_private) {
0395 dev_err(dev, "can't allocate dma private data\n");
0396 return -ENOMEM;
0397 }
0398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0399 dma_private->ssi_sxx_phys = dma->ssi_stx_phys;
0400 else
0401 dma_private->ssi_sxx_phys = dma->ssi_srx_phys;
0402
0403 dma_private->ssi_fifo_depth = dma->ssi_fifo_depth;
0404 dma_private->dma_channel = dma->channel;
0405 dma_private->irq = dma->irq;
0406 dma_private->substream = substream;
0407 dma_private->ld_buf_phys = ld_buf_phys;
0408 dma_private->dma_buf_phys = substream->dma_buffer.addr;
0409
0410 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio",
0411 dma_private);
0412 if (ret) {
0413 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
0414 dma_private->irq, ret);
0415 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
0416 dma_private, dma_private->ld_buf_phys);
0417 return ret;
0418 }
0419
0420 dma->assigned = true;
0421
0422 snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
0423 runtime->private_data = dma_private;
0424
0425
0426
0427 dma_channel = dma_private->dma_channel;
0428
0429 temp_link = dma_private->ld_buf_phys +
0430 sizeof(struct fsl_dma_link_descriptor);
0431
0432 for (i = 0; i < NUM_DMA_LINKS; i++) {
0433 dma_private->link[i].next = cpu_to_be64(temp_link);
0434
0435 temp_link += sizeof(struct fsl_dma_link_descriptor);
0436 }
0437
0438 dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
0439
0440
0441 out_be32(&dma_channel->clndar,
0442 CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
0443 out_be32(&dma_channel->eclndar,
0444 CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
0445
0446
0447 out_be32(&dma_channel->bcr, 0);
0448
0449
0450
0451
0452
0453 mr = in_be32(&dma_channel->mr) &
0454 ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471 mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
0472 CCSR_DMA_MR_EMS_EN;
0473
0474
0475
0476 mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
0477 CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
0478
0479 out_be32(&dma_channel->mr, mr);
0480
0481 return 0;
0482 }
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 static int fsl_dma_hw_params(struct snd_soc_component *component,
0509 struct snd_pcm_substream *substream,
0510 struct snd_pcm_hw_params *hw_params)
0511 {
0512 struct snd_pcm_runtime *runtime = substream->runtime;
0513 struct fsl_dma_private *dma_private = runtime->private_data;
0514 struct device *dev = component->dev;
0515
0516
0517 unsigned int sample_bits =
0518 snd_pcm_format_physical_width(params_format(hw_params));
0519
0520
0521 unsigned int sample_bytes = sample_bits / 8;
0522
0523
0524 dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys;
0525
0526
0527 size_t buffer_size = params_buffer_bytes(hw_params);
0528
0529
0530 size_t period_size = params_period_bytes(hw_params);
0531
0532
0533 dma_addr_t temp_addr = substream->dma_buffer.addr;
0534
0535
0536 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
0537
0538 u32 mr;
0539
0540 unsigned int i;
0541
0542
0543 dma_private->period_size = period_size;
0544 dma_private->num_periods = params_periods(hw_params);
0545 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
0546 dma_private->dma_buf_next = dma_private->dma_buf_phys +
0547 (NUM_DMA_LINKS * period_size);
0548
0549 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
0550
0551 dma_private->dma_buf_next = dma_private->dma_buf_phys;
0552
0553 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK |
0554 CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK);
0555
0556
0557
0558
0559
0560
0561 switch (sample_bits) {
0562 case 8:
0563 mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1;
0564 ssi_sxx_phys += 3;
0565 break;
0566 case 16:
0567 mr |= CCSR_DMA_MR_DAHTS_2 | CCSR_DMA_MR_SAHTS_2;
0568 ssi_sxx_phys += 2;
0569 break;
0570 case 32:
0571 mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4;
0572 break;
0573 default:
0574
0575 dev_err(dev, "unsupported sample size %u\n", sample_bits);
0576 return -EINVAL;
0577 }
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610 mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes);
0611
0612 out_be32(&dma_channel->mr, mr);
0613
0614 for (i = 0; i < NUM_DMA_LINKS; i++) {
0615 struct fsl_dma_link_descriptor *link = &dma_private->link[i];
0616
0617 link->count = cpu_to_be32(period_size);
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0637 link->source_addr = cpu_to_be32(temp_addr);
0638 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
0639 upper_32_bits(temp_addr));
0640
0641 link->dest_addr = cpu_to_be32(ssi_sxx_phys);
0642 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
0643 upper_32_bits(ssi_sxx_phys));
0644 } else {
0645 link->source_addr = cpu_to_be32(ssi_sxx_phys);
0646 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
0647 upper_32_bits(ssi_sxx_phys));
0648
0649 link->dest_addr = cpu_to_be32(temp_addr);
0650 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
0651 upper_32_bits(temp_addr));
0652 }
0653
0654 temp_addr += period_size;
0655 }
0656
0657 return 0;
0658 }
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672 static snd_pcm_uframes_t fsl_dma_pointer(struct snd_soc_component *component,
0673 struct snd_pcm_substream *substream)
0674 {
0675 struct snd_pcm_runtime *runtime = substream->runtime;
0676 struct fsl_dma_private *dma_private = runtime->private_data;
0677 struct device *dev = component->dev;
0678 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
0679 dma_addr_t position;
0680 snd_pcm_uframes_t frames;
0681
0682
0683
0684
0685
0686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0687 position = in_be32(&dma_channel->sar);
0688 #ifdef CONFIG_PHYS_64BIT
0689 position |= (u64)(in_be32(&dma_channel->satr) &
0690 CCSR_DMA_ATR_ESAD_MASK) << 32;
0691 #endif
0692 } else {
0693 position = in_be32(&dma_channel->dar);
0694 #ifdef CONFIG_PHYS_64BIT
0695 position |= (u64)(in_be32(&dma_channel->datr) &
0696 CCSR_DMA_ATR_ESAD_MASK) << 32;
0697 #endif
0698 }
0699
0700
0701
0702
0703
0704
0705
0706
0707 if (!position)
0708 return 0;
0709
0710 if ((position < dma_private->dma_buf_phys) ||
0711 (position > dma_private->dma_buf_end)) {
0712 dev_err(dev, "dma pointer is out of range, halting stream\n");
0713 return SNDRV_PCM_POS_XRUN;
0714 }
0715
0716 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
0717
0718
0719
0720
0721
0722 if (frames == runtime->buffer_size)
0723 frames = 0;
0724
0725 return frames;
0726 }
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736 static int fsl_dma_hw_free(struct snd_soc_component *component,
0737 struct snd_pcm_substream *substream)
0738 {
0739 struct snd_pcm_runtime *runtime = substream->runtime;
0740 struct fsl_dma_private *dma_private = runtime->private_data;
0741
0742 if (dma_private) {
0743 struct ccsr_dma_channel __iomem *dma_channel;
0744
0745 dma_channel = dma_private->dma_channel;
0746
0747
0748 out_be32(&dma_channel->mr, CCSR_DMA_MR_CA);
0749 out_be32(&dma_channel->mr, 0);
0750
0751
0752 out_be32(&dma_channel->sr, -1);
0753 out_be32(&dma_channel->clndar, 0);
0754 out_be32(&dma_channel->eclndar, 0);
0755 out_be32(&dma_channel->satr, 0);
0756 out_be32(&dma_channel->sar, 0);
0757 out_be32(&dma_channel->datr, 0);
0758 out_be32(&dma_channel->dar, 0);
0759 out_be32(&dma_channel->bcr, 0);
0760 out_be32(&dma_channel->nlndar, 0);
0761 out_be32(&dma_channel->enlndar, 0);
0762 }
0763
0764 return 0;
0765 }
0766
0767
0768
0769
0770 static int fsl_dma_close(struct snd_soc_component *component,
0771 struct snd_pcm_substream *substream)
0772 {
0773 struct snd_pcm_runtime *runtime = substream->runtime;
0774 struct fsl_dma_private *dma_private = runtime->private_data;
0775 struct device *dev = component->dev;
0776 struct dma_object *dma =
0777 container_of(component->driver, struct dma_object, dai);
0778
0779 if (dma_private) {
0780 if (dma_private->irq)
0781 free_irq(dma_private->irq, dma_private);
0782
0783
0784 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
0785 dma_private, dma_private->ld_buf_phys);
0786 substream->runtime->private_data = NULL;
0787 }
0788
0789 dma->assigned = false;
0790
0791 return 0;
0792 }
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805 static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
0806 {
0807 struct device_node *ssi_np, *np;
0808
0809 for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") {
0810
0811
0812
0813 np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
0814 of_node_put(np);
0815 if (np == dma_channel_np)
0816 return ssi_np;
0817
0818 np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
0819 of_node_put(np);
0820 if (np == dma_channel_np)
0821 return ssi_np;
0822 }
0823
0824 return NULL;
0825 }
0826
0827 static int fsl_soc_dma_probe(struct platform_device *pdev)
0828 {
0829 struct dma_object *dma;
0830 struct device_node *np = pdev->dev.of_node;
0831 struct device_node *ssi_np;
0832 struct resource res;
0833 const uint32_t *iprop;
0834 int ret;
0835
0836
0837 ssi_np = find_ssi_node(np);
0838 if (!ssi_np) {
0839 dev_err(&pdev->dev, "cannot find parent SSI node\n");
0840 return -ENODEV;
0841 }
0842
0843 ret = of_address_to_resource(ssi_np, 0, &res);
0844 if (ret) {
0845 dev_err(&pdev->dev, "could not determine resources for %pOF\n",
0846 ssi_np);
0847 of_node_put(ssi_np);
0848 return ret;
0849 }
0850
0851 dma = kzalloc(sizeof(*dma), GFP_KERNEL);
0852 if (!dma) {
0853 of_node_put(ssi_np);
0854 return -ENOMEM;
0855 }
0856
0857 dma->dai.name = DRV_NAME;
0858 dma->dai.open = fsl_dma_open;
0859 dma->dai.close = fsl_dma_close;
0860 dma->dai.hw_params = fsl_dma_hw_params;
0861 dma->dai.hw_free = fsl_dma_hw_free;
0862 dma->dai.pointer = fsl_dma_pointer;
0863 dma->dai.pcm_construct = fsl_dma_new;
0864
0865
0866 dma->ssi_stx_phys = res.start + REG_SSI_STX0;
0867 dma->ssi_srx_phys = res.start + REG_SSI_SRX0;
0868
0869 iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
0870 if (iprop)
0871 dma->ssi_fifo_depth = be32_to_cpup(iprop);
0872 else
0873
0874 dma->ssi_fifo_depth = 8;
0875
0876 of_node_put(ssi_np);
0877
0878 ret = devm_snd_soc_register_component(&pdev->dev, &dma->dai, NULL, 0);
0879 if (ret) {
0880 dev_err(&pdev->dev, "could not register platform\n");
0881 kfree(dma);
0882 return ret;
0883 }
0884
0885 dma->channel = of_iomap(np, 0);
0886 dma->irq = irq_of_parse_and_map(np, 0);
0887
0888 dev_set_drvdata(&pdev->dev, dma);
0889
0890 return 0;
0891 }
0892
0893 static int fsl_soc_dma_remove(struct platform_device *pdev)
0894 {
0895 struct dma_object *dma = dev_get_drvdata(&pdev->dev);
0896
0897 iounmap(dma->channel);
0898 irq_dispose_mapping(dma->irq);
0899 kfree(dma);
0900
0901 return 0;
0902 }
0903
0904 static const struct of_device_id fsl_soc_dma_ids[] = {
0905 { .compatible = "fsl,ssi-dma-channel", },
0906 {}
0907 };
0908 MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids);
0909
0910 static struct platform_driver fsl_soc_dma_driver = {
0911 .driver = {
0912 .name = "fsl-pcm-audio",
0913 .of_match_table = fsl_soc_dma_ids,
0914 },
0915 .probe = fsl_soc_dma_probe,
0916 .remove = fsl_soc_dma_remove,
0917 };
0918
0919 module_platform_driver(fsl_soc_dma_driver);
0920
0921 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
0922 MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
0923 MODULE_LICENSE("GPL v2");