0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/dmaengine.h>
0009 #include <linux/module.h>
0010 #include <linux/of_irq.h>
0011 #include <linux/of_platform.h>
0012 #include <linux/pm_runtime.h>
0013 #include <sound/dmaengine_pcm.h>
0014 #include <sound/pcm_params.h>
0015
0016 #include "fsl_esai.h"
0017 #include "imx-pcm.h"
0018
0019 #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
0020 SNDRV_PCM_FMTBIT_S16_LE | \
0021 SNDRV_PCM_FMTBIT_S20_3LE | \
0022 SNDRV_PCM_FMTBIT_S24_LE)
0023
0024
0025
0026
0027
0028 struct fsl_esai_soc_data {
0029 bool reset_at_xrun;
0030 };
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 struct fsl_esai {
0060 struct snd_dmaengine_dai_dma_data dma_params_rx;
0061 struct snd_dmaengine_dai_dma_data dma_params_tx;
0062 struct platform_device *pdev;
0063 struct regmap *regmap;
0064 struct clk *coreclk;
0065 struct clk *extalclk;
0066 struct clk *fsysclk;
0067 struct clk *spbaclk;
0068 struct work_struct work;
0069 const struct fsl_esai_soc_data *soc;
0070 spinlock_t lock;
0071 u32 fifo_depth;
0072 u32 slot_width;
0073 u32 slots;
0074 u32 tx_mask;
0075 u32 rx_mask;
0076 u32 channels[2];
0077 u32 hck_rate[2];
0078 u32 sck_rate[2];
0079 bool hck_dir[2];
0080 bool sck_div[2];
0081 bool consumer_mode;
0082 bool synchronous;
0083 char name[32];
0084 };
0085
0086 static struct fsl_esai_soc_data fsl_esai_vf610 = {
0087 .reset_at_xrun = true,
0088 };
0089
0090 static struct fsl_esai_soc_data fsl_esai_imx35 = {
0091 .reset_at_xrun = true,
0092 };
0093
0094 static struct fsl_esai_soc_data fsl_esai_imx6ull = {
0095 .reset_at_xrun = false,
0096 };
0097
0098 static irqreturn_t esai_isr(int irq, void *devid)
0099 {
0100 struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
0101 struct platform_device *pdev = esai_priv->pdev;
0102 u32 esr;
0103 u32 saisr;
0104
0105 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
0106 regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
0107
0108 if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
0109 esai_priv->soc->reset_at_xrun) {
0110 dev_dbg(&pdev->dev, "reset module for xrun\n");
0111 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0112 ESAI_xCR_xEIE_MASK, 0);
0113 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
0114 ESAI_xCR_xEIE_MASK, 0);
0115 schedule_work(&esai_priv->work);
0116 }
0117
0118 if (esr & ESAI_ESR_TINIT_MASK)
0119 dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
0120
0121 if (esr & ESAI_ESR_RFF_MASK)
0122 dev_warn(&pdev->dev, "isr: Receiving overrun\n");
0123
0124 if (esr & ESAI_ESR_TFE_MASK)
0125 dev_warn(&pdev->dev, "isr: Transmission underrun\n");
0126
0127 if (esr & ESAI_ESR_TLS_MASK)
0128 dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
0129
0130 if (esr & ESAI_ESR_TDE_MASK)
0131 dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
0132
0133 if (esr & ESAI_ESR_TED_MASK)
0134 dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
0135
0136 if (esr & ESAI_ESR_TD_MASK)
0137 dev_dbg(&pdev->dev, "isr: Transmitting data\n");
0138
0139 if (esr & ESAI_ESR_RLS_MASK)
0140 dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
0141
0142 if (esr & ESAI_ESR_RDE_MASK)
0143 dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
0144
0145 if (esr & ESAI_ESR_RED_MASK)
0146 dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
0147
0148 if (esr & ESAI_ESR_RD_MASK)
0149 dev_dbg(&pdev->dev, "isr: Receiving data\n");
0150
0151 return IRQ_HANDLED;
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
0166 bool usefp, u32 fp)
0167 {
0168 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0169 u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
0170
0171 maxfp = usefp ? 16 : 1;
0172
0173 if (usefp && fp)
0174 goto out_fp;
0175
0176 if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
0177 dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
0178 2 * 8 * 256 * maxfp);
0179 return -EINVAL;
0180 } else if (ratio % 2) {
0181 dev_err(dai->dev, "the raio must be even if using upper divider\n");
0182 return -EINVAL;
0183 }
0184
0185 ratio /= 2;
0186
0187 psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
0188
0189
0190 if (ratio <= 256) {
0191 pm = ratio;
0192 fp = 1;
0193 goto out;
0194 }
0195
0196
0197 savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
0198
0199
0200 for (i = 1; i <= 256; i++) {
0201 for (j = 1; j <= maxfp; j++) {
0202
0203 prod = (psr ? 1 : 8) * i * j;
0204
0205 if (prod == ratio)
0206 sub = 0;
0207 else if (prod / ratio == 1)
0208 sub = prod - ratio;
0209 else if (ratio / prod == 1)
0210 sub = ratio - prod;
0211 else
0212 continue;
0213
0214
0215 sub = sub * 1000 / ratio;
0216 if (sub < savesub) {
0217 savesub = sub;
0218 pm = i;
0219 fp = j;
0220 }
0221
0222
0223 if (savesub == 0)
0224 goto out;
0225 }
0226 }
0227
0228 if (pm == 999) {
0229 dev_err(dai->dev, "failed to calculate proper divisors\n");
0230 return -EINVAL;
0231 }
0232
0233 out:
0234 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
0235 ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
0236 psr | ESAI_xCCR_xPM(pm));
0237
0238 out_fp:
0239
0240 if (maxfp <= 1)
0241 return 0;
0242
0243 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
0244 ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
0245
0246 return 0;
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
0260 unsigned int freq, int dir)
0261 {
0262 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0263 struct clk *clksrc = esai_priv->extalclk;
0264 bool tx = (clk_id <= ESAI_HCKT_EXTAL || esai_priv->synchronous);
0265 bool in = dir == SND_SOC_CLOCK_IN;
0266 u32 ratio, ecr = 0;
0267 unsigned long clk_rate;
0268 int ret;
0269
0270 if (freq == 0) {
0271 dev_err(dai->dev, "%sput freq of HCK%c should not be 0Hz\n",
0272 in ? "in" : "out", tx ? 'T' : 'R');
0273 return -EINVAL;
0274 }
0275
0276
0277 if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
0278 return 0;
0279
0280
0281 esai_priv->sck_div[tx] = true;
0282
0283
0284 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
0285 ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
0286
0287 if (in)
0288 goto out;
0289
0290 switch (clk_id) {
0291 case ESAI_HCKT_FSYS:
0292 case ESAI_HCKR_FSYS:
0293 clksrc = esai_priv->fsysclk;
0294 break;
0295 case ESAI_HCKT_EXTAL:
0296 ecr |= ESAI_ECR_ETI;
0297 break;
0298 case ESAI_HCKR_EXTAL:
0299 ecr |= esai_priv->synchronous ? ESAI_ECR_ETI : ESAI_ECR_ERI;
0300 break;
0301 default:
0302 return -EINVAL;
0303 }
0304
0305 if (IS_ERR(clksrc)) {
0306 dev_err(dai->dev, "no assigned %s clock\n",
0307 (clk_id % 2) ? "extal" : "fsys");
0308 return PTR_ERR(clksrc);
0309 }
0310 clk_rate = clk_get_rate(clksrc);
0311
0312 ratio = clk_rate / freq;
0313 if (ratio * freq > clk_rate)
0314 ret = ratio * freq - clk_rate;
0315 else if (ratio * freq < clk_rate)
0316 ret = clk_rate - ratio * freq;
0317 else
0318 ret = 0;
0319
0320
0321 if (ret != 0 && clk_rate / ret < 1000) {
0322 dev_err(dai->dev, "failed to derive required HCK%c rate\n",
0323 tx ? 'T' : 'R');
0324 return -EINVAL;
0325 }
0326
0327
0328 if (ratio == 1 && clksrc == esai_priv->extalclk) {
0329
0330 ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
0331 goto out;
0332 } else if (ratio < 2) {
0333
0334 dev_err(dai->dev, "failed to derive required HCK%c rate\n",
0335 tx ? 'T' : 'R');
0336 return -EINVAL;
0337 }
0338
0339 ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
0340 if (ret)
0341 return ret;
0342
0343 esai_priv->sck_div[tx] = false;
0344
0345 out:
0346 esai_priv->hck_dir[tx] = dir;
0347 esai_priv->hck_rate[tx] = freq;
0348
0349 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
0350 tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
0351 ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
0352
0353 return 0;
0354 }
0355
0356
0357
0358
0359
0360
0361
0362 static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
0363 {
0364 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0365 u32 hck_rate = esai_priv->hck_rate[tx];
0366 u32 sub, ratio = hck_rate / freq;
0367 int ret;
0368
0369
0370 if (esai_priv->consumer_mode || esai_priv->sck_rate[tx] == freq)
0371 return 0;
0372
0373 if (ratio * freq > hck_rate)
0374 sub = ratio * freq - hck_rate;
0375 else if (ratio * freq < hck_rate)
0376 sub = hck_rate - ratio * freq;
0377 else
0378 sub = 0;
0379
0380
0381 if (sub != 0 && hck_rate / sub < 1000) {
0382 dev_err(dai->dev, "failed to derive required SCK%c rate\n",
0383 tx ? 'T' : 'R');
0384 return -EINVAL;
0385 }
0386
0387
0388 if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
0389 dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
0390 return -EINVAL;
0391 }
0392
0393 ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
0394 esai_priv->sck_div[tx] ? 0 : ratio);
0395 if (ret)
0396 return ret;
0397
0398
0399 esai_priv->sck_rate[tx] = freq;
0400
0401 return 0;
0402 }
0403
0404 static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
0405 u32 rx_mask, int slots, int slot_width)
0406 {
0407 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0408
0409 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
0410 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
0411
0412 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
0413 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
0414
0415 esai_priv->slot_width = slot_width;
0416 esai_priv->slots = slots;
0417 esai_priv->tx_mask = tx_mask;
0418 esai_priv->rx_mask = rx_mask;
0419
0420 return 0;
0421 }
0422
0423 static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0424 {
0425 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0426 u32 xcr = 0, xccr = 0, mask;
0427
0428
0429 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0430 case SND_SOC_DAIFMT_I2S:
0431
0432 xcr |= ESAI_xCR_xFSR;
0433 xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0434 break;
0435 case SND_SOC_DAIFMT_LEFT_J:
0436
0437 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0438 break;
0439 case SND_SOC_DAIFMT_RIGHT_J:
0440
0441 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0442 xcr |= ESAI_xCR_xWA;
0443 break;
0444 case SND_SOC_DAIFMT_DSP_A:
0445
0446 xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
0447 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0448 break;
0449 case SND_SOC_DAIFMT_DSP_B:
0450
0451 xcr |= ESAI_xCR_xFSL;
0452 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0453 break;
0454 default:
0455 return -EINVAL;
0456 }
0457
0458
0459 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0460 case SND_SOC_DAIFMT_NB_NF:
0461
0462 break;
0463 case SND_SOC_DAIFMT_IB_NF:
0464
0465 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0466 break;
0467 case SND_SOC_DAIFMT_NB_IF:
0468
0469 xccr ^= ESAI_xCCR_xFSP;
0470 break;
0471 case SND_SOC_DAIFMT_IB_IF:
0472
0473 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
0474 break;
0475 default:
0476 return -EINVAL;
0477 }
0478
0479 esai_priv->consumer_mode = false;
0480
0481
0482 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0483 case SND_SOC_DAIFMT_BC_FC:
0484 esai_priv->consumer_mode = true;
0485 break;
0486 case SND_SOC_DAIFMT_BP_FC:
0487 xccr |= ESAI_xCCR_xCKD;
0488 break;
0489 case SND_SOC_DAIFMT_BC_FP:
0490 xccr |= ESAI_xCCR_xFSD;
0491 break;
0492 case SND_SOC_DAIFMT_BP_FP:
0493 xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
0494 break;
0495 default:
0496 return -EINVAL;
0497 }
0498
0499 mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
0500 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
0501 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
0502
0503 mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
0504 ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
0505 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
0506 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
0507
0508 return 0;
0509 }
0510
0511 static int fsl_esai_startup(struct snd_pcm_substream *substream,
0512 struct snd_soc_dai *dai)
0513 {
0514 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0515
0516 if (!snd_soc_dai_active(dai)) {
0517
0518 regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
0519 ESAI_SAICR_SYNC, esai_priv->synchronous ?
0520 ESAI_SAICR_SYNC : 0);
0521
0522
0523 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
0524 ESAI_xCCR_xDC_MASK,
0525 ESAI_xCCR_xDC(esai_priv->slots));
0526 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
0527 ESAI_xCCR_xDC_MASK,
0528 ESAI_xCCR_xDC(esai_priv->slots));
0529 }
0530
0531 return 0;
0532
0533 }
0534
0535 static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
0536 struct snd_pcm_hw_params *params,
0537 struct snd_soc_dai *dai)
0538 {
0539 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0540 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
0541 u32 width = params_width(params);
0542 u32 channels = params_channels(params);
0543 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
0544 u32 slot_width = width;
0545 u32 bclk, mask, val;
0546 int ret;
0547
0548
0549 if (esai_priv->slot_width)
0550 slot_width = esai_priv->slot_width;
0551
0552 bclk = params_rate(params) * slot_width * esai_priv->slots;
0553
0554 ret = fsl_esai_set_bclk(dai, esai_priv->synchronous || tx, bclk);
0555 if (ret)
0556 return ret;
0557
0558 mask = ESAI_xCR_xSWS_MASK;
0559 val = ESAI_xCR_xSWS(slot_width, width);
0560
0561 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
0562
0563 if (!tx && esai_priv->synchronous)
0564 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, val);
0565
0566
0567 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0568 ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
0569 ESAI_xCR_xMOD_NETWORK : 0);
0570
0571 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0572 ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
0573
0574 mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
0575 (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
0576 val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
0577 (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
0578
0579 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
0580
0581 if (tx)
0582 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0583 ESAI_xCR_PADC, ESAI_xCR_PADC);
0584
0585
0586 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
0587 ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
0588 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
0589 ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
0590 return 0;
0591 }
0592
0593 static int fsl_esai_hw_init(struct fsl_esai *esai_priv)
0594 {
0595 struct platform_device *pdev = esai_priv->pdev;
0596 int ret;
0597
0598
0599 ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
0600 ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
0601 ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
0602 if (ret) {
0603 dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
0604 return ret;
0605 }
0606
0607
0608
0609
0610
0611 ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
0612 ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
0613 ESAI_ECR_ESAIEN);
0614 if (ret) {
0615 dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
0616 return ret;
0617 }
0618
0619 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
0620 ESAI_PRRC_PDC_MASK, 0);
0621 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
0622 ESAI_PCRC_PC_MASK, 0);
0623
0624 return 0;
0625 }
0626
0627 static int fsl_esai_register_restore(struct fsl_esai *esai_priv)
0628 {
0629 int ret;
0630
0631
0632 regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR,
0633 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
0634 regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR,
0635 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
0636
0637 regcache_mark_dirty(esai_priv->regmap);
0638 ret = regcache_sync(esai_priv->regmap);
0639 if (ret)
0640 return ret;
0641
0642
0643 regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
0644 regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
0645
0646 return 0;
0647 }
0648
0649 static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx)
0650 {
0651 u8 i, channels = esai_priv->channels[tx];
0652 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
0653 u32 mask;
0654
0655 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0656 ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
0657
0658
0659 for (i = 0; tx && i < channels; i++)
0660 regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0675 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
0676 tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
0677 mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
0678
0679 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
0680 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
0681 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
0682 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
0683
0684
0685 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0686 ESAI_xCR_xEIE_MASK, ESAI_xCR_xEIE);
0687 }
0688
0689 static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
0690 {
0691 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0692 ESAI_xCR_xEIE_MASK, 0);
0693
0694 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0695 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
0696 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
0697 ESAI_xSMA_xS_MASK, 0);
0698 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
0699 ESAI_xSMB_xS_MASK, 0);
0700
0701
0702 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0703 ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
0704 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0705 ESAI_xFCR_xFR, 0);
0706 }
0707
0708 static void fsl_esai_hw_reset(struct work_struct *work)
0709 {
0710 struct fsl_esai *esai_priv = container_of(work, struct fsl_esai, work);
0711 bool tx = true, rx = false, enabled[2];
0712 unsigned long lock_flags;
0713 u32 tfcr, rfcr;
0714
0715 spin_lock_irqsave(&esai_priv->lock, lock_flags);
0716
0717 regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
0718 regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
0719 enabled[tx] = tfcr & ESAI_xFCR_xFEN;
0720 enabled[rx] = rfcr & ESAI_xFCR_xFEN;
0721
0722
0723 fsl_esai_trigger_stop(esai_priv, tx);
0724 fsl_esai_trigger_stop(esai_priv, rx);
0725
0726
0727 fsl_esai_hw_init(esai_priv);
0728
0729
0730 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0731 ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
0732 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
0733 ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
0734
0735
0736 fsl_esai_register_restore(esai_priv);
0737
0738
0739 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0740 ESAI_xCR_xPR_MASK, 0);
0741 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
0742 ESAI_xCR_xPR_MASK, 0);
0743 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
0744 ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
0745 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
0746 ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
0747
0748
0749 if (enabled[tx])
0750 fsl_esai_trigger_start(esai_priv, tx);
0751 if (enabled[rx])
0752 fsl_esai_trigger_start(esai_priv, rx);
0753
0754 spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
0755 }
0756
0757 static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
0758 struct snd_soc_dai *dai)
0759 {
0760 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0761 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
0762 unsigned long lock_flags;
0763
0764 esai_priv->channels[tx] = substream->runtime->channels;
0765
0766 switch (cmd) {
0767 case SNDRV_PCM_TRIGGER_START:
0768 case SNDRV_PCM_TRIGGER_RESUME:
0769 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0770 spin_lock_irqsave(&esai_priv->lock, lock_flags);
0771 fsl_esai_trigger_start(esai_priv, tx);
0772 spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
0773 break;
0774 case SNDRV_PCM_TRIGGER_SUSPEND:
0775 case SNDRV_PCM_TRIGGER_STOP:
0776 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0777 spin_lock_irqsave(&esai_priv->lock, lock_flags);
0778 fsl_esai_trigger_stop(esai_priv, tx);
0779 spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
0780 break;
0781 default:
0782 return -EINVAL;
0783 }
0784
0785 return 0;
0786 }
0787
0788 static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
0789 .startup = fsl_esai_startup,
0790 .trigger = fsl_esai_trigger,
0791 .hw_params = fsl_esai_hw_params,
0792 .set_sysclk = fsl_esai_set_dai_sysclk,
0793 .set_fmt = fsl_esai_set_dai_fmt,
0794 .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
0795 };
0796
0797 static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
0798 {
0799 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0800
0801 snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
0802 &esai_priv->dma_params_rx);
0803
0804 return 0;
0805 }
0806
0807 static struct snd_soc_dai_driver fsl_esai_dai = {
0808 .probe = fsl_esai_dai_probe,
0809 .playback = {
0810 .stream_name = "CPU-Playback",
0811 .channels_min = 1,
0812 .channels_max = 12,
0813 .rates = SNDRV_PCM_RATE_8000_192000,
0814 .formats = FSL_ESAI_FORMATS,
0815 },
0816 .capture = {
0817 .stream_name = "CPU-Capture",
0818 .channels_min = 1,
0819 .channels_max = 8,
0820 .rates = SNDRV_PCM_RATE_8000_192000,
0821 .formats = FSL_ESAI_FORMATS,
0822 },
0823 .ops = &fsl_esai_dai_ops,
0824 };
0825
0826 static const struct snd_soc_component_driver fsl_esai_component = {
0827 .name = "fsl-esai",
0828 .legacy_dai_naming = 1,
0829 };
0830
0831 static const struct reg_default fsl_esai_reg_defaults[] = {
0832 {REG_ESAI_ETDR, 0x00000000},
0833 {REG_ESAI_ECR, 0x00000000},
0834 {REG_ESAI_TFCR, 0x00000000},
0835 {REG_ESAI_RFCR, 0x00000000},
0836 {REG_ESAI_TX0, 0x00000000},
0837 {REG_ESAI_TX1, 0x00000000},
0838 {REG_ESAI_TX2, 0x00000000},
0839 {REG_ESAI_TX3, 0x00000000},
0840 {REG_ESAI_TX4, 0x00000000},
0841 {REG_ESAI_TX5, 0x00000000},
0842 {REG_ESAI_TSR, 0x00000000},
0843 {REG_ESAI_SAICR, 0x00000000},
0844 {REG_ESAI_TCR, 0x00000000},
0845 {REG_ESAI_TCCR, 0x00000000},
0846 {REG_ESAI_RCR, 0x00000000},
0847 {REG_ESAI_RCCR, 0x00000000},
0848 {REG_ESAI_TSMA, 0x0000ffff},
0849 {REG_ESAI_TSMB, 0x0000ffff},
0850 {REG_ESAI_RSMA, 0x0000ffff},
0851 {REG_ESAI_RSMB, 0x0000ffff},
0852 {REG_ESAI_PRRC, 0x00000000},
0853 {REG_ESAI_PCRC, 0x00000000},
0854 };
0855
0856 static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
0857 {
0858 switch (reg) {
0859 case REG_ESAI_ERDR:
0860 case REG_ESAI_ECR:
0861 case REG_ESAI_ESR:
0862 case REG_ESAI_TFCR:
0863 case REG_ESAI_TFSR:
0864 case REG_ESAI_RFCR:
0865 case REG_ESAI_RFSR:
0866 case REG_ESAI_RX0:
0867 case REG_ESAI_RX1:
0868 case REG_ESAI_RX2:
0869 case REG_ESAI_RX3:
0870 case REG_ESAI_SAISR:
0871 case REG_ESAI_SAICR:
0872 case REG_ESAI_TCR:
0873 case REG_ESAI_TCCR:
0874 case REG_ESAI_RCR:
0875 case REG_ESAI_RCCR:
0876 case REG_ESAI_TSMA:
0877 case REG_ESAI_TSMB:
0878 case REG_ESAI_RSMA:
0879 case REG_ESAI_RSMB:
0880 case REG_ESAI_PRRC:
0881 case REG_ESAI_PCRC:
0882 return true;
0883 default:
0884 return false;
0885 }
0886 }
0887
0888 static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
0889 {
0890 switch (reg) {
0891 case REG_ESAI_ERDR:
0892 case REG_ESAI_ESR:
0893 case REG_ESAI_TFSR:
0894 case REG_ESAI_RFSR:
0895 case REG_ESAI_RX0:
0896 case REG_ESAI_RX1:
0897 case REG_ESAI_RX2:
0898 case REG_ESAI_RX3:
0899 case REG_ESAI_SAISR:
0900 return true;
0901 default:
0902 return false;
0903 }
0904 }
0905
0906 static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
0907 {
0908 switch (reg) {
0909 case REG_ESAI_ETDR:
0910 case REG_ESAI_ECR:
0911 case REG_ESAI_TFCR:
0912 case REG_ESAI_RFCR:
0913 case REG_ESAI_TX0:
0914 case REG_ESAI_TX1:
0915 case REG_ESAI_TX2:
0916 case REG_ESAI_TX3:
0917 case REG_ESAI_TX4:
0918 case REG_ESAI_TX5:
0919 case REG_ESAI_TSR:
0920 case REG_ESAI_SAICR:
0921 case REG_ESAI_TCR:
0922 case REG_ESAI_TCCR:
0923 case REG_ESAI_RCR:
0924 case REG_ESAI_RCCR:
0925 case REG_ESAI_TSMA:
0926 case REG_ESAI_TSMB:
0927 case REG_ESAI_RSMA:
0928 case REG_ESAI_RSMB:
0929 case REG_ESAI_PRRC:
0930 case REG_ESAI_PCRC:
0931 return true;
0932 default:
0933 return false;
0934 }
0935 }
0936
0937 static const struct regmap_config fsl_esai_regmap_config = {
0938 .reg_bits = 32,
0939 .reg_stride = 4,
0940 .val_bits = 32,
0941
0942 .max_register = REG_ESAI_PCRC,
0943 .reg_defaults = fsl_esai_reg_defaults,
0944 .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
0945 .readable_reg = fsl_esai_readable_reg,
0946 .volatile_reg = fsl_esai_volatile_reg,
0947 .writeable_reg = fsl_esai_writeable_reg,
0948 .cache_type = REGCACHE_FLAT,
0949 };
0950
0951 static int fsl_esai_runtime_resume(struct device *dev);
0952 static int fsl_esai_runtime_suspend(struct device *dev);
0953
0954 static int fsl_esai_probe(struct platform_device *pdev)
0955 {
0956 struct device_node *np = pdev->dev.of_node;
0957 struct fsl_esai *esai_priv;
0958 struct resource *res;
0959 const __be32 *iprop;
0960 void __iomem *regs;
0961 int irq, ret;
0962
0963 esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
0964 if (!esai_priv)
0965 return -ENOMEM;
0966
0967 esai_priv->pdev = pdev;
0968 snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
0969
0970 esai_priv->soc = of_device_get_match_data(&pdev->dev);
0971
0972
0973 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
0974 if (IS_ERR(regs))
0975 return PTR_ERR(regs);
0976
0977 esai_priv->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_esai_regmap_config);
0978 if (IS_ERR(esai_priv->regmap)) {
0979 dev_err(&pdev->dev, "failed to init regmap: %ld\n",
0980 PTR_ERR(esai_priv->regmap));
0981 return PTR_ERR(esai_priv->regmap);
0982 }
0983
0984 esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
0985 if (IS_ERR(esai_priv->coreclk)) {
0986 dev_err(&pdev->dev, "failed to get core clock: %ld\n",
0987 PTR_ERR(esai_priv->coreclk));
0988 return PTR_ERR(esai_priv->coreclk);
0989 }
0990
0991 esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
0992 if (IS_ERR(esai_priv->extalclk))
0993 dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
0994 PTR_ERR(esai_priv->extalclk));
0995
0996 esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
0997 if (IS_ERR(esai_priv->fsysclk))
0998 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
0999 PTR_ERR(esai_priv->fsysclk));
1000
1001 esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
1002 if (IS_ERR(esai_priv->spbaclk))
1003 dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
1004 PTR_ERR(esai_priv->spbaclk));
1005
1006 irq = platform_get_irq(pdev, 0);
1007 if (irq < 0)
1008 return irq;
1009
1010 ret = devm_request_irq(&pdev->dev, irq, esai_isr, IRQF_SHARED,
1011 esai_priv->name, esai_priv);
1012 if (ret) {
1013 dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
1014 return ret;
1015 }
1016
1017
1018 esai_priv->slots = 2;
1019
1020
1021 esai_priv->consumer_mode = true;
1022
1023
1024 iprop = of_get_property(np, "fsl,fifo-depth", NULL);
1025 if (iprop)
1026 esai_priv->fifo_depth = be32_to_cpup(iprop);
1027 else
1028 esai_priv->fifo_depth = 64;
1029
1030 esai_priv->dma_params_tx.maxburst = 16;
1031 esai_priv->dma_params_rx.maxburst = 16;
1032 esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
1033 esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
1034
1035 esai_priv->synchronous =
1036 of_property_read_bool(np, "fsl,esai-synchronous");
1037
1038
1039 if (esai_priv->synchronous) {
1040 fsl_esai_dai.symmetric_rate = 1;
1041 fsl_esai_dai.symmetric_channels = 1;
1042 fsl_esai_dai.symmetric_sample_bits = 1;
1043 }
1044
1045 dev_set_drvdata(&pdev->dev, esai_priv);
1046 spin_lock_init(&esai_priv->lock);
1047 pm_runtime_enable(&pdev->dev);
1048 if (!pm_runtime_enabled(&pdev->dev)) {
1049 ret = fsl_esai_runtime_resume(&pdev->dev);
1050 if (ret)
1051 goto err_pm_disable;
1052 }
1053
1054 ret = pm_runtime_resume_and_get(&pdev->dev);
1055 if (ret < 0)
1056 goto err_pm_get_sync;
1057
1058 ret = fsl_esai_hw_init(esai_priv);
1059 if (ret)
1060 goto err_pm_get_sync;
1061
1062 esai_priv->tx_mask = 0xFFFFFFFF;
1063 esai_priv->rx_mask = 0xFFFFFFFF;
1064
1065
1066 regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0);
1067 regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0);
1068 regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0);
1069 regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
1070
1071 ret = pm_runtime_put_sync(&pdev->dev);
1072 if (ret < 0)
1073 goto err_pm_get_sync;
1074
1075
1076
1077
1078
1079 ret = imx_pcm_dma_init(pdev);
1080 if (ret) {
1081 dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
1082 goto err_pm_get_sync;
1083 }
1084
1085 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
1086 &fsl_esai_dai, 1);
1087 if (ret) {
1088 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
1089 goto err_pm_get_sync;
1090 }
1091
1092 INIT_WORK(&esai_priv->work, fsl_esai_hw_reset);
1093
1094 return ret;
1095
1096 err_pm_get_sync:
1097 if (!pm_runtime_status_suspended(&pdev->dev))
1098 fsl_esai_runtime_suspend(&pdev->dev);
1099 err_pm_disable:
1100 pm_runtime_disable(&pdev->dev);
1101 return ret;
1102 }
1103
1104 static int fsl_esai_remove(struct platform_device *pdev)
1105 {
1106 struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
1107
1108 pm_runtime_disable(&pdev->dev);
1109 if (!pm_runtime_status_suspended(&pdev->dev))
1110 fsl_esai_runtime_suspend(&pdev->dev);
1111
1112 cancel_work_sync(&esai_priv->work);
1113
1114 return 0;
1115 }
1116
1117 static const struct of_device_id fsl_esai_dt_ids[] = {
1118 { .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
1119 { .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
1120 { .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
1121 {}
1122 };
1123 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
1124
1125 static int fsl_esai_runtime_resume(struct device *dev)
1126 {
1127 struct fsl_esai *esai = dev_get_drvdata(dev);
1128 int ret;
1129
1130
1131
1132
1133
1134 ret = clk_prepare_enable(esai->coreclk);
1135 if (ret)
1136 return ret;
1137 if (!IS_ERR(esai->spbaclk)) {
1138 ret = clk_prepare_enable(esai->spbaclk);
1139 if (ret)
1140 goto err_spbaclk;
1141 }
1142 if (!IS_ERR(esai->extalclk)) {
1143 ret = clk_prepare_enable(esai->extalclk);
1144 if (ret)
1145 goto err_extalclk;
1146 }
1147 if (!IS_ERR(esai->fsysclk)) {
1148 ret = clk_prepare_enable(esai->fsysclk);
1149 if (ret)
1150 goto err_fsysclk;
1151 }
1152
1153 regcache_cache_only(esai->regmap, false);
1154
1155 ret = fsl_esai_register_restore(esai);
1156 if (ret)
1157 goto err_regcache_sync;
1158
1159 return 0;
1160
1161 err_regcache_sync:
1162 if (!IS_ERR(esai->fsysclk))
1163 clk_disable_unprepare(esai->fsysclk);
1164 err_fsysclk:
1165 if (!IS_ERR(esai->extalclk))
1166 clk_disable_unprepare(esai->extalclk);
1167 err_extalclk:
1168 if (!IS_ERR(esai->spbaclk))
1169 clk_disable_unprepare(esai->spbaclk);
1170 err_spbaclk:
1171 clk_disable_unprepare(esai->coreclk);
1172
1173 return ret;
1174 }
1175
1176 static int fsl_esai_runtime_suspend(struct device *dev)
1177 {
1178 struct fsl_esai *esai = dev_get_drvdata(dev);
1179
1180 regcache_cache_only(esai->regmap, true);
1181
1182 if (!IS_ERR(esai->fsysclk))
1183 clk_disable_unprepare(esai->fsysclk);
1184 if (!IS_ERR(esai->extalclk))
1185 clk_disable_unprepare(esai->extalclk);
1186 if (!IS_ERR(esai->spbaclk))
1187 clk_disable_unprepare(esai->spbaclk);
1188 clk_disable_unprepare(esai->coreclk);
1189
1190 return 0;
1191 }
1192
1193 static const struct dev_pm_ops fsl_esai_pm_ops = {
1194 SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
1195 fsl_esai_runtime_resume,
1196 NULL)
1197 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1198 pm_runtime_force_resume)
1199 };
1200
1201 static struct platform_driver fsl_esai_driver = {
1202 .probe = fsl_esai_probe,
1203 .remove = fsl_esai_remove,
1204 .driver = {
1205 .name = "fsl-esai-dai",
1206 .pm = &fsl_esai_pm_ops,
1207 .of_match_table = fsl_esai_dt_ids,
1208 },
1209 };
1210
1211 module_platform_driver(fsl_esai_driver);
1212
1213 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1214 MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
1215 MODULE_LICENSE("GPL v2");
1216 MODULE_ALIAS("platform:fsl-esai-dai");