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