0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/init.h>
0018 #include <linux/module.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/device.h>
0021 #include <linux/delay.h>
0022 #include <linux/clk.h>
0023 #include <linux/atmel_pdc.h>
0024
0025 #include <linux/atmel-ssc.h>
0026 #include <sound/core.h>
0027 #include <sound/pcm.h>
0028 #include <sound/pcm_params.h>
0029 #include <sound/initval.h>
0030 #include <sound/soc.h>
0031
0032 #include "atmel-pcm.h"
0033 #include "atmel_ssc_dai.h"
0034
0035
0036 #define NUM_SSC_DEVICES 3
0037
0038
0039
0040
0041 static struct atmel_pdc_regs pdc_tx_reg = {
0042 .xpr = ATMEL_PDC_TPR,
0043 .xcr = ATMEL_PDC_TCR,
0044 .xnpr = ATMEL_PDC_TNPR,
0045 .xncr = ATMEL_PDC_TNCR,
0046 };
0047
0048 static struct atmel_pdc_regs pdc_rx_reg = {
0049 .xpr = ATMEL_PDC_RPR,
0050 .xcr = ATMEL_PDC_RCR,
0051 .xnpr = ATMEL_PDC_RNPR,
0052 .xncr = ATMEL_PDC_RNCR,
0053 };
0054
0055
0056
0057
0058 static struct atmel_ssc_mask ssc_tx_mask = {
0059 .ssc_enable = SSC_BIT(CR_TXEN),
0060 .ssc_disable = SSC_BIT(CR_TXDIS),
0061 .ssc_endx = SSC_BIT(SR_ENDTX),
0062 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
0063 .ssc_error = SSC_BIT(SR_OVRUN),
0064 .pdc_enable = ATMEL_PDC_TXTEN,
0065 .pdc_disable = ATMEL_PDC_TXTDIS,
0066 };
0067
0068 static struct atmel_ssc_mask ssc_rx_mask = {
0069 .ssc_enable = SSC_BIT(CR_RXEN),
0070 .ssc_disable = SSC_BIT(CR_RXDIS),
0071 .ssc_endx = SSC_BIT(SR_ENDRX),
0072 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
0073 .ssc_error = SSC_BIT(SR_OVRUN),
0074 .pdc_enable = ATMEL_PDC_RXTEN,
0075 .pdc_disable = ATMEL_PDC_RXTDIS,
0076 };
0077
0078
0079
0080
0081
0082 static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
0083 {{
0084 .name = "SSC0 PCM out",
0085 .pdc = &pdc_tx_reg,
0086 .mask = &ssc_tx_mask,
0087 },
0088 {
0089 .name = "SSC0 PCM in",
0090 .pdc = &pdc_rx_reg,
0091 .mask = &ssc_rx_mask,
0092 } },
0093 {{
0094 .name = "SSC1 PCM out",
0095 .pdc = &pdc_tx_reg,
0096 .mask = &ssc_tx_mask,
0097 },
0098 {
0099 .name = "SSC1 PCM in",
0100 .pdc = &pdc_rx_reg,
0101 .mask = &ssc_rx_mask,
0102 } },
0103 {{
0104 .name = "SSC2 PCM out",
0105 .pdc = &pdc_tx_reg,
0106 .mask = &ssc_tx_mask,
0107 },
0108 {
0109 .name = "SSC2 PCM in",
0110 .pdc = &pdc_rx_reg,
0111 .mask = &ssc_rx_mask,
0112 } },
0113 };
0114
0115
0116 static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
0117 {
0118 .name = "ssc0",
0119 .dir_mask = SSC_DIR_MASK_UNUSED,
0120 .initialized = 0,
0121 },
0122 {
0123 .name = "ssc1",
0124 .dir_mask = SSC_DIR_MASK_UNUSED,
0125 .initialized = 0,
0126 },
0127 {
0128 .name = "ssc2",
0129 .dir_mask = SSC_DIR_MASK_UNUSED,
0130 .initialized = 0,
0131 },
0132 };
0133
0134
0135
0136
0137
0138
0139 static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
0140 {
0141 struct atmel_ssc_info *ssc_p = dev_id;
0142 struct atmel_pcm_dma_params *dma_params;
0143 u32 ssc_sr;
0144 u32 ssc_substream_mask;
0145 int i;
0146
0147 ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
0148 & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
0149
0150
0151
0152
0153
0154
0155
0156 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
0157 dma_params = ssc_p->dma_params[i];
0158
0159 if ((dma_params != NULL) &&
0160 (dma_params->dma_intr_handler != NULL)) {
0161 ssc_substream_mask = (dma_params->mask->ssc_endx |
0162 dma_params->mask->ssc_endbuf);
0163 if (ssc_sr & ssc_substream_mask) {
0164 dma_params->dma_intr_handler(ssc_sr,
0165 dma_params->
0166 substream);
0167 }
0168 }
0169 }
0170
0171 return IRQ_HANDLED;
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
0192 struct snd_pcm_hw_rule *rule)
0193 {
0194 struct atmel_ssc_info *ssc_p = rule->private;
0195 struct ssc_device *ssc = ssc_p->ssc;
0196 struct snd_interval *i = hw_param_interval(params, rule->var);
0197 struct snd_interval t;
0198 struct snd_ratnum r = {
0199 .den_min = 1,
0200 .den_max = 4095,
0201 .den_step = 1,
0202 };
0203 unsigned int num = 0, den = 0;
0204 int frame_size;
0205 int mck_div = 2;
0206 int ret;
0207
0208 frame_size = snd_soc_params_to_frame_size(params);
0209 if (frame_size < 0)
0210 return frame_size;
0211
0212 switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0213 case SND_SOC_DAIFMT_BC_FP:
0214 if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE)
0215 && ssc->clk_from_rk_pin)
0216
0217
0218
0219
0220 mck_div = 3;
0221 break;
0222
0223 case SND_SOC_DAIFMT_BC_FC:
0224 if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK)
0225 && !ssc->clk_from_rk_pin)
0226
0227
0228
0229
0230
0231 mck_div = 6;
0232 break;
0233 }
0234
0235 switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0236 case SND_SOC_DAIFMT_BP_FP:
0237 r.num = ssc_p->mck_rate / mck_div / frame_size;
0238
0239 ret = snd_interval_ratnum(i, 1, &r, &num, &den);
0240 if (ret >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
0241 params->rate_num = num;
0242 params->rate_den = den;
0243 }
0244 break;
0245
0246 case SND_SOC_DAIFMT_BC_FP:
0247 case SND_SOC_DAIFMT_BC_FC:
0248 t.min = 8000;
0249 t.max = ssc_p->mck_rate / mck_div / frame_size;
0250 t.openmin = t.openmax = 0;
0251 t.integer = 0;
0252 ret = snd_interval_refine(i, &t);
0253 break;
0254
0255 default:
0256 ret = -EINVAL;
0257 break;
0258 }
0259
0260 return ret;
0261 }
0262
0263
0264
0265
0266
0267
0268
0269 static int atmel_ssc_startup(struct snd_pcm_substream *substream,
0270 struct snd_soc_dai *dai)
0271 {
0272 struct platform_device *pdev = to_platform_device(dai->dev);
0273 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
0274 struct atmel_pcm_dma_params *dma_params;
0275 int dir, dir_mask;
0276 int ret;
0277
0278 pr_debug("atmel_ssc_startup: SSC_SR=0x%x\n",
0279 ssc_readl(ssc_p->ssc->regs, SR));
0280
0281
0282 pr_debug("atmel_ssc_dai: Starting clock\n");
0283 ret = clk_enable(ssc_p->ssc->clk);
0284 if (ret)
0285 return ret;
0286
0287 ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
0288
0289
0290 if (!ssc_p->initialized)
0291 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
0292
0293 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0294 dir = 0;
0295 dir_mask = SSC_DIR_MASK_PLAYBACK;
0296 } else {
0297 dir = 1;
0298 dir_mask = SSC_DIR_MASK_CAPTURE;
0299 }
0300
0301 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
0302 SNDRV_PCM_HW_PARAM_RATE,
0303 atmel_ssc_hw_rule_rate,
0304 ssc_p,
0305 SNDRV_PCM_HW_PARAM_FRAME_BITS,
0306 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
0307 if (ret < 0) {
0308 dev_err(dai->dev, "Failed to specify rate rule: %d\n", ret);
0309 return ret;
0310 }
0311
0312 dma_params = &ssc_dma_params[pdev->id][dir];
0313 dma_params->ssc = ssc_p->ssc;
0314 dma_params->substream = substream;
0315
0316 ssc_p->dma_params[dir] = dma_params;
0317
0318 snd_soc_dai_set_dma_data(dai, substream, dma_params);
0319
0320 if (ssc_p->dir_mask & dir_mask)
0321 return -EBUSY;
0322
0323 ssc_p->dir_mask |= dir_mask;
0324
0325 return 0;
0326 }
0327
0328
0329
0330
0331
0332 static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
0333 struct snd_soc_dai *dai)
0334 {
0335 struct platform_device *pdev = to_platform_device(dai->dev);
0336 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
0337 struct atmel_pcm_dma_params *dma_params;
0338 int dir, dir_mask;
0339
0340 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0341 dir = 0;
0342 else
0343 dir = 1;
0344
0345 dma_params = ssc_p->dma_params[dir];
0346
0347 if (dma_params != NULL) {
0348 dma_params->ssc = NULL;
0349 dma_params->substream = NULL;
0350 ssc_p->dma_params[dir] = NULL;
0351 }
0352
0353 dir_mask = 1 << dir;
0354
0355 ssc_p->dir_mask &= ~dir_mask;
0356 if (!ssc_p->dir_mask) {
0357 if (ssc_p->initialized) {
0358 free_irq(ssc_p->ssc->irq, ssc_p);
0359 ssc_p->initialized = 0;
0360 }
0361
0362
0363 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
0364
0365 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
0366 ssc_p->forced_divider = 0;
0367 }
0368
0369
0370 pr_debug("atmel_ssc_dai: Stopping clock\n");
0371 clk_disable(ssc_p->ssc->clk);
0372 }
0373
0374
0375
0376
0377
0378 static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
0379 unsigned int fmt)
0380 {
0381 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
0382 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
0383
0384 ssc_p->daifmt = fmt;
0385 return 0;
0386 }
0387
0388
0389
0390
0391 static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
0392 int div_id, int div)
0393 {
0394 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
0395 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
0396
0397 switch (div_id) {
0398 case ATMEL_SSC_CMR_DIV:
0399
0400
0401
0402
0403
0404 if (ssc_p->dir_mask !=
0405 (SSC_DIR_MASK_PLAYBACK | SSC_DIR_MASK_CAPTURE))
0406 ssc_p->cmr_div = div;
0407 else if (ssc_p->cmr_div == 0)
0408 ssc_p->cmr_div = div;
0409 else
0410 if (div != ssc_p->cmr_div)
0411 return -EBUSY;
0412 ssc_p->forced_divider |= BIT(ATMEL_SSC_CMR_DIV);
0413 break;
0414
0415 case ATMEL_SSC_TCMR_PERIOD:
0416 ssc_p->tcmr_period = div;
0417 ssc_p->forced_divider |= BIT(ATMEL_SSC_TCMR_PERIOD);
0418 break;
0419
0420 case ATMEL_SSC_RCMR_PERIOD:
0421 ssc_p->rcmr_period = div;
0422 ssc_p->forced_divider |= BIT(ATMEL_SSC_RCMR_PERIOD);
0423 break;
0424
0425 default:
0426 return -EINVAL;
0427 }
0428
0429 return 0;
0430 }
0431
0432
0433 static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p)
0434 {
0435 switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0436 case SND_SOC_DAIFMT_BC_FP:
0437 case SND_SOC_DAIFMT_BP_FP:
0438 return 1;
0439 }
0440 return 0;
0441 }
0442
0443
0444 static int atmel_ssc_cbs(struct atmel_ssc_info *ssc_p)
0445 {
0446 switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0447 case SND_SOC_DAIFMT_BP_FC:
0448 case SND_SOC_DAIFMT_BP_FP:
0449 return 1;
0450 }
0451 return 0;
0452 }
0453
0454
0455
0456
0457 static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
0458 struct snd_pcm_hw_params *params,
0459 struct snd_soc_dai *dai)
0460 {
0461 struct platform_device *pdev = to_platform_device(dai->dev);
0462 int id = pdev->id;
0463 struct atmel_ssc_info *ssc_p = &ssc_info[id];
0464 struct ssc_device *ssc = ssc_p->ssc;
0465 struct atmel_pcm_dma_params *dma_params;
0466 int dir, channels, bits;
0467 u32 tfmr, rfmr, tcmr, rcmr;
0468 int ret;
0469 int fslen, fslen_ext, fs_osync, fs_edge;
0470 u32 cmr_div;
0471 u32 tcmr_period;
0472 u32 rcmr_period;
0473
0474
0475
0476
0477
0478
0479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0480 dir = 0;
0481 else
0482 dir = 1;
0483
0484
0485
0486
0487
0488 cmr_div = ssc_p->cmr_div;
0489 if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_CMR_DIV)) &&
0490 atmel_ssc_cbs(ssc_p)) {
0491 int bclk_rate = snd_soc_params_to_bclk(params);
0492
0493 if (bclk_rate < 0) {
0494 dev_err(dai->dev, "unable to calculate cmr_div: %d\n",
0495 bclk_rate);
0496 return bclk_rate;
0497 }
0498
0499 cmr_div = DIV_ROUND_CLOSEST(ssc_p->mck_rate, 2 * bclk_rate);
0500 }
0501
0502
0503
0504
0505
0506 tcmr_period = ssc_p->tcmr_period;
0507 rcmr_period = ssc_p->rcmr_period;
0508 if (atmel_ssc_cfs(ssc_p)) {
0509 int frame_size = snd_soc_params_to_frame_size(params);
0510
0511 if (frame_size < 0) {
0512 dev_err(dai->dev,
0513 "unable to calculate tx/rx cmr_period: %d\n",
0514 frame_size);
0515 return frame_size;
0516 }
0517
0518 if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_TCMR_PERIOD)))
0519 tcmr_period = frame_size / 2 - 1;
0520 if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_RCMR_PERIOD)))
0521 rcmr_period = frame_size / 2 - 1;
0522 }
0523
0524 dma_params = ssc_p->dma_params[dir];
0525
0526 channels = params_channels(params);
0527
0528
0529
0530
0531 switch (params_format(params)) {
0532 case SNDRV_PCM_FORMAT_S8:
0533 bits = 8;
0534 dma_params->pdc_xfer_size = 1;
0535 break;
0536 case SNDRV_PCM_FORMAT_S16_LE:
0537 bits = 16;
0538 dma_params->pdc_xfer_size = 2;
0539 break;
0540 case SNDRV_PCM_FORMAT_S24_LE:
0541 bits = 24;
0542 dma_params->pdc_xfer_size = 4;
0543 break;
0544 case SNDRV_PCM_FORMAT_S32_LE:
0545 bits = 32;
0546 dma_params->pdc_xfer_size = 4;
0547 break;
0548 default:
0549 printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
0550 return -EINVAL;
0551 }
0552
0553
0554
0555
0556
0557 fslen_ext = (bits - 1) / 16;
0558 fslen = (bits - 1) % 16;
0559
0560 switch (ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0561
0562 case SND_SOC_DAIFMT_LEFT_J:
0563 fs_osync = SSC_FSOS_POSITIVE;
0564 fs_edge = SSC_START_RISING_RF;
0565
0566 rcmr = SSC_BF(RCMR_STTDLY, 0);
0567 tcmr = SSC_BF(TCMR_STTDLY, 0);
0568
0569 break;
0570
0571 case SND_SOC_DAIFMT_I2S:
0572 fs_osync = SSC_FSOS_NEGATIVE;
0573 fs_edge = SSC_START_FALLING_RF;
0574
0575 rcmr = SSC_BF(RCMR_STTDLY, 1);
0576 tcmr = SSC_BF(TCMR_STTDLY, 1);
0577
0578 break;
0579
0580 case SND_SOC_DAIFMT_DSP_A:
0581
0582
0583
0584
0585
0586
0587
0588 fs_osync = SSC_FSOS_POSITIVE;
0589 fs_edge = SSC_START_RISING_RF;
0590 fslen = fslen_ext = 0;
0591
0592 rcmr = SSC_BF(RCMR_STTDLY, 1);
0593 tcmr = SSC_BF(TCMR_STTDLY, 1);
0594
0595 break;
0596
0597 default:
0598 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
0599 ssc_p->daifmt);
0600 return -EINVAL;
0601 }
0602
0603 if (!atmel_ssc_cfs(ssc_p)) {
0604 fslen = fslen_ext = 0;
0605 rcmr_period = tcmr_period = 0;
0606 fs_osync = SSC_FSOS_NONE;
0607 }
0608
0609 rcmr |= SSC_BF(RCMR_START, fs_edge);
0610 tcmr |= SSC_BF(TCMR_START, fs_edge);
0611
0612 if (atmel_ssc_cbs(ssc_p)) {
0613
0614
0615
0616
0617
0618
0619
0620 rcmr |= SSC_BF(RCMR_CKS, SSC_CKS_DIV)
0621 | SSC_BF(RCMR_CKO, SSC_CKO_NONE);
0622
0623 tcmr |= SSC_BF(TCMR_CKS, SSC_CKS_DIV)
0624 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS);
0625 } else {
0626 rcmr |= SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
0627 SSC_CKS_PIN : SSC_CKS_CLOCK)
0628 | SSC_BF(RCMR_CKO, SSC_CKO_NONE);
0629
0630 tcmr |= SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
0631 SSC_CKS_CLOCK : SSC_CKS_PIN)
0632 | SSC_BF(TCMR_CKO, SSC_CKO_NONE);
0633 }
0634
0635 rcmr |= SSC_BF(RCMR_PERIOD, rcmr_period)
0636 | SSC_BF(RCMR_CKI, SSC_CKI_RISING);
0637
0638 tcmr |= SSC_BF(TCMR_PERIOD, tcmr_period)
0639 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING);
0640
0641 rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
0642 | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
0643 | SSC_BF(RFMR_FSOS, fs_osync)
0644 | SSC_BF(RFMR_FSLEN, fslen)
0645 | SSC_BF(RFMR_DATNB, (channels - 1))
0646 | SSC_BIT(RFMR_MSBF)
0647 | SSC_BF(RFMR_LOOP, 0)
0648 | SSC_BF(RFMR_DATLEN, (bits - 1));
0649
0650 tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
0651 | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
0652 | SSC_BF(TFMR_FSDEN, 0)
0653 | SSC_BF(TFMR_FSOS, fs_osync)
0654 | SSC_BF(TFMR_FSLEN, fslen)
0655 | SSC_BF(TFMR_DATNB, (channels - 1))
0656 | SSC_BIT(TFMR_MSBF)
0657 | SSC_BF(TFMR_DATDEF, 0)
0658 | SSC_BF(TFMR_DATLEN, (bits - 1));
0659
0660 if (fslen_ext && !ssc->pdata->has_fslen_ext) {
0661 dev_err(dai->dev, "sample size %d is too large for SSC device\n",
0662 bits);
0663 return -EINVAL;
0664 }
0665
0666 pr_debug("atmel_ssc_hw_params: "
0667 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
0668 rcmr, rfmr, tcmr, tfmr);
0669
0670 if (!ssc_p->initialized) {
0671 if (!ssc_p->ssc->pdata->use_dma) {
0672 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
0673 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
0674 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
0675 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
0676
0677 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
0678 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
0679 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
0680 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
0681 }
0682
0683 ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
0684 ssc_p->name, ssc_p);
0685 if (ret < 0) {
0686 printk(KERN_WARNING
0687 "atmel_ssc_dai: request_irq failure\n");
0688 pr_debug("Atmel_ssc_dai: Stopping clock\n");
0689 clk_disable(ssc_p->ssc->clk);
0690 return ret;
0691 }
0692
0693 ssc_p->initialized = 1;
0694 }
0695
0696
0697 ssc_writel(ssc_p->ssc->regs, CMR, cmr_div);
0698
0699
0700 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
0701 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
0702
0703
0704 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
0705 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
0706
0707 pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
0708 return 0;
0709 }
0710
0711
0712 static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
0713 struct snd_soc_dai *dai)
0714 {
0715 struct platform_device *pdev = to_platform_device(dai->dev);
0716 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
0717 struct atmel_pcm_dma_params *dma_params;
0718 int dir;
0719
0720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0721 dir = 0;
0722 else
0723 dir = 1;
0724
0725 dma_params = ssc_p->dma_params[dir];
0726
0727 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
0728 ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error);
0729
0730 pr_debug("%s enabled SSC_SR=0x%08x\n",
0731 dir ? "receive" : "transmit",
0732 ssc_readl(ssc_p->ssc->regs, SR));
0733 return 0;
0734 }
0735
0736 static int atmel_ssc_trigger(struct snd_pcm_substream *substream,
0737 int cmd, struct snd_soc_dai *dai)
0738 {
0739 struct platform_device *pdev = to_platform_device(dai->dev);
0740 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
0741 struct atmel_pcm_dma_params *dma_params;
0742 int dir;
0743
0744 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0745 dir = 0;
0746 else
0747 dir = 1;
0748
0749 dma_params = ssc_p->dma_params[dir];
0750
0751 switch (cmd) {
0752 case SNDRV_PCM_TRIGGER_START:
0753 case SNDRV_PCM_TRIGGER_RESUME:
0754 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0755 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
0756 break;
0757 default:
0758 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
0759 break;
0760 }
0761
0762 return 0;
0763 }
0764
0765 static int atmel_ssc_suspend(struct snd_soc_component *component)
0766 {
0767 struct atmel_ssc_info *ssc_p;
0768 struct platform_device *pdev = to_platform_device(component->dev);
0769
0770 if (!snd_soc_component_active(component))
0771 return 0;
0772
0773 ssc_p = &ssc_info[pdev->id];
0774
0775
0776 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
0777 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
0778
0779
0780 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
0781 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
0782
0783 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
0784 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
0785 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
0786 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
0787 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
0788
0789 return 0;
0790 }
0791
0792 static int atmel_ssc_resume(struct snd_soc_component *component)
0793 {
0794 struct atmel_ssc_info *ssc_p;
0795 struct platform_device *pdev = to_platform_device(component->dev);
0796 u32 cr;
0797
0798 if (!snd_soc_component_active(component))
0799 return 0;
0800
0801 ssc_p = &ssc_info[pdev->id];
0802
0803
0804 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
0805 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
0806 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
0807 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
0808 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
0809
0810
0811 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
0812
0813
0814 cr = 0;
0815 cr |=
0816 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
0817 cr |=
0818 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
0819 ssc_writel(ssc_p->ssc->regs, CR, cr);
0820
0821 return 0;
0822 }
0823
0824 #define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
0825 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0826
0827 static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
0828 .startup = atmel_ssc_startup,
0829 .shutdown = atmel_ssc_shutdown,
0830 .prepare = atmel_ssc_prepare,
0831 .trigger = atmel_ssc_trigger,
0832 .hw_params = atmel_ssc_hw_params,
0833 .set_fmt = atmel_ssc_set_dai_fmt,
0834 .set_clkdiv = atmel_ssc_set_dai_clkdiv,
0835 };
0836
0837 static struct snd_soc_dai_driver atmel_ssc_dai = {
0838 .playback = {
0839 .channels_min = 1,
0840 .channels_max = 2,
0841 .rates = SNDRV_PCM_RATE_CONTINUOUS,
0842 .rate_min = 8000,
0843 .rate_max = 384000,
0844 .formats = ATMEL_SSC_FORMATS,},
0845 .capture = {
0846 .channels_min = 1,
0847 .channels_max = 2,
0848 .rates = SNDRV_PCM_RATE_CONTINUOUS,
0849 .rate_min = 8000,
0850 .rate_max = 384000,
0851 .formats = ATMEL_SSC_FORMATS,},
0852 .ops = &atmel_ssc_dai_ops,
0853 };
0854
0855 static const struct snd_soc_component_driver atmel_ssc_component = {
0856 .name = "atmel-ssc",
0857 .suspend = pm_ptr(atmel_ssc_suspend),
0858 .resume = pm_ptr(atmel_ssc_resume),
0859 .legacy_dai_naming = 1,
0860 };
0861
0862 static int asoc_ssc_init(struct device *dev)
0863 {
0864 struct ssc_device *ssc = dev_get_drvdata(dev);
0865 int ret;
0866
0867 ret = devm_snd_soc_register_component(dev, &atmel_ssc_component,
0868 &atmel_ssc_dai, 1);
0869 if (ret) {
0870 dev_err(dev, "Could not register DAI: %d\n", ret);
0871 return ret;
0872 }
0873
0874 if (ssc->pdata->use_dma)
0875 ret = atmel_pcm_dma_platform_register(dev);
0876 else
0877 ret = atmel_pcm_pdc_platform_register(dev);
0878
0879 if (ret) {
0880 dev_err(dev, "Could not register PCM: %d\n", ret);
0881 return ret;
0882 }
0883
0884 return 0;
0885 }
0886
0887
0888
0889
0890
0891 int atmel_ssc_set_audio(int ssc_id)
0892 {
0893 struct ssc_device *ssc;
0894 int ret;
0895
0896
0897 ssc = ssc_request(ssc_id);
0898 if (IS_ERR(ssc)) {
0899 pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
0900 PTR_ERR(ssc));
0901 return PTR_ERR(ssc);
0902 } else {
0903 ssc_info[ssc_id].ssc = ssc;
0904 }
0905
0906 ret = asoc_ssc_init(&ssc->pdev->dev);
0907
0908 return ret;
0909 }
0910 EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
0911
0912 void atmel_ssc_put_audio(int ssc_id)
0913 {
0914 struct ssc_device *ssc = ssc_info[ssc_id].ssc;
0915
0916 ssc_free(ssc);
0917 }
0918 EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
0919
0920
0921 MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
0922 MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
0923 MODULE_LICENSE("GPL");