1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver 4 // 5 // Copyright (C) 2014 Freescale Semiconductor, Inc. 6 7 #include <linux/clk.h> 8 #include <linux/dmaengine.h> 9 #include <linux/module.h> 10 #include <linux/of_irq.h> 11 #include <linux/of_platform.h> 12 #include <sound/dmaengine_pcm.h> 13 #include <sound/pcm_params.h> 14 15 #include "fsl_esai.h" 16 #include "imx-pcm.h" 17 18 #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 19 SNDRV_PCM_FMTBIT_S16_LE | \ 20 SNDRV_PCM_FMTBIT_S20_3LE | \ 21 SNDRV_PCM_FMTBIT_S24_LE) 22 23 /** 24 * fsl_esai: ESAI private data 25 * 26 * @dma_params_rx: DMA parameters for receive channel 27 * @dma_params_tx: DMA parameters for transmit channel 28 * @pdev: platform device pointer 29 * @regmap: regmap handler 30 * @coreclk: clock source to access register 31 * @extalclk: esai clock source to derive HCK, SCK and FS 32 * @fsysclk: system clock source to derive HCK, SCK and FS 33 * @spbaclk: SPBA clock (optional, depending on SoC design) 34 * @fifo_depth: depth of tx/rx FIFO 35 * @slot_width: width of each DAI slot 36 * @slots: number of slots 37 * @hck_rate: clock rate of desired HCKx clock 38 * @sck_rate: clock rate of desired SCKx clock 39 * @hck_dir: the direction of HCKx pads 40 * @sck_div: if using PSR/PM dividers for SCKx clock 41 * @slave_mode: if fully using DAI slave mode 42 * @synchronous: if using tx/rx synchronous mode 43 * @name: driver name 44 */ 45 struct fsl_esai { 46 struct snd_dmaengine_dai_dma_data dma_params_rx; 47 struct snd_dmaengine_dai_dma_data dma_params_tx; 48 struct platform_device *pdev; 49 struct regmap *regmap; 50 struct clk *coreclk; 51 struct clk *extalclk; 52 struct clk *fsysclk; 53 struct clk *spbaclk; 54 u32 fifo_depth; 55 u32 slot_width; 56 u32 slots; 57 u32 hck_rate[2]; 58 u32 sck_rate[2]; 59 bool hck_dir[2]; 60 bool sck_div[2]; 61 bool slave_mode; 62 bool synchronous; 63 char name[32]; 64 }; 65 66 static irqreturn_t esai_isr(int irq, void *devid) 67 { 68 struct fsl_esai *esai_priv = (struct fsl_esai *)devid; 69 struct platform_device *pdev = esai_priv->pdev; 70 u32 esr; 71 72 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); 73 74 if (esr & ESAI_ESR_TINIT_MASK) 75 dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); 76 77 if (esr & ESAI_ESR_RFF_MASK) 78 dev_warn(&pdev->dev, "isr: Receiving overrun\n"); 79 80 if (esr & ESAI_ESR_TFE_MASK) 81 dev_warn(&pdev->dev, "isr: Transmission underrun\n"); 82 83 if (esr & ESAI_ESR_TLS_MASK) 84 dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); 85 86 if (esr & ESAI_ESR_TDE_MASK) 87 dev_dbg(&pdev->dev, "isr: Transmission data exception\n"); 88 89 if (esr & ESAI_ESR_TED_MASK) 90 dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); 91 92 if (esr & ESAI_ESR_TD_MASK) 93 dev_dbg(&pdev->dev, "isr: Transmitting data\n"); 94 95 if (esr & ESAI_ESR_RLS_MASK) 96 dev_dbg(&pdev->dev, "isr: Just received the last slot\n"); 97 98 if (esr & ESAI_ESR_RDE_MASK) 99 dev_dbg(&pdev->dev, "isr: Receiving data exception\n"); 100 101 if (esr & ESAI_ESR_RED_MASK) 102 dev_dbg(&pdev->dev, "isr: Receiving even slots\n"); 103 104 if (esr & ESAI_ESR_RD_MASK) 105 dev_dbg(&pdev->dev, "isr: Receiving data\n"); 106 107 return IRQ_HANDLED; 108 } 109 110 /** 111 * This function is used to calculate the divisors of psr, pm, fp and it is 112 * supposed to be called in set_dai_sysclk() and set_bclk(). 113 * 114 * @ratio: desired overall ratio for the paticipating dividers 115 * @usefp: for HCK setting, there is no need to set fp divider 116 * @fp: bypass other dividers by setting fp directly if fp != 0 117 * @tx: current setting is for playback or capture 118 */ 119 static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio, 120 bool usefp, u32 fp) 121 { 122 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 123 u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j; 124 125 maxfp = usefp ? 16 : 1; 126 127 if (usefp && fp) 128 goto out_fp; 129 130 if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) { 131 dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n", 132 2 * 8 * 256 * maxfp); 133 return -EINVAL; 134 } else if (ratio % 2) { 135 dev_err(dai->dev, "the raio must be even if using upper divider\n"); 136 return -EINVAL; 137 } 138 139 ratio /= 2; 140 141 psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8; 142 143 /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */ 144 if (ratio <= 256) { 145 pm = ratio; 146 fp = 1; 147 goto out; 148 } 149 150 /* Set the max fluctuation -- 0.1% of the max devisor */ 151 savesub = (psr ? 1 : 8) * 256 * maxfp / 1000; 152 153 /* Find the best value for PM */ 154 for (i = 1; i <= 256; i++) { 155 for (j = 1; j <= maxfp; j++) { 156 /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */ 157 prod = (psr ? 1 : 8) * i * j; 158 159 if (prod == ratio) 160 sub = 0; 161 else if (prod / ratio == 1) 162 sub = prod - ratio; 163 else if (ratio / prod == 1) 164 sub = ratio - prod; 165 else 166 continue; 167 168 /* Calculate the fraction */ 169 sub = sub * 1000 / ratio; 170 if (sub < savesub) { 171 savesub = sub; 172 pm = i; 173 fp = j; 174 } 175 176 /* We are lucky */ 177 if (savesub == 0) 178 goto out; 179 } 180 } 181 182 if (pm == 999) { 183 dev_err(dai->dev, "failed to calculate proper divisors\n"); 184 return -EINVAL; 185 } 186 187 out: 188 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), 189 ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK, 190 psr | ESAI_xCCR_xPM(pm)); 191 192 out_fp: 193 /* Bypass fp if not being required */ 194 if (maxfp <= 1) 195 return 0; 196 197 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), 198 ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp)); 199 200 return 0; 201 } 202 203 /** 204 * This function mainly configures the clock frequency of MCLK (HCKT/HCKR) 205 * 206 * @Parameters: 207 * clk_id: The clock source of HCKT/HCKR 208 * (Input from outside; output from inside, FSYS or EXTAL) 209 * freq: The required clock rate of HCKT/HCKR 210 * dir: The clock direction of HCKT/HCKR 211 * 212 * Note: If the direction is input, we do not care about clk_id. 213 */ 214 static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 215 unsigned int freq, int dir) 216 { 217 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 218 struct clk *clksrc = esai_priv->extalclk; 219 bool tx = clk_id <= ESAI_HCKT_EXTAL; 220 bool in = dir == SND_SOC_CLOCK_IN; 221 u32 ratio, ecr = 0; 222 unsigned long clk_rate; 223 int ret; 224 225 if (freq == 0) { 226 dev_err(dai->dev, "%sput freq of HCK%c should not be 0Hz\n", 227 in ? "in" : "out", tx ? 'T' : 'R'); 228 return -EINVAL; 229 } 230 231 /* Bypass divider settings if the requirement doesn't change */ 232 if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx]) 233 return 0; 234 235 /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ 236 esai_priv->sck_div[tx] = true; 237 238 /* Set the direction of HCKT/HCKR pins */ 239 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), 240 ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD); 241 242 if (in) 243 goto out; 244 245 switch (clk_id) { 246 case ESAI_HCKT_FSYS: 247 case ESAI_HCKR_FSYS: 248 clksrc = esai_priv->fsysclk; 249 break; 250 case ESAI_HCKT_EXTAL: 251 ecr |= ESAI_ECR_ETI; 252 case ESAI_HCKR_EXTAL: 253 ecr |= ESAI_ECR_ERI; 254 break; 255 default: 256 return -EINVAL; 257 } 258 259 if (IS_ERR(clksrc)) { 260 dev_err(dai->dev, "no assigned %s clock\n", 261 clk_id % 2 ? "extal" : "fsys"); 262 return PTR_ERR(clksrc); 263 } 264 clk_rate = clk_get_rate(clksrc); 265 266 ratio = clk_rate / freq; 267 if (ratio * freq > clk_rate) 268 ret = ratio * freq - clk_rate; 269 else if (ratio * freq < clk_rate) 270 ret = clk_rate - ratio * freq; 271 else 272 ret = 0; 273 274 /* Block if clock source can not be divided into the required rate */ 275 if (ret != 0 && clk_rate / ret < 1000) { 276 dev_err(dai->dev, "failed to derive required HCK%c rate\n", 277 tx ? 'T' : 'R'); 278 return -EINVAL; 279 } 280 281 /* Only EXTAL source can be output directly without using PSR and PM */ 282 if (ratio == 1 && clksrc == esai_priv->extalclk) { 283 /* Bypass all the dividers if not being needed */ 284 ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO; 285 goto out; 286 } else if (ratio < 2) { 287 /* The ratio should be no less than 2 if using other sources */ 288 dev_err(dai->dev, "failed to derive required HCK%c rate\n", 289 tx ? 'T' : 'R'); 290 return -EINVAL; 291 } 292 293 ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0); 294 if (ret) 295 return ret; 296 297 esai_priv->sck_div[tx] = false; 298 299 out: 300 esai_priv->hck_dir[tx] = dir; 301 esai_priv->hck_rate[tx] = freq; 302 303 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, 304 tx ? ESAI_ECR_ETI | ESAI_ECR_ETO : 305 ESAI_ECR_ERI | ESAI_ECR_ERO, ecr); 306 307 return 0; 308 } 309 310 /** 311 * This function configures the related dividers according to the bclk rate 312 */ 313 static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) 314 { 315 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 316 u32 hck_rate = esai_priv->hck_rate[tx]; 317 u32 sub, ratio = hck_rate / freq; 318 int ret; 319 320 /* Don't apply for fully slave mode or unchanged bclk */ 321 if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq) 322 return 0; 323 324 if (ratio * freq > hck_rate) 325 sub = ratio * freq - hck_rate; 326 else if (ratio * freq < hck_rate) 327 sub = hck_rate - ratio * freq; 328 else 329 sub = 0; 330 331 /* Block if clock source can not be divided into the required rate */ 332 if (sub != 0 && hck_rate / sub < 1000) { 333 dev_err(dai->dev, "failed to derive required SCK%c rate\n", 334 tx ? 'T' : 'R'); 335 return -EINVAL; 336 } 337 338 /* The ratio should be contented by FP alone if bypassing PM and PSR */ 339 if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) { 340 dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n"); 341 return -EINVAL; 342 } 343 344 ret = fsl_esai_divisor_cal(dai, tx, ratio, true, 345 esai_priv->sck_div[tx] ? 0 : ratio); 346 if (ret) 347 return ret; 348 349 /* Save current bclk rate */ 350 esai_priv->sck_rate[tx] = freq; 351 352 return 0; 353 } 354 355 static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, 356 u32 rx_mask, int slots, int slot_width) 357 { 358 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 359 360 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, 361 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); 362 363 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, 364 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); 365 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, 366 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); 367 368 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, 369 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); 370 371 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, 372 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); 373 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, 374 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); 375 376 esai_priv->slot_width = slot_width; 377 esai_priv->slots = slots; 378 379 return 0; 380 } 381 382 static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 383 { 384 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 385 u32 xcr = 0, xccr = 0, mask; 386 387 /* DAI mode */ 388 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 389 case SND_SOC_DAIFMT_I2S: 390 /* Data on rising edge of bclk, frame low, 1clk before data */ 391 xcr |= ESAI_xCR_xFSR; 392 xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; 393 break; 394 case SND_SOC_DAIFMT_LEFT_J: 395 /* Data on rising edge of bclk, frame high */ 396 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; 397 break; 398 case SND_SOC_DAIFMT_RIGHT_J: 399 /* Data on rising edge of bclk, frame high, right aligned */ 400 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA; 401 break; 402 case SND_SOC_DAIFMT_DSP_A: 403 /* Data on rising edge of bclk, frame high, 1clk before data */ 404 xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR; 405 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; 406 break; 407 case SND_SOC_DAIFMT_DSP_B: 408 /* Data on rising edge of bclk, frame high */ 409 xcr |= ESAI_xCR_xFSL; 410 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; 411 break; 412 default: 413 return -EINVAL; 414 } 415 416 /* DAI clock inversion */ 417 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 418 case SND_SOC_DAIFMT_NB_NF: 419 /* Nothing to do for both normal cases */ 420 break; 421 case SND_SOC_DAIFMT_IB_NF: 422 /* Invert bit clock */ 423 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; 424 break; 425 case SND_SOC_DAIFMT_NB_IF: 426 /* Invert frame clock */ 427 xccr ^= ESAI_xCCR_xFSP; 428 break; 429 case SND_SOC_DAIFMT_IB_IF: 430 /* Invert both clocks */ 431 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP; 432 break; 433 default: 434 return -EINVAL; 435 } 436 437 esai_priv->slave_mode = false; 438 439 /* DAI clock master masks */ 440 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 441 case SND_SOC_DAIFMT_CBM_CFM: 442 esai_priv->slave_mode = true; 443 break; 444 case SND_SOC_DAIFMT_CBS_CFM: 445 xccr |= ESAI_xCCR_xCKD; 446 break; 447 case SND_SOC_DAIFMT_CBM_CFS: 448 xccr |= ESAI_xCCR_xFSD; 449 break; 450 case SND_SOC_DAIFMT_CBS_CFS: 451 xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD; 452 break; 453 default: 454 return -EINVAL; 455 } 456 457 mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR; 458 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr); 459 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr); 460 461 mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP | 462 ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA; 463 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr); 464 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr); 465 466 return 0; 467 } 468 469 static int fsl_esai_startup(struct snd_pcm_substream *substream, 470 struct snd_soc_dai *dai) 471 { 472 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 473 int ret; 474 475 /* 476 * Some platforms might use the same bit to gate all three or two of 477 * clocks, so keep all clocks open/close at the same time for safety 478 */ 479 ret = clk_prepare_enable(esai_priv->coreclk); 480 if (ret) 481 return ret; 482 if (!IS_ERR(esai_priv->spbaclk)) { 483 ret = clk_prepare_enable(esai_priv->spbaclk); 484 if (ret) 485 goto err_spbaclk; 486 } 487 if (!IS_ERR(esai_priv->extalclk)) { 488 ret = clk_prepare_enable(esai_priv->extalclk); 489 if (ret) 490 goto err_extalck; 491 } 492 if (!IS_ERR(esai_priv->fsysclk)) { 493 ret = clk_prepare_enable(esai_priv->fsysclk); 494 if (ret) 495 goto err_fsysclk; 496 } 497 498 if (!dai->active) { 499 /* Set synchronous mode */ 500 regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR, 501 ESAI_SAICR_SYNC, esai_priv->synchronous ? 502 ESAI_SAICR_SYNC : 0); 503 504 /* Set a default slot number -- 2 */ 505 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, 506 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2)); 507 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, 508 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2)); 509 } 510 511 return 0; 512 513 err_fsysclk: 514 if (!IS_ERR(esai_priv->extalclk)) 515 clk_disable_unprepare(esai_priv->extalclk); 516 err_extalck: 517 if (!IS_ERR(esai_priv->spbaclk)) 518 clk_disable_unprepare(esai_priv->spbaclk); 519 err_spbaclk: 520 clk_disable_unprepare(esai_priv->coreclk); 521 522 return ret; 523 } 524 525 static int fsl_esai_hw_params(struct snd_pcm_substream *substream, 526 struct snd_pcm_hw_params *params, 527 struct snd_soc_dai *dai) 528 { 529 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 530 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 531 u32 width = params_width(params); 532 u32 channels = params_channels(params); 533 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); 534 u32 slot_width = width; 535 u32 bclk, mask, val; 536 int ret; 537 538 /* Override slot_width if being specifically set */ 539 if (esai_priv->slot_width) 540 slot_width = esai_priv->slot_width; 541 542 bclk = params_rate(params) * slot_width * esai_priv->slots; 543 544 ret = fsl_esai_set_bclk(dai, tx, bclk); 545 if (ret) 546 return ret; 547 548 /* Use Normal mode to support monaural audio */ 549 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), 550 ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ? 551 ESAI_xCR_xMOD_NETWORK : 0); 552 553 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), 554 ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR); 555 556 mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | 557 (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); 558 val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | 559 (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins)); 560 561 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); 562 563 mask = ESAI_xCR_xSWS_MASK | (tx ? ESAI_xCR_PADC : 0); 564 val = ESAI_xCR_xSWS(slot_width, width) | (tx ? ESAI_xCR_PADC : 0); 565 566 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val); 567 568 /* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */ 569 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, 570 ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO)); 571 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, 572 ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO)); 573 return 0; 574 } 575 576 static void fsl_esai_shutdown(struct snd_pcm_substream *substream, 577 struct snd_soc_dai *dai) 578 { 579 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 580 581 if (!IS_ERR(esai_priv->fsysclk)) 582 clk_disable_unprepare(esai_priv->fsysclk); 583 if (!IS_ERR(esai_priv->extalclk)) 584 clk_disable_unprepare(esai_priv->extalclk); 585 if (!IS_ERR(esai_priv->spbaclk)) 586 clk_disable_unprepare(esai_priv->spbaclk); 587 clk_disable_unprepare(esai_priv->coreclk); 588 } 589 590 static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, 591 struct snd_soc_dai *dai) 592 { 593 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 594 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 595 u8 i, channels = substream->runtime->channels; 596 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); 597 598 switch (cmd) { 599 case SNDRV_PCM_TRIGGER_START: 600 case SNDRV_PCM_TRIGGER_RESUME: 601 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 602 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), 603 ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN); 604 605 /* Write initial words reqiured by ESAI as normal procedure */ 606 for (i = 0; tx && i < channels; i++) 607 regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); 608 609 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), 610 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 611 tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); 612 break; 613 case SNDRV_PCM_TRIGGER_SUSPEND: 614 case SNDRV_PCM_TRIGGER_STOP: 615 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 616 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), 617 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); 618 619 /* Disable and reset FIFO */ 620 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), 621 ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR); 622 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), 623 ESAI_xFCR_xFR, 0); 624 break; 625 default: 626 return -EINVAL; 627 } 628 629 return 0; 630 } 631 632 static const struct snd_soc_dai_ops fsl_esai_dai_ops = { 633 .startup = fsl_esai_startup, 634 .shutdown = fsl_esai_shutdown, 635 .trigger = fsl_esai_trigger, 636 .hw_params = fsl_esai_hw_params, 637 .set_sysclk = fsl_esai_set_dai_sysclk, 638 .set_fmt = fsl_esai_set_dai_fmt, 639 .set_tdm_slot = fsl_esai_set_dai_tdm_slot, 640 }; 641 642 static int fsl_esai_dai_probe(struct snd_soc_dai *dai) 643 { 644 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 645 646 snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx, 647 &esai_priv->dma_params_rx); 648 649 return 0; 650 } 651 652 static struct snd_soc_dai_driver fsl_esai_dai = { 653 .probe = fsl_esai_dai_probe, 654 .playback = { 655 .stream_name = "CPU-Playback", 656 .channels_min = 1, 657 .channels_max = 12, 658 .rates = SNDRV_PCM_RATE_8000_192000, 659 .formats = FSL_ESAI_FORMATS, 660 }, 661 .capture = { 662 .stream_name = "CPU-Capture", 663 .channels_min = 1, 664 .channels_max = 8, 665 .rates = SNDRV_PCM_RATE_8000_192000, 666 .formats = FSL_ESAI_FORMATS, 667 }, 668 .ops = &fsl_esai_dai_ops, 669 }; 670 671 static const struct snd_soc_component_driver fsl_esai_component = { 672 .name = "fsl-esai", 673 }; 674 675 static const struct reg_default fsl_esai_reg_defaults[] = { 676 {REG_ESAI_ETDR, 0x00000000}, 677 {REG_ESAI_ECR, 0x00000000}, 678 {REG_ESAI_TFCR, 0x00000000}, 679 {REG_ESAI_RFCR, 0x00000000}, 680 {REG_ESAI_TX0, 0x00000000}, 681 {REG_ESAI_TX1, 0x00000000}, 682 {REG_ESAI_TX2, 0x00000000}, 683 {REG_ESAI_TX3, 0x00000000}, 684 {REG_ESAI_TX4, 0x00000000}, 685 {REG_ESAI_TX5, 0x00000000}, 686 {REG_ESAI_TSR, 0x00000000}, 687 {REG_ESAI_SAICR, 0x00000000}, 688 {REG_ESAI_TCR, 0x00000000}, 689 {REG_ESAI_TCCR, 0x00000000}, 690 {REG_ESAI_RCR, 0x00000000}, 691 {REG_ESAI_RCCR, 0x00000000}, 692 {REG_ESAI_TSMA, 0x0000ffff}, 693 {REG_ESAI_TSMB, 0x0000ffff}, 694 {REG_ESAI_RSMA, 0x0000ffff}, 695 {REG_ESAI_RSMB, 0x0000ffff}, 696 {REG_ESAI_PRRC, 0x00000000}, 697 {REG_ESAI_PCRC, 0x00000000}, 698 }; 699 700 static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) 701 { 702 switch (reg) { 703 case REG_ESAI_ERDR: 704 case REG_ESAI_ECR: 705 case REG_ESAI_ESR: 706 case REG_ESAI_TFCR: 707 case REG_ESAI_TFSR: 708 case REG_ESAI_RFCR: 709 case REG_ESAI_RFSR: 710 case REG_ESAI_RX0: 711 case REG_ESAI_RX1: 712 case REG_ESAI_RX2: 713 case REG_ESAI_RX3: 714 case REG_ESAI_SAISR: 715 case REG_ESAI_SAICR: 716 case REG_ESAI_TCR: 717 case REG_ESAI_TCCR: 718 case REG_ESAI_RCR: 719 case REG_ESAI_RCCR: 720 case REG_ESAI_TSMA: 721 case REG_ESAI_TSMB: 722 case REG_ESAI_RSMA: 723 case REG_ESAI_RSMB: 724 case REG_ESAI_PRRC: 725 case REG_ESAI_PCRC: 726 return true; 727 default: 728 return false; 729 } 730 } 731 732 static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg) 733 { 734 switch (reg) { 735 case REG_ESAI_ERDR: 736 case REG_ESAI_ESR: 737 case REG_ESAI_TFSR: 738 case REG_ESAI_RFSR: 739 case REG_ESAI_RX0: 740 case REG_ESAI_RX1: 741 case REG_ESAI_RX2: 742 case REG_ESAI_RX3: 743 case REG_ESAI_SAISR: 744 return true; 745 default: 746 return false; 747 } 748 } 749 750 static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) 751 { 752 switch (reg) { 753 case REG_ESAI_ETDR: 754 case REG_ESAI_ECR: 755 case REG_ESAI_TFCR: 756 case REG_ESAI_RFCR: 757 case REG_ESAI_TX0: 758 case REG_ESAI_TX1: 759 case REG_ESAI_TX2: 760 case REG_ESAI_TX3: 761 case REG_ESAI_TX4: 762 case REG_ESAI_TX5: 763 case REG_ESAI_TSR: 764 case REG_ESAI_SAICR: 765 case REG_ESAI_TCR: 766 case REG_ESAI_TCCR: 767 case REG_ESAI_RCR: 768 case REG_ESAI_RCCR: 769 case REG_ESAI_TSMA: 770 case REG_ESAI_TSMB: 771 case REG_ESAI_RSMA: 772 case REG_ESAI_RSMB: 773 case REG_ESAI_PRRC: 774 case REG_ESAI_PCRC: 775 return true; 776 default: 777 return false; 778 } 779 } 780 781 static const struct regmap_config fsl_esai_regmap_config = { 782 .reg_bits = 32, 783 .reg_stride = 4, 784 .val_bits = 32, 785 786 .max_register = REG_ESAI_PCRC, 787 .reg_defaults = fsl_esai_reg_defaults, 788 .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults), 789 .readable_reg = fsl_esai_readable_reg, 790 .volatile_reg = fsl_esai_volatile_reg, 791 .writeable_reg = fsl_esai_writeable_reg, 792 .cache_type = REGCACHE_FLAT, 793 }; 794 795 static int fsl_esai_probe(struct platform_device *pdev) 796 { 797 struct device_node *np = pdev->dev.of_node; 798 struct fsl_esai *esai_priv; 799 struct resource *res; 800 const __be32 *iprop; 801 void __iomem *regs; 802 int irq, ret; 803 804 esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL); 805 if (!esai_priv) 806 return -ENOMEM; 807 808 esai_priv->pdev = pdev; 809 strncpy(esai_priv->name, np->name, sizeof(esai_priv->name) - 1); 810 811 /* Get the addresses and IRQ */ 812 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 813 regs = devm_ioremap_resource(&pdev->dev, res); 814 if (IS_ERR(regs)) 815 return PTR_ERR(regs); 816 817 esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, 818 "core", regs, &fsl_esai_regmap_config); 819 if (IS_ERR(esai_priv->regmap)) { 820 dev_err(&pdev->dev, "failed to init regmap: %ld\n", 821 PTR_ERR(esai_priv->regmap)); 822 return PTR_ERR(esai_priv->regmap); 823 } 824 825 esai_priv->coreclk = devm_clk_get(&pdev->dev, "core"); 826 if (IS_ERR(esai_priv->coreclk)) { 827 dev_err(&pdev->dev, "failed to get core clock: %ld\n", 828 PTR_ERR(esai_priv->coreclk)); 829 return PTR_ERR(esai_priv->coreclk); 830 } 831 832 esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal"); 833 if (IS_ERR(esai_priv->extalclk)) 834 dev_warn(&pdev->dev, "failed to get extal clock: %ld\n", 835 PTR_ERR(esai_priv->extalclk)); 836 837 esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys"); 838 if (IS_ERR(esai_priv->fsysclk)) 839 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n", 840 PTR_ERR(esai_priv->fsysclk)); 841 842 esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba"); 843 if (IS_ERR(esai_priv->spbaclk)) 844 dev_warn(&pdev->dev, "failed to get spba clock: %ld\n", 845 PTR_ERR(esai_priv->spbaclk)); 846 847 irq = platform_get_irq(pdev, 0); 848 if (irq < 0) { 849 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); 850 return irq; 851 } 852 853 ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, 854 esai_priv->name, esai_priv); 855 if (ret) { 856 dev_err(&pdev->dev, "failed to claim irq %u\n", irq); 857 return ret; 858 } 859 860 /* Set a default slot number */ 861 esai_priv->slots = 2; 862 863 /* Set a default master/slave state */ 864 esai_priv->slave_mode = true; 865 866 /* Determine the FIFO depth */ 867 iprop = of_get_property(np, "fsl,fifo-depth", NULL); 868 if (iprop) 869 esai_priv->fifo_depth = be32_to_cpup(iprop); 870 else 871 esai_priv->fifo_depth = 64; 872 873 esai_priv->dma_params_tx.maxburst = 16; 874 esai_priv->dma_params_rx.maxburst = 16; 875 esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR; 876 esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR; 877 878 esai_priv->synchronous = 879 of_property_read_bool(np, "fsl,esai-synchronous"); 880 881 /* Implement full symmetry for synchronous mode */ 882 if (esai_priv->synchronous) { 883 fsl_esai_dai.symmetric_rates = 1; 884 fsl_esai_dai.symmetric_channels = 1; 885 fsl_esai_dai.symmetric_samplebits = 1; 886 } 887 888 dev_set_drvdata(&pdev->dev, esai_priv); 889 890 /* Reset ESAI unit */ 891 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST); 892 if (ret) { 893 dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret); 894 return ret; 895 } 896 897 /* 898 * We need to enable ESAI so as to access some of its registers. 899 * Otherwise, we would fail to dump regmap from user space. 900 */ 901 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN); 902 if (ret) { 903 dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret); 904 return ret; 905 } 906 907 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, 908 &fsl_esai_dai, 1); 909 if (ret) { 910 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 911 return ret; 912 } 913 914 ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE); 915 if (ret) 916 dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret); 917 918 return ret; 919 } 920 921 static const struct of_device_id fsl_esai_dt_ids[] = { 922 { .compatible = "fsl,imx35-esai", }, 923 { .compatible = "fsl,vf610-esai", }, 924 {} 925 }; 926 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); 927 928 #ifdef CONFIG_PM_SLEEP 929 static int fsl_esai_suspend(struct device *dev) 930 { 931 struct fsl_esai *esai = dev_get_drvdata(dev); 932 933 regcache_cache_only(esai->regmap, true); 934 regcache_mark_dirty(esai->regmap); 935 936 return 0; 937 } 938 939 static int fsl_esai_resume(struct device *dev) 940 { 941 struct fsl_esai *esai = dev_get_drvdata(dev); 942 int ret; 943 944 regcache_cache_only(esai->regmap, false); 945 946 /* FIFO reset for safety */ 947 regmap_update_bits(esai->regmap, REG_ESAI_TFCR, 948 ESAI_xFCR_xFR, ESAI_xFCR_xFR); 949 regmap_update_bits(esai->regmap, REG_ESAI_RFCR, 950 ESAI_xFCR_xFR, ESAI_xFCR_xFR); 951 952 ret = regcache_sync(esai->regmap); 953 if (ret) 954 return ret; 955 956 /* FIFO reset done */ 957 regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0); 958 regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0); 959 960 return 0; 961 } 962 #endif /* CONFIG_PM_SLEEP */ 963 964 static const struct dev_pm_ops fsl_esai_pm_ops = { 965 SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume) 966 }; 967 968 static struct platform_driver fsl_esai_driver = { 969 .probe = fsl_esai_probe, 970 .driver = { 971 .name = "fsl-esai-dai", 972 .pm = &fsl_esai_pm_ops, 973 .of_match_table = fsl_esai_dt_ids, 974 }, 975 }; 976 977 module_platform_driver(fsl_esai_driver); 978 979 MODULE_AUTHOR("Freescale Semiconductor, Inc."); 980 MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver"); 981 MODULE_LICENSE("GPL v2"); 982 MODULE_ALIAS("platform:fsl-esai-dai"); 983