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