fsl_sai.c (36836B)
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// Freescale ALSA SoC Digital Audio Interface (SAI) driver. 4// 5// Copyright 2012-2015 Freescale Semiconductor, Inc. 6 7#include <linux/clk.h> 8#include <linux/delay.h> 9#include <linux/dmaengine.h> 10#include <linux/module.h> 11#include <linux/of_address.h> 12#include <linux/of_device.h> 13#include <linux/pm_qos.h> 14#include <linux/pm_runtime.h> 15#include <linux/regmap.h> 16#include <linux/slab.h> 17#include <linux/time.h> 18#include <sound/core.h> 19#include <sound/dmaengine_pcm.h> 20#include <sound/pcm_params.h> 21#include <linux/mfd/syscon.h> 22#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> 23 24#include "fsl_sai.h" 25#include "imx-pcm.h" 26 27#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ 28 FSL_SAI_CSR_FEIE) 29 30static const unsigned int fsl_sai_rates[] = { 31 8000, 11025, 12000, 16000, 22050, 32 24000, 32000, 44100, 48000, 64000, 33 88200, 96000, 176400, 192000 34}; 35 36static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = { 37 .count = ARRAY_SIZE(fsl_sai_rates), 38 .list = fsl_sai_rates, 39}; 40 41/** 42 * fsl_sai_dir_is_synced - Check if stream is synced by the opposite stream 43 * 44 * SAI supports synchronous mode using bit/frame clocks of either Transmitter's 45 * or Receiver's for both streams. This function is used to check if clocks of 46 * the stream's are synced by the opposite stream. 47 * 48 * @sai: SAI context 49 * @dir: stream direction 50 */ 51static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir) 52{ 53 int adir = (dir == TX) ? RX : TX; 54 55 /* current dir in async mode while opposite dir in sync mode */ 56 return !sai->synchronous[dir] && sai->synchronous[adir]; 57} 58 59static irqreturn_t fsl_sai_isr(int irq, void *devid) 60{ 61 struct fsl_sai *sai = (struct fsl_sai *)devid; 62 unsigned int ofs = sai->soc_data->reg_offset; 63 struct device *dev = &sai->pdev->dev; 64 u32 flags, xcsr, mask; 65 irqreturn_t iret = IRQ_NONE; 66 67 /* 68 * Both IRQ status bits and IRQ mask bits are in the xCSR but 69 * different shifts. And we here create a mask only for those 70 * IRQs that we activated. 71 */ 72 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; 73 74 /* Tx IRQ */ 75 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr); 76 flags = xcsr & mask; 77 78 if (flags) 79 iret = IRQ_HANDLED; 80 else 81 goto irq_rx; 82 83 if (flags & FSL_SAI_CSR_WSF) 84 dev_dbg(dev, "isr: Start of Tx word detected\n"); 85 86 if (flags & FSL_SAI_CSR_SEF) 87 dev_dbg(dev, "isr: Tx Frame sync error detected\n"); 88 89 if (flags & FSL_SAI_CSR_FEF) { 90 dev_dbg(dev, "isr: Transmit underrun detected\n"); 91 /* FIFO reset for safety */ 92 xcsr |= FSL_SAI_CSR_FR; 93 } 94 95 if (flags & FSL_SAI_CSR_FWF) 96 dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); 97 98 if (flags & FSL_SAI_CSR_FRF) 99 dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n"); 100 101 flags &= FSL_SAI_CSR_xF_W_MASK; 102 xcsr &= ~FSL_SAI_CSR_xF_MASK; 103 104 if (flags) 105 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr); 106 107irq_rx: 108 /* Rx IRQ */ 109 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr); 110 flags = xcsr & mask; 111 112 if (flags) 113 iret = IRQ_HANDLED; 114 else 115 goto out; 116 117 if (flags & FSL_SAI_CSR_WSF) 118 dev_dbg(dev, "isr: Start of Rx word detected\n"); 119 120 if (flags & FSL_SAI_CSR_SEF) 121 dev_dbg(dev, "isr: Rx Frame sync error detected\n"); 122 123 if (flags & FSL_SAI_CSR_FEF) { 124 dev_dbg(dev, "isr: Receive overflow detected\n"); 125 /* FIFO reset for safety */ 126 xcsr |= FSL_SAI_CSR_FR; 127 } 128 129 if (flags & FSL_SAI_CSR_FWF) 130 dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); 131 132 if (flags & FSL_SAI_CSR_FRF) 133 dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n"); 134 135 flags &= FSL_SAI_CSR_xF_W_MASK; 136 xcsr &= ~FSL_SAI_CSR_xF_MASK; 137 138 if (flags) 139 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr); 140 141out: 142 return iret; 143} 144 145static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, 146 u32 rx_mask, int slots, int slot_width) 147{ 148 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 149 150 sai->slots = slots; 151 sai->slot_width = slot_width; 152 153 return 0; 154} 155 156static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai, 157 unsigned int ratio) 158{ 159 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); 160 161 sai->bclk_ratio = ratio; 162 163 return 0; 164} 165 166static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, 167 int clk_id, unsigned int freq, bool tx) 168{ 169 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 170 unsigned int ofs = sai->soc_data->reg_offset; 171 u32 val_cr2 = 0; 172 173 switch (clk_id) { 174 case FSL_SAI_CLK_BUS: 175 val_cr2 |= FSL_SAI_CR2_MSEL_BUS; 176 break; 177 case FSL_SAI_CLK_MAST1: 178 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1; 179 break; 180 case FSL_SAI_CLK_MAST2: 181 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2; 182 break; 183 case FSL_SAI_CLK_MAST3: 184 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3; 185 break; 186 default: 187 return -EINVAL; 188 } 189 190 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), 191 FSL_SAI_CR2_MSEL_MASK, val_cr2); 192 193 return 0; 194} 195 196static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 197 int clk_id, unsigned int freq, int dir) 198{ 199 int ret; 200 201 if (dir == SND_SOC_CLOCK_IN) 202 return 0; 203 204 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, true); 205 if (ret) { 206 dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); 207 return ret; 208 } 209 210 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, false); 211 if (ret) 212 dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret); 213 214 return ret; 215} 216 217static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, 218 unsigned int fmt, bool tx) 219{ 220 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 221 unsigned int ofs = sai->soc_data->reg_offset; 222 u32 val_cr2 = 0, val_cr4 = 0; 223 224 if (!sai->is_lsb_first) 225 val_cr4 |= FSL_SAI_CR4_MF; 226 227 /* DAI mode */ 228 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 229 case SND_SOC_DAIFMT_I2S: 230 /* 231 * Frame low, 1clk before data, one word length for frame sync, 232 * frame sync starts one serial clock cycle earlier, 233 * that is, together with the last bit of the previous 234 * data word. 235 */ 236 val_cr2 |= FSL_SAI_CR2_BCP; 237 val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP; 238 break; 239 case SND_SOC_DAIFMT_LEFT_J: 240 /* 241 * Frame high, one word length for frame sync, 242 * frame sync asserts with the first bit of the frame. 243 */ 244 val_cr2 |= FSL_SAI_CR2_BCP; 245 break; 246 case SND_SOC_DAIFMT_DSP_A: 247 /* 248 * Frame high, 1clk before data, one bit for frame sync, 249 * frame sync starts one serial clock cycle earlier, 250 * that is, together with the last bit of the previous 251 * data word. 252 */ 253 val_cr2 |= FSL_SAI_CR2_BCP; 254 val_cr4 |= FSL_SAI_CR4_FSE; 255 sai->is_dsp_mode = true; 256 break; 257 case SND_SOC_DAIFMT_DSP_B: 258 /* 259 * Frame high, one bit for frame sync, 260 * frame sync asserts with the first bit of the frame. 261 */ 262 val_cr2 |= FSL_SAI_CR2_BCP; 263 sai->is_dsp_mode = true; 264 break; 265 case SND_SOC_DAIFMT_RIGHT_J: 266 /* To be done */ 267 default: 268 return -EINVAL; 269 } 270 271 /* DAI clock inversion */ 272 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 273 case SND_SOC_DAIFMT_IB_IF: 274 /* Invert both clocks */ 275 val_cr2 ^= FSL_SAI_CR2_BCP; 276 val_cr4 ^= FSL_SAI_CR4_FSP; 277 break; 278 case SND_SOC_DAIFMT_IB_NF: 279 /* Invert bit clock */ 280 val_cr2 ^= FSL_SAI_CR2_BCP; 281 break; 282 case SND_SOC_DAIFMT_NB_IF: 283 /* Invert frame clock */ 284 val_cr4 ^= FSL_SAI_CR4_FSP; 285 break; 286 case SND_SOC_DAIFMT_NB_NF: 287 /* Nothing to do for both normal cases */ 288 break; 289 default: 290 return -EINVAL; 291 } 292 293 /* DAI clock provider masks */ 294 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 295 case SND_SOC_DAIFMT_CBC_CFC: 296 val_cr2 |= FSL_SAI_CR2_BCD_MSTR; 297 val_cr4 |= FSL_SAI_CR4_FSD_MSTR; 298 sai->is_consumer_mode = false; 299 break; 300 case SND_SOC_DAIFMT_CBP_CFP: 301 sai->is_consumer_mode = true; 302 break; 303 case SND_SOC_DAIFMT_CBC_CFP: 304 val_cr2 |= FSL_SAI_CR2_BCD_MSTR; 305 sai->is_consumer_mode = false; 306 break; 307 case SND_SOC_DAIFMT_CBP_CFC: 308 val_cr4 |= FSL_SAI_CR4_FSD_MSTR; 309 sai->is_consumer_mode = true; 310 break; 311 default: 312 return -EINVAL; 313 } 314 315 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), 316 FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); 317 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), 318 FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | 319 FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); 320 321 return 0; 322} 323 324static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 325{ 326 int ret; 327 328 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, true); 329 if (ret) { 330 dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); 331 return ret; 332 } 333 334 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, false); 335 if (ret) 336 dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); 337 338 return ret; 339} 340 341static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) 342{ 343 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); 344 unsigned int reg, ofs = sai->soc_data->reg_offset; 345 unsigned long clk_rate; 346 u32 savediv = 0, ratio, bestdiff = freq; 347 int adir = tx ? RX : TX; 348 int dir = tx ? TX : RX; 349 u32 id; 350 bool support_1_1_ratio = sai->verid.version >= 0x0301; 351 352 /* Don't apply to consumer mode */ 353 if (sai->is_consumer_mode) 354 return 0; 355 356 /* 357 * There is no point in polling MCLK0 if it is identical to MCLK1. 358 * And given that MQS use case has to use MCLK1 though two clocks 359 * are the same, we simply skip MCLK0 and start to find from MCLK1. 360 */ 361 id = sai->soc_data->mclk0_is_mclk1 ? 1 : 0; 362 363 for (; id < FSL_SAI_MCLK_MAX; id++) { 364 int diff; 365 366 clk_rate = clk_get_rate(sai->mclk_clk[id]); 367 if (!clk_rate) 368 continue; 369 370 ratio = DIV_ROUND_CLOSEST(clk_rate, freq); 371 if (!ratio || ratio > 512) 372 continue; 373 if (ratio == 1 && !support_1_1_ratio) 374 continue; 375 if ((ratio & 1) && ratio > 1) 376 continue; 377 378 diff = abs((long)clk_rate - ratio * freq); 379 380 /* 381 * Drop the source that can not be 382 * divided into the required rate. 383 */ 384 if (diff != 0 && clk_rate / diff < 1000) 385 continue; 386 387 dev_dbg(dai->dev, 388 "ratio %d for freq %dHz based on clock %ldHz\n", 389 ratio, freq, clk_rate); 390 391 392 if (diff < bestdiff) { 393 savediv = ratio; 394 sai->mclk_id[tx] = id; 395 bestdiff = diff; 396 } 397 398 if (diff == 0) 399 break; 400 } 401 402 if (savediv == 0) { 403 dev_err(dai->dev, "failed to derive required %cx rate: %d\n", 404 tx ? 'T' : 'R', freq); 405 return -EINVAL; 406 } 407 408 dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n", 409 sai->mclk_id[tx], savediv, bestdiff); 410 411 /* 412 * 1) For Asynchronous mode, we must set RCR2 register for capture, and 413 * set TCR2 register for playback. 414 * 2) For Tx sync with Rx clock, we must set RCR2 register for playback 415 * and capture. 416 * 3) For Rx sync with Tx clock, we must set TCR2 register for playback 417 * and capture. 418 * 4) For Tx and Rx are both Synchronous with another SAI, we just 419 * ignore it. 420 */ 421 if (fsl_sai_dir_is_synced(sai, adir)) 422 reg = FSL_SAI_xCR2(!tx, ofs); 423 else if (!sai->synchronous[dir]) 424 reg = FSL_SAI_xCR2(tx, ofs); 425 else 426 return 0; 427 428 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK, 429 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 430 431 if (savediv == 1) 432 regmap_update_bits(sai->regmap, reg, 433 FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP, 434 FSL_SAI_CR2_BYP); 435 else 436 regmap_update_bits(sai->regmap, reg, 437 FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP, 438 savediv / 2 - 1); 439 440 return 0; 441} 442 443static int fsl_sai_hw_params(struct snd_pcm_substream *substream, 444 struct snd_pcm_hw_params *params, 445 struct snd_soc_dai *cpu_dai) 446{ 447 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 448 unsigned int ofs = sai->soc_data->reg_offset; 449 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 450 unsigned int channels = params_channels(params); 451 u32 word_width = params_width(params); 452 u32 val_cr4 = 0, val_cr5 = 0; 453 u32 slots = (channels == 1) ? 2 : channels; 454 u32 slot_width = word_width; 455 int adir = tx ? RX : TX; 456 u32 pins; 457 int ret; 458 459 if (sai->slots) 460 slots = sai->slots; 461 462 if (sai->slot_width) 463 slot_width = sai->slot_width; 464 465 pins = DIV_ROUND_UP(channels, slots); 466 467 if (!sai->is_consumer_mode) { 468 if (sai->bclk_ratio) 469 ret = fsl_sai_set_bclk(cpu_dai, tx, 470 sai->bclk_ratio * 471 params_rate(params)); 472 else 473 ret = fsl_sai_set_bclk(cpu_dai, tx, 474 slots * slot_width * 475 params_rate(params)); 476 if (ret) 477 return ret; 478 479 /* Do not enable the clock if it is already enabled */ 480 if (!(sai->mclk_streams & BIT(substream->stream))) { 481 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]); 482 if (ret) 483 return ret; 484 485 sai->mclk_streams |= BIT(substream->stream); 486 } 487 } 488 489 if (!sai->is_dsp_mode) 490 val_cr4 |= FSL_SAI_CR4_SYWD(slot_width); 491 492 val_cr5 |= FSL_SAI_CR5_WNW(slot_width); 493 val_cr5 |= FSL_SAI_CR5_W0W(slot_width); 494 495 if (sai->is_lsb_first) 496 val_cr5 |= FSL_SAI_CR5_FBT(0); 497 else 498 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); 499 500 val_cr4 |= FSL_SAI_CR4_FRSZ(slots); 501 502 /* Set to output mode to avoid tri-stated data pins */ 503 if (tx) 504 val_cr4 |= FSL_SAI_CR4_CHMOD; 505 506 /* 507 * For SAI provider mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will 508 * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), 509 * RCR5(TCR5) for playback(capture), or there will be sync error. 510 */ 511 512 if (!sai->is_consumer_mode && fsl_sai_dir_is_synced(sai, adir)) { 513 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs), 514 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | 515 FSL_SAI_CR4_CHMOD_MASK, 516 val_cr4); 517 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs), 518 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | 519 FSL_SAI_CR5_FBT_MASK, val_cr5); 520 } 521 522 if (sai->soc_data->pins > 1) 523 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), 524 FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT); 525 526 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), 527 FSL_SAI_CR3_TRCE_MASK, 528 FSL_SAI_CR3_TRCE((1 << pins) - 1)); 529 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), 530 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | 531 FSL_SAI_CR4_CHMOD_MASK, 532 val_cr4); 533 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), 534 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | 535 FSL_SAI_CR5_FBT_MASK, val_cr5); 536 regmap_write(sai->regmap, FSL_SAI_xMR(tx), 537 ~0UL - ((1 << min(channels, slots)) - 1)); 538 539 return 0; 540} 541 542static int fsl_sai_hw_free(struct snd_pcm_substream *substream, 543 struct snd_soc_dai *cpu_dai) 544{ 545 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 546 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 547 unsigned int ofs = sai->soc_data->reg_offset; 548 549 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), 550 FSL_SAI_CR3_TRCE_MASK, 0); 551 552 if (!sai->is_consumer_mode && 553 sai->mclk_streams & BIT(substream->stream)) { 554 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]); 555 sai->mclk_streams &= ~BIT(substream->stream); 556 } 557 558 return 0; 559} 560 561static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) 562{ 563 unsigned int ofs = sai->soc_data->reg_offset; 564 bool tx = dir == TX; 565 u32 xcsr, count = 100; 566 567 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 568 FSL_SAI_CSR_TERE, 0); 569 570 /* TERE will remain set till the end of current frame */ 571 do { 572 udelay(10); 573 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr); 574 } while (--count && xcsr & FSL_SAI_CSR_TERE); 575 576 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 577 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); 578 579 /* 580 * For sai master mode, after several open/close sai, 581 * there will be no frame clock, and can't recover 582 * anymore. Add software reset to fix this issue. 583 * This is a hardware bug, and will be fix in the 584 * next sai version. 585 */ 586 if (!sai->is_consumer_mode) { 587 /* Software Reset */ 588 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR); 589 /* Clear SR bit to finish the reset */ 590 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0); 591 } 592} 593 594static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, 595 struct snd_soc_dai *cpu_dai) 596{ 597 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 598 unsigned int ofs = sai->soc_data->reg_offset; 599 600 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 601 int adir = tx ? RX : TX; 602 int dir = tx ? TX : RX; 603 u32 xcsr; 604 605 /* 606 * Asynchronous mode: Clear SYNC for both Tx and Rx. 607 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. 608 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. 609 */ 610 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC, 611 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); 612 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC, 613 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); 614 615 /* 616 * It is recommended that the transmitter is the last enabled 617 * and the first disabled. 618 */ 619 switch (cmd) { 620 case SNDRV_PCM_TRIGGER_START: 621 case SNDRV_PCM_TRIGGER_RESUME: 622 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 623 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 624 FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); 625 626 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 627 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); 628 /* 629 * Enable the opposite direction for synchronous mode 630 * 1. Tx sync with Rx: only set RE for Rx; set TE & RE for Tx 631 * 2. Rx sync with Tx: only set TE for Tx; set RE & TE for Rx 632 * 633 * RM recommends to enable RE after TE for case 1 and to enable 634 * TE after RE for case 2, but we here may not always guarantee 635 * that happens: "arecord 1.wav; aplay 2.wav" in case 1 enables 636 * TE after RE, which is against what RM recommends but should 637 * be safe to do, judging by years of testing results. 638 */ 639 if (fsl_sai_dir_is_synced(sai, adir)) 640 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs), 641 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); 642 643 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 644 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); 645 break; 646 case SNDRV_PCM_TRIGGER_STOP: 647 case SNDRV_PCM_TRIGGER_SUSPEND: 648 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 649 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 650 FSL_SAI_CSR_FRDE, 0); 651 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), 652 FSL_SAI_CSR_xIE_MASK, 0); 653 654 /* Check if the opposite FRDE is also disabled */ 655 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr); 656 657 /* 658 * If opposite stream provides clocks for synchronous mode and 659 * it is inactive, disable it before disabling the current one 660 */ 661 if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE)) 662 fsl_sai_config_disable(sai, adir); 663 664 /* 665 * Disable current stream if either of: 666 * 1. current stream doesn't provide clocks for synchronous mode 667 * 2. current stream provides clocks for synchronous mode but no 668 * more stream is active. 669 */ 670 if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE)) 671 fsl_sai_config_disable(sai, dir); 672 673 break; 674 default: 675 return -EINVAL; 676 } 677 678 return 0; 679} 680 681static int fsl_sai_startup(struct snd_pcm_substream *substream, 682 struct snd_soc_dai *cpu_dai) 683{ 684 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 685 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 686 int ret; 687 688 /* 689 * EDMA controller needs period size to be a multiple of 690 * tx/rx maxburst 691 */ 692 if (sai->soc_data->use_edma) 693 snd_pcm_hw_constraint_step(substream->runtime, 0, 694 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 695 tx ? sai->dma_params_tx.maxburst : 696 sai->dma_params_rx.maxburst); 697 698 ret = snd_pcm_hw_constraint_list(substream->runtime, 0, 699 SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints); 700 701 return ret; 702} 703 704static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { 705 .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, 706 .set_sysclk = fsl_sai_set_dai_sysclk, 707 .set_fmt = fsl_sai_set_dai_fmt, 708 .set_tdm_slot = fsl_sai_set_dai_tdm_slot, 709 .hw_params = fsl_sai_hw_params, 710 .hw_free = fsl_sai_hw_free, 711 .trigger = fsl_sai_trigger, 712 .startup = fsl_sai_startup, 713}; 714 715static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) 716{ 717 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); 718 unsigned int ofs = sai->soc_data->reg_offset; 719 720 /* Software Reset for both Tx and Rx */ 721 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); 722 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); 723 /* Clear SR bit to finish the reset */ 724 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); 725 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); 726 727 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs), 728 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), 729 sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX); 730 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs), 731 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), 732 FSL_SAI_MAXBURST_RX - 1); 733 734 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, 735 &sai->dma_params_rx); 736 737 return 0; 738} 739 740static struct snd_soc_dai_driver fsl_sai_dai_template = { 741 .probe = fsl_sai_dai_probe, 742 .playback = { 743 .stream_name = "CPU-Playback", 744 .channels_min = 1, 745 .channels_max = 32, 746 .rate_min = 8000, 747 .rate_max = 192000, 748 .rates = SNDRV_PCM_RATE_KNOT, 749 .formats = FSL_SAI_FORMATS, 750 }, 751 .capture = { 752 .stream_name = "CPU-Capture", 753 .channels_min = 1, 754 .channels_max = 32, 755 .rate_min = 8000, 756 .rate_max = 192000, 757 .rates = SNDRV_PCM_RATE_KNOT, 758 .formats = FSL_SAI_FORMATS, 759 }, 760 .ops = &fsl_sai_pcm_dai_ops, 761}; 762 763static const struct snd_soc_component_driver fsl_component = { 764 .name = "fsl-sai", 765}; 766 767static struct reg_default fsl_sai_reg_defaults_ofs0[] = { 768 {FSL_SAI_TCR1(0), 0}, 769 {FSL_SAI_TCR2(0), 0}, 770 {FSL_SAI_TCR3(0), 0}, 771 {FSL_SAI_TCR4(0), 0}, 772 {FSL_SAI_TCR5(0), 0}, 773 {FSL_SAI_TDR0, 0}, 774 {FSL_SAI_TDR1, 0}, 775 {FSL_SAI_TDR2, 0}, 776 {FSL_SAI_TDR3, 0}, 777 {FSL_SAI_TDR4, 0}, 778 {FSL_SAI_TDR5, 0}, 779 {FSL_SAI_TDR6, 0}, 780 {FSL_SAI_TDR7, 0}, 781 {FSL_SAI_TMR, 0}, 782 {FSL_SAI_RCR1(0), 0}, 783 {FSL_SAI_RCR2(0), 0}, 784 {FSL_SAI_RCR3(0), 0}, 785 {FSL_SAI_RCR4(0), 0}, 786 {FSL_SAI_RCR5(0), 0}, 787 {FSL_SAI_RMR, 0}, 788}; 789 790static struct reg_default fsl_sai_reg_defaults_ofs8[] = { 791 {FSL_SAI_TCR1(8), 0}, 792 {FSL_SAI_TCR2(8), 0}, 793 {FSL_SAI_TCR3(8), 0}, 794 {FSL_SAI_TCR4(8), 0}, 795 {FSL_SAI_TCR5(8), 0}, 796 {FSL_SAI_TDR0, 0}, 797 {FSL_SAI_TDR1, 0}, 798 {FSL_SAI_TDR2, 0}, 799 {FSL_SAI_TDR3, 0}, 800 {FSL_SAI_TDR4, 0}, 801 {FSL_SAI_TDR5, 0}, 802 {FSL_SAI_TDR6, 0}, 803 {FSL_SAI_TDR7, 0}, 804 {FSL_SAI_TMR, 0}, 805 {FSL_SAI_RCR1(8), 0}, 806 {FSL_SAI_RCR2(8), 0}, 807 {FSL_SAI_RCR3(8), 0}, 808 {FSL_SAI_RCR4(8), 0}, 809 {FSL_SAI_RCR5(8), 0}, 810 {FSL_SAI_RMR, 0}, 811 {FSL_SAI_MCTL, 0}, 812 {FSL_SAI_MDIV, 0}, 813}; 814 815static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) 816{ 817 struct fsl_sai *sai = dev_get_drvdata(dev); 818 unsigned int ofs = sai->soc_data->reg_offset; 819 820 if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs)) 821 return true; 822 823 if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs)) 824 return true; 825 826 switch (reg) { 827 case FSL_SAI_TFR0: 828 case FSL_SAI_TFR1: 829 case FSL_SAI_TFR2: 830 case FSL_SAI_TFR3: 831 case FSL_SAI_TFR4: 832 case FSL_SAI_TFR5: 833 case FSL_SAI_TFR6: 834 case FSL_SAI_TFR7: 835 case FSL_SAI_TMR: 836 case FSL_SAI_RDR0: 837 case FSL_SAI_RDR1: 838 case FSL_SAI_RDR2: 839 case FSL_SAI_RDR3: 840 case FSL_SAI_RDR4: 841 case FSL_SAI_RDR5: 842 case FSL_SAI_RDR6: 843 case FSL_SAI_RDR7: 844 case FSL_SAI_RFR0: 845 case FSL_SAI_RFR1: 846 case FSL_SAI_RFR2: 847 case FSL_SAI_RFR3: 848 case FSL_SAI_RFR4: 849 case FSL_SAI_RFR5: 850 case FSL_SAI_RFR6: 851 case FSL_SAI_RFR7: 852 case FSL_SAI_RMR: 853 case FSL_SAI_MCTL: 854 case FSL_SAI_MDIV: 855 case FSL_SAI_VERID: 856 case FSL_SAI_PARAM: 857 case FSL_SAI_TTCTN: 858 case FSL_SAI_RTCTN: 859 case FSL_SAI_TTCTL: 860 case FSL_SAI_TBCTN: 861 case FSL_SAI_TTCAP: 862 case FSL_SAI_RTCTL: 863 case FSL_SAI_RBCTN: 864 case FSL_SAI_RTCAP: 865 return true; 866 default: 867 return false; 868 } 869} 870 871static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) 872{ 873 struct fsl_sai *sai = dev_get_drvdata(dev); 874 unsigned int ofs = sai->soc_data->reg_offset; 875 876 if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs)) 877 return true; 878 879 /* Set VERID and PARAM be volatile for reading value in probe */ 880 if (ofs == 8 && (reg == FSL_SAI_VERID || reg == FSL_SAI_PARAM)) 881 return true; 882 883 switch (reg) { 884 case FSL_SAI_TFR0: 885 case FSL_SAI_TFR1: 886 case FSL_SAI_TFR2: 887 case FSL_SAI_TFR3: 888 case FSL_SAI_TFR4: 889 case FSL_SAI_TFR5: 890 case FSL_SAI_TFR6: 891 case FSL_SAI_TFR7: 892 case FSL_SAI_RFR0: 893 case FSL_SAI_RFR1: 894 case FSL_SAI_RFR2: 895 case FSL_SAI_RFR3: 896 case FSL_SAI_RFR4: 897 case FSL_SAI_RFR5: 898 case FSL_SAI_RFR6: 899 case FSL_SAI_RFR7: 900 case FSL_SAI_RDR0: 901 case FSL_SAI_RDR1: 902 case FSL_SAI_RDR2: 903 case FSL_SAI_RDR3: 904 case FSL_SAI_RDR4: 905 case FSL_SAI_RDR5: 906 case FSL_SAI_RDR6: 907 case FSL_SAI_RDR7: 908 return true; 909 default: 910 return false; 911 } 912} 913 914static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) 915{ 916 struct fsl_sai *sai = dev_get_drvdata(dev); 917 unsigned int ofs = sai->soc_data->reg_offset; 918 919 if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs)) 920 return true; 921 922 if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs)) 923 return true; 924 925 switch (reg) { 926 case FSL_SAI_TDR0: 927 case FSL_SAI_TDR1: 928 case FSL_SAI_TDR2: 929 case FSL_SAI_TDR3: 930 case FSL_SAI_TDR4: 931 case FSL_SAI_TDR5: 932 case FSL_SAI_TDR6: 933 case FSL_SAI_TDR7: 934 case FSL_SAI_TMR: 935 case FSL_SAI_RMR: 936 case FSL_SAI_MCTL: 937 case FSL_SAI_MDIV: 938 case FSL_SAI_TTCTL: 939 case FSL_SAI_RTCTL: 940 return true; 941 default: 942 return false; 943 } 944} 945 946static struct regmap_config fsl_sai_regmap_config = { 947 .reg_bits = 32, 948 .reg_stride = 4, 949 .val_bits = 32, 950 .fast_io = true, 951 952 .max_register = FSL_SAI_RMR, 953 .reg_defaults = fsl_sai_reg_defaults_ofs0, 954 .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0), 955 .readable_reg = fsl_sai_readable_reg, 956 .volatile_reg = fsl_sai_volatile_reg, 957 .writeable_reg = fsl_sai_writeable_reg, 958 .cache_type = REGCACHE_FLAT, 959}; 960 961static int fsl_sai_check_version(struct device *dev) 962{ 963 struct fsl_sai *sai = dev_get_drvdata(dev); 964 unsigned char ofs = sai->soc_data->reg_offset; 965 unsigned int val; 966 int ret; 967 968 if (FSL_SAI_TCSR(ofs) == FSL_SAI_VERID) 969 return 0; 970 971 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val); 972 if (ret < 0) 973 return ret; 974 975 dev_dbg(dev, "VERID: 0x%016X\n", val); 976 977 sai->verid.version = val & 978 (FSL_SAI_VERID_MAJOR_MASK | FSL_SAI_VERID_MINOR_MASK); 979 sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK; 980 981 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val); 982 if (ret < 0) 983 return ret; 984 985 dev_dbg(dev, "PARAM: 0x%016X\n", val); 986 987 /* Max slots per frame, power of 2 */ 988 sai->param.slot_num = 1 << 989 ((val & FSL_SAI_PARAM_SPF_MASK) >> FSL_SAI_PARAM_SPF_SHIFT); 990 991 /* Words per fifo, power of 2 */ 992 sai->param.fifo_depth = 1 << 993 ((val & FSL_SAI_PARAM_WPF_MASK) >> FSL_SAI_PARAM_WPF_SHIFT); 994 995 /* Number of datalines implemented */ 996 sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK; 997 998 return 0; 999} 1000 1001static int fsl_sai_runtime_suspend(struct device *dev); 1002static int fsl_sai_runtime_resume(struct device *dev); 1003 1004static int fsl_sai_probe(struct platform_device *pdev) 1005{ 1006 struct device_node *np = pdev->dev.of_node; 1007 struct fsl_sai *sai; 1008 struct regmap *gpr; 1009 struct resource *res; 1010 void __iomem *base; 1011 char tmp[8]; 1012 int irq, ret, i; 1013 int index; 1014 1015 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); 1016 if (!sai) 1017 return -ENOMEM; 1018 1019 sai->pdev = pdev; 1020 sai->soc_data = of_device_get_match_data(&pdev->dev); 1021 1022 sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); 1023 1024 base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1025 if (IS_ERR(base)) 1026 return PTR_ERR(base); 1027 1028 if (sai->soc_data->reg_offset == 8) { 1029 fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8; 1030 fsl_sai_regmap_config.max_register = FSL_SAI_MDIV; 1031 fsl_sai_regmap_config.num_reg_defaults = 1032 ARRAY_SIZE(fsl_sai_reg_defaults_ofs8); 1033 } 1034 1035 sai->regmap = devm_regmap_init_mmio(&pdev->dev, base, &fsl_sai_regmap_config); 1036 if (IS_ERR(sai->regmap)) { 1037 dev_err(&pdev->dev, "regmap init failed\n"); 1038 return PTR_ERR(sai->regmap); 1039 } 1040 1041 sai->bus_clk = devm_clk_get(&pdev->dev, "bus"); 1042 /* Compatible with old DTB cases */ 1043 if (IS_ERR(sai->bus_clk) && PTR_ERR(sai->bus_clk) != -EPROBE_DEFER) 1044 sai->bus_clk = devm_clk_get(&pdev->dev, "sai"); 1045 if (IS_ERR(sai->bus_clk)) { 1046 dev_err(&pdev->dev, "failed to get bus clock: %ld\n", 1047 PTR_ERR(sai->bus_clk)); 1048 /* -EPROBE_DEFER */ 1049 return PTR_ERR(sai->bus_clk); 1050 } 1051 1052 for (i = 1; i < FSL_SAI_MCLK_MAX; i++) { 1053 sprintf(tmp, "mclk%d", i); 1054 sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); 1055 if (IS_ERR(sai->mclk_clk[i])) { 1056 dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n", 1057 i + 1, PTR_ERR(sai->mclk_clk[i])); 1058 sai->mclk_clk[i] = NULL; 1059 } 1060 } 1061 1062 if (sai->soc_data->mclk0_is_mclk1) 1063 sai->mclk_clk[0] = sai->mclk_clk[1]; 1064 else 1065 sai->mclk_clk[0] = sai->bus_clk; 1066 1067 irq = platform_get_irq(pdev, 0); 1068 if (irq < 0) 1069 return irq; 1070 1071 ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, IRQF_SHARED, 1072 np->name, sai); 1073 if (ret) { 1074 dev_err(&pdev->dev, "failed to claim irq %u\n", irq); 1075 return ret; 1076 } 1077 1078 memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template, 1079 sizeof(fsl_sai_dai_template)); 1080 1081 /* Sync Tx with Rx as default by following old DT binding */ 1082 sai->synchronous[RX] = true; 1083 sai->synchronous[TX] = false; 1084 sai->cpu_dai_drv.symmetric_rate = 1; 1085 sai->cpu_dai_drv.symmetric_channels = 1; 1086 sai->cpu_dai_drv.symmetric_sample_bits = 1; 1087 1088 if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && 1089 of_find_property(np, "fsl,sai-asynchronous", NULL)) { 1090 /* error out if both synchronous and asynchronous are present */ 1091 dev_err(&pdev->dev, "invalid binding for synchronous mode\n"); 1092 return -EINVAL; 1093 } 1094 1095 if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) { 1096 /* Sync Rx with Tx */ 1097 sai->synchronous[RX] = false; 1098 sai->synchronous[TX] = true; 1099 } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) { 1100 /* Discard all settings for asynchronous mode */ 1101 sai->synchronous[RX] = false; 1102 sai->synchronous[TX] = false; 1103 sai->cpu_dai_drv.symmetric_rate = 0; 1104 sai->cpu_dai_drv.symmetric_channels = 0; 1105 sai->cpu_dai_drv.symmetric_sample_bits = 0; 1106 } 1107 1108 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && 1109 of_device_is_compatible(np, "fsl,imx6ul-sai")) { 1110 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); 1111 if (IS_ERR(gpr)) { 1112 dev_err(&pdev->dev, "cannot find iomuxc registers\n"); 1113 return PTR_ERR(gpr); 1114 } 1115 1116 index = of_alias_get_id(np, "sai"); 1117 if (index < 0) 1118 return index; 1119 1120 regmap_update_bits(gpr, IOMUXC_GPR1, MCLK_DIR(index), 1121 MCLK_DIR(index)); 1122 } 1123 1124 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0; 1125 sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0; 1126 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; 1127 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; 1128 1129 platform_set_drvdata(pdev, sai); 1130 pm_runtime_enable(&pdev->dev); 1131 if (!pm_runtime_enabled(&pdev->dev)) { 1132 ret = fsl_sai_runtime_resume(&pdev->dev); 1133 if (ret) 1134 goto err_pm_disable; 1135 } 1136 1137 ret = pm_runtime_get_sync(&pdev->dev); 1138 if (ret < 0) { 1139 pm_runtime_put_noidle(&pdev->dev); 1140 goto err_pm_get_sync; 1141 } 1142 1143 /* Get sai version */ 1144 ret = fsl_sai_check_version(&pdev->dev); 1145 if (ret < 0) 1146 dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret); 1147 1148 /* Select MCLK direction */ 1149 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && 1150 sai->soc_data->max_register >= FSL_SAI_MCTL) { 1151 regmap_update_bits(sai->regmap, FSL_SAI_MCTL, 1152 FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); 1153 } 1154 1155 ret = pm_runtime_put_sync(&pdev->dev); 1156 if (ret < 0) 1157 goto err_pm_get_sync; 1158 1159 /* 1160 * Register platform component before registering cpu dai for there 1161 * is not defer probe for platform component in snd_soc_add_pcm_runtime(). 1162 */ 1163 if (sai->soc_data->use_imx_pcm) { 1164 ret = imx_pcm_dma_init(pdev); 1165 if (ret) 1166 goto err_pm_get_sync; 1167 } else { 1168 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 1169 if (ret) 1170 goto err_pm_get_sync; 1171 } 1172 1173 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, 1174 &sai->cpu_dai_drv, 1); 1175 if (ret) 1176 goto err_pm_get_sync; 1177 1178 return ret; 1179 1180err_pm_get_sync: 1181 if (!pm_runtime_status_suspended(&pdev->dev)) 1182 fsl_sai_runtime_suspend(&pdev->dev); 1183err_pm_disable: 1184 pm_runtime_disable(&pdev->dev); 1185 1186 return ret; 1187} 1188 1189static int fsl_sai_remove(struct platform_device *pdev) 1190{ 1191 pm_runtime_disable(&pdev->dev); 1192 if (!pm_runtime_status_suspended(&pdev->dev)) 1193 fsl_sai_runtime_suspend(&pdev->dev); 1194 1195 return 0; 1196} 1197 1198static const struct fsl_sai_soc_data fsl_sai_vf610_data = { 1199 .use_imx_pcm = false, 1200 .use_edma = false, 1201 .fifo_depth = 32, 1202 .pins = 1, 1203 .reg_offset = 0, 1204 .mclk0_is_mclk1 = false, 1205 .flags = 0, 1206 .max_register = FSL_SAI_RMR, 1207}; 1208 1209static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = { 1210 .use_imx_pcm = true, 1211 .use_edma = false, 1212 .fifo_depth = 32, 1213 .pins = 1, 1214 .reg_offset = 0, 1215 .mclk0_is_mclk1 = true, 1216 .flags = 0, 1217 .max_register = FSL_SAI_RMR, 1218}; 1219 1220static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = { 1221 .use_imx_pcm = true, 1222 .use_edma = false, 1223 .fifo_depth = 16, 1224 .pins = 2, 1225 .reg_offset = 8, 1226 .mclk0_is_mclk1 = false, 1227 .flags = PMQOS_CPU_LATENCY, 1228 .max_register = FSL_SAI_RMR, 1229}; 1230 1231static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = { 1232 .use_imx_pcm = true, 1233 .use_edma = false, 1234 .fifo_depth = 128, 1235 .pins = 8, 1236 .reg_offset = 8, 1237 .mclk0_is_mclk1 = false, 1238 .flags = 0, 1239 .max_register = FSL_SAI_RMR, 1240}; 1241 1242static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = { 1243 .use_imx_pcm = true, 1244 .use_edma = true, 1245 .fifo_depth = 64, 1246 .pins = 1, 1247 .reg_offset = 0, 1248 .mclk0_is_mclk1 = false, 1249 .flags = 0, 1250 .max_register = FSL_SAI_RMR, 1251}; 1252 1253static const struct fsl_sai_soc_data fsl_sai_imx8mm_data = { 1254 .use_imx_pcm = true, 1255 .use_edma = false, 1256 .fifo_depth = 128, 1257 .reg_offset = 8, 1258 .mclk0_is_mclk1 = false, 1259 .pins = 8, 1260 .flags = 0, 1261 .max_register = FSL_SAI_MCTL, 1262}; 1263 1264static const struct fsl_sai_soc_data fsl_sai_imx8mp_data = { 1265 .use_imx_pcm = true, 1266 .use_edma = false, 1267 .fifo_depth = 128, 1268 .reg_offset = 8, 1269 .mclk0_is_mclk1 = false, 1270 .pins = 8, 1271 .flags = 0, 1272 .max_register = FSL_SAI_MDIV, 1273}; 1274 1275static const struct fsl_sai_soc_data fsl_sai_imx8ulp_data = { 1276 .use_imx_pcm = true, 1277 .use_edma = true, 1278 .fifo_depth = 16, 1279 .reg_offset = 8, 1280 .mclk0_is_mclk1 = false, 1281 .pins = 4, 1282 .flags = PMQOS_CPU_LATENCY, 1283 .max_register = FSL_SAI_RTCAP, 1284}; 1285 1286static const struct of_device_id fsl_sai_ids[] = { 1287 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data }, 1288 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data }, 1289 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data }, 1290 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data }, 1291 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data }, 1292 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data }, 1293 { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data }, 1294 { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data }, 1295 { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data }, 1296 { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mp_data }, 1297 { /* sentinel */ } 1298}; 1299MODULE_DEVICE_TABLE(of, fsl_sai_ids); 1300 1301static int fsl_sai_runtime_suspend(struct device *dev) 1302{ 1303 struct fsl_sai *sai = dev_get_drvdata(dev); 1304 1305 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) 1306 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); 1307 1308 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) 1309 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]); 1310 1311 clk_disable_unprepare(sai->bus_clk); 1312 1313 if (sai->soc_data->flags & PMQOS_CPU_LATENCY) 1314 cpu_latency_qos_remove_request(&sai->pm_qos_req); 1315 1316 regcache_cache_only(sai->regmap, true); 1317 1318 return 0; 1319} 1320 1321static int fsl_sai_runtime_resume(struct device *dev) 1322{ 1323 struct fsl_sai *sai = dev_get_drvdata(dev); 1324 unsigned int ofs = sai->soc_data->reg_offset; 1325 int ret; 1326 1327 ret = clk_prepare_enable(sai->bus_clk); 1328 if (ret) { 1329 dev_err(dev, "failed to enable bus clock: %d\n", ret); 1330 return ret; 1331 } 1332 1333 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) { 1334 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]); 1335 if (ret) 1336 goto disable_bus_clk; 1337 } 1338 1339 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) { 1340 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]); 1341 if (ret) 1342 goto disable_tx_clk; 1343 } 1344 1345 if (sai->soc_data->flags & PMQOS_CPU_LATENCY) 1346 cpu_latency_qos_add_request(&sai->pm_qos_req, 0); 1347 1348 regcache_cache_only(sai->regmap, false); 1349 regcache_mark_dirty(sai->regmap); 1350 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); 1351 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); 1352 usleep_range(1000, 2000); 1353 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); 1354 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); 1355 1356 ret = regcache_sync(sai->regmap); 1357 if (ret) 1358 goto disable_rx_clk; 1359 1360 return 0; 1361 1362disable_rx_clk: 1363 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) 1364 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); 1365disable_tx_clk: 1366 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) 1367 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]); 1368disable_bus_clk: 1369 clk_disable_unprepare(sai->bus_clk); 1370 1371 return ret; 1372} 1373 1374static const struct dev_pm_ops fsl_sai_pm_ops = { 1375 SET_RUNTIME_PM_OPS(fsl_sai_runtime_suspend, 1376 fsl_sai_runtime_resume, NULL) 1377 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1378 pm_runtime_force_resume) 1379}; 1380 1381static struct platform_driver fsl_sai_driver = { 1382 .probe = fsl_sai_probe, 1383 .remove = fsl_sai_remove, 1384 .driver = { 1385 .name = "fsl-sai", 1386 .pm = &fsl_sai_pm_ops, 1387 .of_match_table = fsl_sai_ids, 1388 }, 1389}; 1390module_platform_driver(fsl_sai_driver); 1391 1392MODULE_DESCRIPTION("Freescale Soc SAI Interface"); 1393MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>"); 1394MODULE_ALIAS("platform:fsl-sai"); 1395MODULE_LICENSE("GPL");