1836 lines · c
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.h>12#include <linux/pinctrl/consumer.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 "fsl_utils.h"26#include "imx-pcm.h"27 28#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\29 FSL_SAI_CSR_FEIE)30 31static const unsigned int fsl_sai_rates[] = {32 8000, 11025, 12000, 16000, 22050,33 24000, 32000, 44100, 48000, 64000,34 88200, 96000, 176400, 192000, 352800,35 384000, 705600, 768000, 1411200, 2822400,36};37 38static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {39 .count = ARRAY_SIZE(fsl_sai_rates),40 .list = fsl_sai_rates,41};42 43/**44 * fsl_sai_dir_is_synced - Check if stream is synced by the opposite stream45 *46 * SAI supports synchronous mode using bit/frame clocks of either Transmitter's47 * or Receiver's for both streams. This function is used to check if clocks of48 * the stream's are synced by the opposite stream.49 *50 * @sai: SAI context51 * @dir: stream direction52 */53static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir)54{55 int adir = (dir == TX) ? RX : TX;56 57 /* current dir in async mode while opposite dir in sync mode */58 return !sai->synchronous[dir] && sai->synchronous[adir];59}60 61static struct pinctrl_state *fsl_sai_get_pins_state(struct fsl_sai *sai, u32 bclk)62{63 struct pinctrl_state *state = NULL;64 65 if (sai->is_pdm_mode) {66 /* DSD512@44.1kHz, DSD512@48kHz */67 if (bclk >= 22579200)68 state = pinctrl_lookup_state(sai->pinctrl, "dsd512");69 70 /* Get default DSD state */71 if (IS_ERR_OR_NULL(state))72 state = pinctrl_lookup_state(sai->pinctrl, "dsd");73 } else {74 /* 706k32b2c, 768k32b2c, etc */75 if (bclk >= 45158400)76 state = pinctrl_lookup_state(sai->pinctrl, "pcm_b2m");77 }78 79 /* Get default state */80 if (IS_ERR_OR_NULL(state))81 state = pinctrl_lookup_state(sai->pinctrl, "default");82 83 return state;84}85 86static irqreturn_t fsl_sai_isr(int irq, void *devid)87{88 struct fsl_sai *sai = (struct fsl_sai *)devid;89 unsigned int ofs = sai->soc_data->reg_offset;90 struct device *dev = &sai->pdev->dev;91 u32 flags, xcsr, mask;92 irqreturn_t iret = IRQ_NONE;93 94 /*95 * Both IRQ status bits and IRQ mask bits are in the xCSR but96 * different shifts. And we here create a mask only for those97 * IRQs that we activated.98 */99 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;100 101 /* Tx IRQ */102 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr);103 flags = xcsr & mask;104 105 if (flags)106 iret = IRQ_HANDLED;107 else108 goto irq_rx;109 110 if (flags & FSL_SAI_CSR_WSF)111 dev_dbg(dev, "isr: Start of Tx word detected\n");112 113 if (flags & FSL_SAI_CSR_SEF)114 dev_dbg(dev, "isr: Tx Frame sync error detected\n");115 116 if (flags & FSL_SAI_CSR_FEF)117 dev_dbg(dev, "isr: Transmit underrun detected\n");118 119 if (flags & FSL_SAI_CSR_FWF)120 dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");121 122 if (flags & FSL_SAI_CSR_FRF)123 dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");124 125 flags &= FSL_SAI_CSR_xF_W_MASK;126 xcsr &= ~FSL_SAI_CSR_xF_MASK;127 128 if (flags)129 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr);130 131irq_rx:132 /* Rx IRQ */133 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr);134 flags = xcsr & mask;135 136 if (flags)137 iret = IRQ_HANDLED;138 else139 goto out;140 141 if (flags & FSL_SAI_CSR_WSF)142 dev_dbg(dev, "isr: Start of Rx word detected\n");143 144 if (flags & FSL_SAI_CSR_SEF)145 dev_dbg(dev, "isr: Rx Frame sync error detected\n");146 147 if (flags & FSL_SAI_CSR_FEF)148 dev_dbg(dev, "isr: Receive overflow detected\n");149 150 if (flags & FSL_SAI_CSR_FWF)151 dev_dbg(dev, "isr: Enabled receive FIFO is full\n");152 153 if (flags & FSL_SAI_CSR_FRF)154 dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");155 156 flags &= FSL_SAI_CSR_xF_W_MASK;157 xcsr &= ~FSL_SAI_CSR_xF_MASK;158 159 if (flags)160 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr);161 162out:163 return iret;164}165 166static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,167 u32 rx_mask, int slots, int slot_width)168{169 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);170 171 sai->slots = slots;172 sai->slot_width = slot_width;173 174 return 0;175}176 177static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai,178 unsigned int ratio)179{180 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);181 182 sai->bclk_ratio = ratio;183 184 return 0;185}186 187static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,188 int clk_id, unsigned int freq, bool tx)189{190 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);191 unsigned int ofs = sai->soc_data->reg_offset;192 u32 val_cr2 = 0;193 194 switch (clk_id) {195 case FSL_SAI_CLK_BUS:196 val_cr2 |= FSL_SAI_CR2_MSEL_BUS;197 break;198 case FSL_SAI_CLK_MAST1:199 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;200 break;201 case FSL_SAI_CLK_MAST2:202 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;203 break;204 case FSL_SAI_CLK_MAST3:205 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;206 break;207 default:208 return -EINVAL;209 }210 211 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),212 FSL_SAI_CR2_MSEL_MASK, val_cr2);213 214 return 0;215}216 217static int fsl_sai_set_mclk_rate(struct snd_soc_dai *dai, int clk_id, unsigned int freq)218{219 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);220 int ret;221 222 fsl_asoc_reparent_pll_clocks(dai->dev, sai->mclk_clk[clk_id],223 sai->pll8k_clk, sai->pll11k_clk, freq);224 225 ret = clk_set_rate(sai->mclk_clk[clk_id], freq);226 if (ret < 0)227 dev_err(dai->dev, "failed to set clock rate (%u): %d\n", freq, ret);228 229 return ret;230}231 232static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,233 int clk_id, unsigned int freq, int dir)234{235 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);236 int ret;237 238 if (dir == SND_SOC_CLOCK_IN)239 return 0;240 241 if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) {242 if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) {243 dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id);244 return -EINVAL;245 }246 247 if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) {248 dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id);249 return -EINVAL;250 }251 252 if (sai->mclk_streams == 0) {253 ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq);254 if (ret < 0)255 return ret;256 }257 }258 259 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, true);260 if (ret) {261 dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);262 return ret;263 }264 265 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, false);266 if (ret)267 dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);268 269 return ret;270}271 272static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,273 unsigned int fmt, bool tx)274{275 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);276 unsigned int ofs = sai->soc_data->reg_offset;277 u32 val_cr2 = 0, val_cr4 = 0;278 279 if (!sai->is_lsb_first)280 val_cr4 |= FSL_SAI_CR4_MF;281 282 sai->is_pdm_mode = false;283 sai->is_dsp_mode = false;284 /* DAI mode */285 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {286 case SND_SOC_DAIFMT_I2S:287 /*288 * Frame low, 1clk before data, one word length for frame sync,289 * frame sync starts one serial clock cycle earlier,290 * that is, together with the last bit of the previous291 * data word.292 */293 val_cr2 |= FSL_SAI_CR2_BCP;294 val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;295 break;296 case SND_SOC_DAIFMT_LEFT_J:297 /*298 * Frame high, one word length for frame sync,299 * frame sync asserts with the first bit of the frame.300 */301 val_cr2 |= FSL_SAI_CR2_BCP;302 break;303 case SND_SOC_DAIFMT_DSP_A:304 /*305 * Frame high, 1clk before data, one bit for frame sync,306 * frame sync starts one serial clock cycle earlier,307 * that is, together with the last bit of the previous308 * data word.309 */310 val_cr2 |= FSL_SAI_CR2_BCP;311 val_cr4 |= FSL_SAI_CR4_FSE;312 sai->is_dsp_mode = true;313 break;314 case SND_SOC_DAIFMT_DSP_B:315 /*316 * Frame high, one bit for frame sync,317 * frame sync asserts with the first bit of the frame.318 */319 val_cr2 |= FSL_SAI_CR2_BCP;320 sai->is_dsp_mode = true;321 break;322 case SND_SOC_DAIFMT_PDM:323 val_cr2 |= FSL_SAI_CR2_BCP;324 val_cr4 &= ~FSL_SAI_CR4_MF;325 sai->is_pdm_mode = true;326 break;327 case SND_SOC_DAIFMT_RIGHT_J:328 /* To be done */329 default:330 return -EINVAL;331 }332 333 /* DAI clock inversion */334 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {335 case SND_SOC_DAIFMT_IB_IF:336 /* Invert both clocks */337 val_cr2 ^= FSL_SAI_CR2_BCP;338 val_cr4 ^= FSL_SAI_CR4_FSP;339 break;340 case SND_SOC_DAIFMT_IB_NF:341 /* Invert bit clock */342 val_cr2 ^= FSL_SAI_CR2_BCP;343 break;344 case SND_SOC_DAIFMT_NB_IF:345 /* Invert frame clock */346 val_cr4 ^= FSL_SAI_CR4_FSP;347 break;348 case SND_SOC_DAIFMT_NB_NF:349 /* Nothing to do for both normal cases */350 break;351 default:352 return -EINVAL;353 }354 355 /* DAI clock provider masks */356 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {357 case SND_SOC_DAIFMT_BP_FP:358 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;359 val_cr4 |= FSL_SAI_CR4_FSD_MSTR;360 sai->is_consumer_mode[tx] = false;361 break;362 case SND_SOC_DAIFMT_BC_FC:363 sai->is_consumer_mode[tx] = true;364 break;365 case SND_SOC_DAIFMT_BP_FC:366 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;367 sai->is_consumer_mode[tx] = false;368 break;369 case SND_SOC_DAIFMT_BC_FP:370 val_cr4 |= FSL_SAI_CR4_FSD_MSTR;371 sai->is_consumer_mode[tx] = true;372 break;373 default:374 return -EINVAL;375 }376 377 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),378 FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);379 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),380 FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |381 FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);382 383 return 0;384}385 386static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)387{388 int ret;389 390 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, true);391 if (ret) {392 dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);393 return ret;394 }395 396 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, false);397 if (ret)398 dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);399 400 return ret;401}402 403static int fsl_sai_set_dai_fmt_tx(struct snd_soc_dai *cpu_dai, unsigned int fmt)404{405 return fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, true);406}407 408static int fsl_sai_set_dai_fmt_rx(struct snd_soc_dai *cpu_dai, unsigned int fmt)409{410 return fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, false);411}412 413static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)414{415 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);416 unsigned int reg, ofs = sai->soc_data->reg_offset;417 unsigned long clk_rate;418 u32 savediv = 0, ratio, bestdiff = freq;419 int adir = tx ? RX : TX;420 int dir = tx ? TX : RX;421 u32 id;422 bool support_1_1_ratio = sai->verid.version >= 0x0301;423 424 /* Don't apply to consumer mode */425 if (sai->is_consumer_mode[tx])426 return 0;427 428 /*429 * There is no point in polling MCLK0 if it is identical to MCLK1.430 * And given that MQS use case has to use MCLK1 though two clocks431 * are the same, we simply skip MCLK0 and start to find from MCLK1.432 */433 id = sai->soc_data->mclk0_is_mclk1 ? 1 : 0;434 435 for (; id < FSL_SAI_MCLK_MAX; id++) {436 int diff;437 438 clk_rate = clk_get_rate(sai->mclk_clk[id]);439 if (!clk_rate)440 continue;441 442 ratio = DIV_ROUND_CLOSEST(clk_rate, freq);443 if (!ratio || ratio > 512)444 continue;445 if (ratio == 1 && !support_1_1_ratio)446 continue;447 if ((ratio & 1) && ratio > 1)448 continue;449 450 diff = abs((long)clk_rate - ratio * freq);451 452 /*453 * Drop the source that can not be454 * divided into the required rate.455 */456 if (diff != 0 && clk_rate / diff < 1000)457 continue;458 459 dev_dbg(dai->dev,460 "ratio %d for freq %dHz based on clock %ldHz\n",461 ratio, freq, clk_rate);462 463 464 if (diff < bestdiff) {465 savediv = ratio;466 sai->mclk_id[tx] = id;467 bestdiff = diff;468 }469 470 if (diff == 0)471 break;472 }473 474 if (savediv == 0) {475 dev_err(dai->dev, "failed to derive required %cx rate: %d\n",476 tx ? 'T' : 'R', freq);477 return -EINVAL;478 }479 480 dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n",481 sai->mclk_id[tx], savediv, bestdiff);482 483 /*484 * 1) For Asynchronous mode, we must set RCR2 register for capture, and485 * set TCR2 register for playback.486 * 2) For Tx sync with Rx clock, we must set RCR2 register for playback487 * and capture.488 * 3) For Rx sync with Tx clock, we must set TCR2 register for playback489 * and capture.490 * 4) For Tx and Rx are both Synchronous with another SAI, we just491 * ignore it.492 */493 if (fsl_sai_dir_is_synced(sai, adir))494 reg = FSL_SAI_xCR2(!tx, ofs);495 else if (!sai->synchronous[dir])496 reg = FSL_SAI_xCR2(tx, ofs);497 else498 return 0;499 500 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,501 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));502 503 if (savediv == 1) {504 regmap_update_bits(sai->regmap, reg,505 FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP,506 FSL_SAI_CR2_BYP);507 if (fsl_sai_dir_is_synced(sai, adir))508 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),509 FSL_SAI_CR2_BCI, FSL_SAI_CR2_BCI);510 else511 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),512 FSL_SAI_CR2_BCI, 0);513 } else {514 regmap_update_bits(sai->regmap, reg,515 FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP,516 savediv / 2 - 1);517 }518 519 return 0;520}521 522static int fsl_sai_hw_params(struct snd_pcm_substream *substream,523 struct snd_pcm_hw_params *params,524 struct snd_soc_dai *cpu_dai)525{526 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);527 unsigned int ofs = sai->soc_data->reg_offset;528 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;529 unsigned int channels = params_channels(params);530 struct snd_dmaengine_dai_dma_data *dma_params;531 struct fsl_sai_dl_cfg *dl_cfg = sai->dl_cfg;532 u32 word_width = params_width(params);533 int trce_mask = 0, dl_cfg_idx = 0;534 int dl_cfg_cnt = sai->dl_cfg_cnt;535 u32 dl_type = FSL_SAI_DL_I2S;536 u32 val_cr4 = 0, val_cr5 = 0;537 u32 slots = (channels == 1) ? 2 : channels;538 u32 slot_width = word_width;539 int adir = tx ? RX : TX;540 u32 pins, bclk;541 u32 watermark;542 int ret, i;543 544 if (sai->slot_width)545 slot_width = sai->slot_width;546 547 if (sai->slots)548 slots = sai->slots;549 else if (sai->bclk_ratio)550 slots = sai->bclk_ratio / slot_width;551 552 pins = DIV_ROUND_UP(channels, slots);553 554 /*555 * PDM mode, channels are independent556 * each channels are on one dataline/FIFO.557 */558 if (sai->is_pdm_mode) {559 pins = channels;560 dl_type = FSL_SAI_DL_PDM;561 }562 563 for (i = 0; i < dl_cfg_cnt; i++) {564 if (dl_cfg[i].type == dl_type && dl_cfg[i].pins[tx] == pins) {565 dl_cfg_idx = i;566 break;567 }568 }569 570 if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) < pins) {571 dev_err(cpu_dai->dev, "channel not supported\n");572 return -EINVAL;573 }574 575 bclk = params_rate(params) * (sai->bclk_ratio ? sai->bclk_ratio : slots * slot_width);576 577 if (!IS_ERR_OR_NULL(sai->pinctrl)) {578 sai->pins_state = fsl_sai_get_pins_state(sai, bclk);579 if (!IS_ERR_OR_NULL(sai->pins_state)) {580 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);581 if (ret) {582 dev_err(cpu_dai->dev, "failed to set proper pins state: %d\n", ret);583 return ret;584 }585 }586 }587 588 if (!sai->is_consumer_mode[tx]) {589 ret = fsl_sai_set_bclk(cpu_dai, tx, bclk);590 if (ret)591 return ret;592 593 /* Do not enable the clock if it is already enabled */594 if (!(sai->mclk_streams & BIT(substream->stream))) {595 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);596 if (ret)597 return ret;598 599 sai->mclk_streams |= BIT(substream->stream);600 }601 }602 603 if (!sai->is_dsp_mode && !sai->is_pdm_mode)604 val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);605 606 val_cr5 |= FSL_SAI_CR5_WNW(slot_width);607 val_cr5 |= FSL_SAI_CR5_W0W(slot_width);608 609 if (sai->is_lsb_first || sai->is_pdm_mode)610 val_cr5 |= FSL_SAI_CR5_FBT(0);611 else612 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);613 614 val_cr4 |= FSL_SAI_CR4_FRSZ(slots);615 616 /* Set to avoid channel swap */617 val_cr4 |= FSL_SAI_CR4_FCONT;618 619 /* Set to output mode to avoid tri-stated data pins */620 if (tx)621 val_cr4 |= FSL_SAI_CR4_CHMOD;622 623 /*624 * For SAI provider mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will625 * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4),626 * RCR5(TCR5) for playback(capture), or there will be sync error.627 */628 629 if (!sai->is_consumer_mode[tx] && fsl_sai_dir_is_synced(sai, adir)) {630 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs),631 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |632 FSL_SAI_CR4_CHMOD_MASK,633 val_cr4);634 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs),635 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |636 FSL_SAI_CR5_FBT_MASK, val_cr5);637 }638 639 /*640 * Combine mode has limation:641 * - Can't used for singel dataline/FIFO case except the FIFO0642 * - Can't used for multi dataline/FIFO case except the enabled FIFOs643 * are successive and start from FIFO0644 *645 * So for common usage, all multi fifo case disable the combine mode.646 */647 if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) <= 1 || sai->is_multi_fifo_dma)648 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),649 FSL_SAI_CR4_FCOMB_MASK, 0);650 else651 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),652 FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT);653 654 dma_params = tx ? &sai->dma_params_tx : &sai->dma_params_rx;655 dma_params->addr = sai->res->start + FSL_SAI_xDR0(tx) +656 dl_cfg[dl_cfg_idx].start_off[tx] * 0x4;657 658 if (sai->is_multi_fifo_dma) {659 sai->audio_config[tx].words_per_fifo = min(slots, channels);660 if (tx) {661 sai->audio_config[tx].n_fifos_dst = pins;662 sai->audio_config[tx].stride_fifos_dst = dl_cfg[dl_cfg_idx].next_off[tx];663 } else {664 sai->audio_config[tx].n_fifos_src = pins;665 sai->audio_config[tx].stride_fifos_src = dl_cfg[dl_cfg_idx].next_off[tx];666 }667 dma_params->maxburst = sai->audio_config[tx].words_per_fifo * pins;668 dma_params->peripheral_config = &sai->audio_config[tx];669 dma_params->peripheral_size = sizeof(sai->audio_config[tx]);670 671 watermark = tx ? (sai->soc_data->fifo_depth - dma_params->maxburst) :672 (dma_params->maxburst - 1);673 regmap_update_bits(sai->regmap, FSL_SAI_xCR1(tx, ofs),674 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),675 watermark);676 }677 678 /* Find a proper tcre setting */679 for (i = 0; i < sai->soc_data->pins; i++) {680 trce_mask = (1 << (i + 1)) - 1;681 if (hweight8(dl_cfg[dl_cfg_idx].mask[tx] & trce_mask) == pins)682 break;683 }684 685 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),686 FSL_SAI_CR3_TRCE_MASK,687 FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask)));688 689 /*690 * When the TERE and FSD_MSTR enabled before configuring the word width691 * There will be no frame sync clock issue, because word width impact692 * the generation of frame sync clock.693 *694 * TERE enabled earlier only for i.MX8MP case for the hardware limitation,695 * We need to disable FSD_MSTR before configuring word width, then enable696 * FSD_MSTR bit for this specific case.697 */698 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&699 !sai->is_consumer_mode[tx])700 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),701 FSL_SAI_CR4_FSD_MSTR, 0);702 703 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),704 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |705 FSL_SAI_CR4_CHMOD_MASK | FSL_SAI_CR4_FCONT_MASK,706 val_cr4);707 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),708 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |709 FSL_SAI_CR5_FBT_MASK, val_cr5);710 711 /* Enable FSD_MSTR after configuring word width */712 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&713 !sai->is_consumer_mode[tx])714 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),715 FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);716 717 regmap_write(sai->regmap, FSL_SAI_xMR(tx),718 ~0UL - ((1 << min(channels, slots)) - 1));719 720 return 0;721}722 723static int fsl_sai_hw_free(struct snd_pcm_substream *substream,724 struct snd_soc_dai *cpu_dai)725{726 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);727 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;728 unsigned int ofs = sai->soc_data->reg_offset;729 730 /* Clear xMR to avoid channel swap with mclk_with_tere enabled case */731 regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0);732 733 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),734 FSL_SAI_CR3_TRCE_MASK, 0);735 736 if (!sai->is_consumer_mode[tx] &&737 sai->mclk_streams & BIT(substream->stream)) {738 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);739 sai->mclk_streams &= ~BIT(substream->stream);740 }741 742 return 0;743}744 745static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)746{747 unsigned int ofs = sai->soc_data->reg_offset;748 bool tx = dir == TX;749 u32 xcsr, count = 100, mask;750 751 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)752 mask = FSL_SAI_CSR_TERE;753 else754 mask = FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE;755 756 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),757 mask, 0);758 759 /* TERE will remain set till the end of current frame */760 do {761 udelay(10);762 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr);763 } while (--count && xcsr & FSL_SAI_CSR_TERE);764 765 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),766 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);767 768 /*769 * For sai master mode, after several open/close sai,770 * there will be no frame clock, and can't recover771 * anymore. Add software reset to fix this issue.772 * This is a hardware bug, and will be fix in the773 * next sai version.774 */775 if (!sai->is_consumer_mode[tx]) {776 /* Software Reset */777 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR);778 /* Clear SR bit to finish the reset */779 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0);780 }781}782 783static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,784 struct snd_soc_dai *cpu_dai)785{786 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);787 unsigned int ofs = sai->soc_data->reg_offset;788 789 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;790 int adir = tx ? RX : TX;791 int dir = tx ? TX : RX;792 u32 xcsr;793 794 /*795 * Asynchronous mode: Clear SYNC for both Tx and Rx.796 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.797 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.798 */799 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC,800 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);801 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC,802 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);803 804 /*805 * It is recommended that the transmitter is the last enabled806 * and the first disabled.807 */808 switch (cmd) {809 case SNDRV_PCM_TRIGGER_START:810 case SNDRV_PCM_TRIGGER_RESUME:811 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:812 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),813 FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);814 815 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),816 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);817 /*818 * Enable the opposite direction for synchronous mode819 * 1. Tx sync with Rx: only set RE for Rx; set TE & RE for Tx820 * 2. Rx sync with Tx: only set TE for Tx; set RE & TE for Rx821 *822 * RM recommends to enable RE after TE for case 1 and to enable823 * TE after RE for case 2, but we here may not always guarantee824 * that happens: "arecord 1.wav; aplay 2.wav" in case 1 enables825 * TE after RE, which is against what RM recommends but should826 * be safe to do, judging by years of testing results.827 */828 if (fsl_sai_dir_is_synced(sai, adir))829 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs),830 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);831 832 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),833 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);834 break;835 case SNDRV_PCM_TRIGGER_STOP:836 case SNDRV_PCM_TRIGGER_SUSPEND:837 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:838 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),839 FSL_SAI_CSR_FRDE, 0);840 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),841 FSL_SAI_CSR_xIE_MASK, 0);842 843 /* Check if the opposite FRDE is also disabled */844 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr);845 846 /*847 * If opposite stream provides clocks for synchronous mode and848 * it is inactive, disable it before disabling the current one849 */850 if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE))851 fsl_sai_config_disable(sai, adir);852 853 /*854 * Disable current stream if either of:855 * 1. current stream doesn't provide clocks for synchronous mode856 * 2. current stream provides clocks for synchronous mode but no857 * more stream is active.858 */859 if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE))860 fsl_sai_config_disable(sai, dir);861 862 break;863 default:864 return -EINVAL;865 }866 867 return 0;868}869 870static int fsl_sai_startup(struct snd_pcm_substream *substream,871 struct snd_soc_dai *cpu_dai)872{873 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);874 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;875 int ret;876 877 /*878 * EDMA controller needs period size to be a multiple of879 * tx/rx maxburst880 */881 if (sai->soc_data->use_edma)882 snd_pcm_hw_constraint_step(substream->runtime, 0,883 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,884 tx ? sai->dma_params_tx.maxburst :885 sai->dma_params_rx.maxburst);886 887 ret = snd_pcm_hw_constraint_list(substream->runtime, 0,888 SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);889 890 return ret;891}892 893static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)894{895 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);896 unsigned int ofs = sai->soc_data->reg_offset;897 898 /* Software Reset for both Tx and Rx */899 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);900 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);901 /* Clear SR bit to finish the reset */902 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);903 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);904 905 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs),906 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),907 sai->soc_data->fifo_depth - sai->dma_params_tx.maxburst);908 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs),909 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),910 sai->dma_params_rx.maxburst - 1);911 912 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,913 &sai->dma_params_rx);914 915 return 0;916}917 918static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {919 .probe = fsl_sai_dai_probe,920 .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio,921 .set_sysclk = fsl_sai_set_dai_sysclk,922 .set_fmt = fsl_sai_set_dai_fmt,923 .set_tdm_slot = fsl_sai_set_dai_tdm_slot,924 .hw_params = fsl_sai_hw_params,925 .hw_free = fsl_sai_hw_free,926 .trigger = fsl_sai_trigger,927 .startup = fsl_sai_startup,928};929 930static const struct snd_soc_dai_ops fsl_sai_pcm_dai_tx_ops = {931 .probe = fsl_sai_dai_probe,932 .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio,933 .set_sysclk = fsl_sai_set_dai_sysclk,934 .set_fmt = fsl_sai_set_dai_fmt_tx,935 .set_tdm_slot = fsl_sai_set_dai_tdm_slot,936 .hw_params = fsl_sai_hw_params,937 .hw_free = fsl_sai_hw_free,938 .trigger = fsl_sai_trigger,939 .startup = fsl_sai_startup,940};941 942static const struct snd_soc_dai_ops fsl_sai_pcm_dai_rx_ops = {943 .probe = fsl_sai_dai_probe,944 .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio,945 .set_sysclk = fsl_sai_set_dai_sysclk,946 .set_fmt = fsl_sai_set_dai_fmt_rx,947 .set_tdm_slot = fsl_sai_set_dai_tdm_slot,948 .hw_params = fsl_sai_hw_params,949 .hw_free = fsl_sai_hw_free,950 .trigger = fsl_sai_trigger,951 .startup = fsl_sai_startup,952};953 954static int fsl_sai_dai_resume(struct snd_soc_component *component)955{956 struct fsl_sai *sai = snd_soc_component_get_drvdata(component);957 struct device *dev = &sai->pdev->dev;958 int ret;959 960 if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) {961 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);962 if (ret) {963 dev_err(dev, "failed to set proper pins state: %d\n", ret);964 return ret;965 }966 }967 968 return 0;969}970 971static struct snd_soc_dai_driver fsl_sai_dai_template[] = {972 {973 .name = "sai-tx-rx",974 .playback = {975 .stream_name = "CPU-Playback",976 .channels_min = 1,977 .channels_max = 32,978 .rate_min = 8000,979 .rate_max = 2822400,980 .rates = SNDRV_PCM_RATE_KNOT,981 .formats = FSL_SAI_FORMATS,982 },983 .capture = {984 .stream_name = "CPU-Capture",985 .channels_min = 1,986 .channels_max = 32,987 .rate_min = 8000,988 .rate_max = 2822400,989 .rates = SNDRV_PCM_RATE_KNOT,990 .formats = FSL_SAI_FORMATS,991 },992 .ops = &fsl_sai_pcm_dai_ops,993 },994 {995 .name = "sai-tx",996 .playback = {997 .stream_name = "CPU-Playback",998 .channels_min = 1,999 .channels_max = 32,1000 .rate_min = 8000,1001 .rate_max = 2822400,1002 .rates = SNDRV_PCM_RATE_KNOT,1003 .formats = FSL_SAI_FORMATS,1004 },1005 .ops = &fsl_sai_pcm_dai_tx_ops,1006 },1007 {1008 .name = "sai-rx",1009 .capture = {1010 .stream_name = "CPU-Capture",1011 .channels_min = 1,1012 .channels_max = 32,1013 .rate_min = 8000,1014 .rate_max = 2822400,1015 .rates = SNDRV_PCM_RATE_KNOT,1016 .formats = FSL_SAI_FORMATS,1017 },1018 .ops = &fsl_sai_pcm_dai_rx_ops,1019 },1020};1021 1022static const struct snd_soc_component_driver fsl_component = {1023 .name = "fsl-sai",1024 .resume = fsl_sai_dai_resume,1025 .legacy_dai_naming = 1,1026};1027 1028static struct reg_default fsl_sai_reg_defaults_ofs0[] = {1029 {FSL_SAI_TCR1(0), 0},1030 {FSL_SAI_TCR2(0), 0},1031 {FSL_SAI_TCR3(0), 0},1032 {FSL_SAI_TCR4(0), 0},1033 {FSL_SAI_TCR5(0), 0},1034 {FSL_SAI_TDR0, 0},1035 {FSL_SAI_TDR1, 0},1036 {FSL_SAI_TDR2, 0},1037 {FSL_SAI_TDR3, 0},1038 {FSL_SAI_TDR4, 0},1039 {FSL_SAI_TDR5, 0},1040 {FSL_SAI_TDR6, 0},1041 {FSL_SAI_TDR7, 0},1042 {FSL_SAI_TMR, 0},1043 {FSL_SAI_RCR1(0), 0},1044 {FSL_SAI_RCR2(0), 0},1045 {FSL_SAI_RCR3(0), 0},1046 {FSL_SAI_RCR4(0), 0},1047 {FSL_SAI_RCR5(0), 0},1048 {FSL_SAI_RMR, 0},1049};1050 1051static struct reg_default fsl_sai_reg_defaults_ofs8[] = {1052 {FSL_SAI_TCR1(8), 0},1053 {FSL_SAI_TCR2(8), 0},1054 {FSL_SAI_TCR3(8), 0},1055 {FSL_SAI_TCR4(8), 0},1056 {FSL_SAI_TCR5(8), 0},1057 {FSL_SAI_TDR0, 0},1058 {FSL_SAI_TDR1, 0},1059 {FSL_SAI_TDR2, 0},1060 {FSL_SAI_TDR3, 0},1061 {FSL_SAI_TDR4, 0},1062 {FSL_SAI_TDR5, 0},1063 {FSL_SAI_TDR6, 0},1064 {FSL_SAI_TDR7, 0},1065 {FSL_SAI_TMR, 0},1066 {FSL_SAI_RCR1(8), 0},1067 {FSL_SAI_RCR2(8), 0},1068 {FSL_SAI_RCR3(8), 0},1069 {FSL_SAI_RCR4(8), 0},1070 {FSL_SAI_RCR5(8), 0},1071 {FSL_SAI_RMR, 0},1072 {FSL_SAI_MCTL, 0},1073 {FSL_SAI_MDIV, 0},1074};1075 1076static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)1077{1078 struct fsl_sai *sai = dev_get_drvdata(dev);1079 unsigned int ofs = sai->soc_data->reg_offset;1080 1081 if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs))1082 return true;1083 1084 if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs))1085 return true;1086 1087 switch (reg) {1088 case FSL_SAI_TFR0:1089 case FSL_SAI_TFR1:1090 case FSL_SAI_TFR2:1091 case FSL_SAI_TFR3:1092 case FSL_SAI_TFR4:1093 case FSL_SAI_TFR5:1094 case FSL_SAI_TFR6:1095 case FSL_SAI_TFR7:1096 case FSL_SAI_TMR:1097 case FSL_SAI_RDR0:1098 case FSL_SAI_RDR1:1099 case FSL_SAI_RDR2:1100 case FSL_SAI_RDR3:1101 case FSL_SAI_RDR4:1102 case FSL_SAI_RDR5:1103 case FSL_SAI_RDR6:1104 case FSL_SAI_RDR7:1105 case FSL_SAI_RFR0:1106 case FSL_SAI_RFR1:1107 case FSL_SAI_RFR2:1108 case FSL_SAI_RFR3:1109 case FSL_SAI_RFR4:1110 case FSL_SAI_RFR5:1111 case FSL_SAI_RFR6:1112 case FSL_SAI_RFR7:1113 case FSL_SAI_RMR:1114 case FSL_SAI_MCTL:1115 case FSL_SAI_MDIV:1116 case FSL_SAI_VERID:1117 case FSL_SAI_PARAM:1118 case FSL_SAI_TTCTN:1119 case FSL_SAI_RTCTN:1120 case FSL_SAI_TTCTL:1121 case FSL_SAI_TBCTN:1122 case FSL_SAI_TTCAP:1123 case FSL_SAI_RTCTL:1124 case FSL_SAI_RBCTN:1125 case FSL_SAI_RTCAP:1126 return true;1127 default:1128 return false;1129 }1130}1131 1132static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)1133{1134 struct fsl_sai *sai = dev_get_drvdata(dev);1135 unsigned int ofs = sai->soc_data->reg_offset;1136 1137 if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs))1138 return true;1139 1140 /* Set VERID and PARAM be volatile for reading value in probe */1141 if (ofs == 8 && (reg == FSL_SAI_VERID || reg == FSL_SAI_PARAM))1142 return true;1143 1144 switch (reg) {1145 case FSL_SAI_TFR0:1146 case FSL_SAI_TFR1:1147 case FSL_SAI_TFR2:1148 case FSL_SAI_TFR3:1149 case FSL_SAI_TFR4:1150 case FSL_SAI_TFR5:1151 case FSL_SAI_TFR6:1152 case FSL_SAI_TFR7:1153 case FSL_SAI_RFR0:1154 case FSL_SAI_RFR1:1155 case FSL_SAI_RFR2:1156 case FSL_SAI_RFR3:1157 case FSL_SAI_RFR4:1158 case FSL_SAI_RFR5:1159 case FSL_SAI_RFR6:1160 case FSL_SAI_RFR7:1161 case FSL_SAI_RDR0:1162 case FSL_SAI_RDR1:1163 case FSL_SAI_RDR2:1164 case FSL_SAI_RDR3:1165 case FSL_SAI_RDR4:1166 case FSL_SAI_RDR5:1167 case FSL_SAI_RDR6:1168 case FSL_SAI_RDR7:1169 return true;1170 default:1171 return false;1172 }1173}1174 1175static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)1176{1177 struct fsl_sai *sai = dev_get_drvdata(dev);1178 unsigned int ofs = sai->soc_data->reg_offset;1179 1180 if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs))1181 return true;1182 1183 if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs))1184 return true;1185 1186 switch (reg) {1187 case FSL_SAI_TDR0:1188 case FSL_SAI_TDR1:1189 case FSL_SAI_TDR2:1190 case FSL_SAI_TDR3:1191 case FSL_SAI_TDR4:1192 case FSL_SAI_TDR5:1193 case FSL_SAI_TDR6:1194 case FSL_SAI_TDR7:1195 case FSL_SAI_TMR:1196 case FSL_SAI_RMR:1197 case FSL_SAI_MCTL:1198 case FSL_SAI_MDIV:1199 case FSL_SAI_TTCTL:1200 case FSL_SAI_RTCTL:1201 return true;1202 default:1203 return false;1204 }1205}1206 1207static struct regmap_config fsl_sai_regmap_config = {1208 .reg_bits = 32,1209 .reg_stride = 4,1210 .val_bits = 32,1211 .fast_io = true,1212 1213 .max_register = FSL_SAI_RMR,1214 .reg_defaults = fsl_sai_reg_defaults_ofs0,1215 .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0),1216 .readable_reg = fsl_sai_readable_reg,1217 .volatile_reg = fsl_sai_volatile_reg,1218 .writeable_reg = fsl_sai_writeable_reg,1219 .cache_type = REGCACHE_FLAT,1220};1221 1222static int fsl_sai_check_version(struct device *dev)1223{1224 struct fsl_sai *sai = dev_get_drvdata(dev);1225 unsigned char ofs = sai->soc_data->reg_offset;1226 unsigned int val;1227 int ret;1228 1229 if (FSL_SAI_TCSR(ofs) == FSL_SAI_VERID)1230 return 0;1231 1232 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);1233 if (ret < 0)1234 return ret;1235 1236 dev_dbg(dev, "VERID: 0x%016X\n", val);1237 1238 sai->verid.version = val &1239 (FSL_SAI_VERID_MAJOR_MASK | FSL_SAI_VERID_MINOR_MASK);1240 sai->verid.version >>= FSL_SAI_VERID_MINOR_SHIFT;1241 sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;1242 1243 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);1244 if (ret < 0)1245 return ret;1246 1247 dev_dbg(dev, "PARAM: 0x%016X\n", val);1248 1249 /* Max slots per frame, power of 2 */1250 sai->param.slot_num = 1 <<1251 ((val & FSL_SAI_PARAM_SPF_MASK) >> FSL_SAI_PARAM_SPF_SHIFT);1252 1253 /* Words per fifo, power of 2 */1254 sai->param.fifo_depth = 1 <<1255 ((val & FSL_SAI_PARAM_WPF_MASK) >> FSL_SAI_PARAM_WPF_SHIFT);1256 1257 /* Number of datalines implemented */1258 sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;1259 1260 return 0;1261}1262 1263/*1264 * Calculate the offset between first two datalines, don't1265 * different offset in one case.1266 */1267static unsigned int fsl_sai_calc_dl_off(unsigned long dl_mask)1268{1269 int fbidx, nbidx, offset;1270 1271 fbidx = find_first_bit(&dl_mask, FSL_SAI_DL_NUM);1272 nbidx = find_next_bit(&dl_mask, FSL_SAI_DL_NUM, fbidx + 1);1273 offset = nbidx - fbidx - 1;1274 1275 return (offset < 0 || offset >= (FSL_SAI_DL_NUM - 1) ? 0 : offset);1276}1277 1278/*1279 * read the fsl,dataline property from dts file.1280 * It has 3 value for each configuration, first one means the type:1281 * I2S(1) or PDM(2), second one is dataline mask for 'rx', third one is1282 * dataline mask for 'tx'. for example1283 *1284 * fsl,dataline = <1 0xff 0xff 2 0xff 0x11>,1285 *1286 * It means I2S type rx mask is 0xff, tx mask is 0xff, PDM type1287 * rx mask is 0xff, tx mask is 0x11 (dataline 1 and 4 enabled).1288 *1289 */1290static int fsl_sai_read_dlcfg(struct fsl_sai *sai)1291{1292 struct platform_device *pdev = sai->pdev;1293 struct device_node *np = pdev->dev.of_node;1294 struct device *dev = &pdev->dev;1295 int ret, elems, i, index, num_cfg;1296 char *propname = "fsl,dataline";1297 struct fsl_sai_dl_cfg *cfg;1298 unsigned long dl_mask;1299 unsigned int soc_dl;1300 u32 rx, tx, type;1301 1302 elems = of_property_count_u32_elems(np, propname);1303 1304 if (elems <= 0) {1305 elems = 0;1306 } else if (elems % 3) {1307 dev_err(dev, "Number of elements must be divisible to 3.\n");1308 return -EINVAL;1309 }1310 1311 num_cfg = elems / 3;1312 /* Add one more for default value */1313 cfg = devm_kzalloc(&pdev->dev, (num_cfg + 1) * sizeof(*cfg), GFP_KERNEL);1314 if (!cfg)1315 return -ENOMEM;1316 1317 /* Consider default value "0 0xFF 0xFF" if property is missing */1318 soc_dl = BIT(sai->soc_data->pins) - 1;1319 cfg[0].type = FSL_SAI_DL_DEFAULT;1320 cfg[0].pins[0] = sai->soc_data->pins;1321 cfg[0].mask[0] = soc_dl;1322 cfg[0].start_off[0] = 0;1323 cfg[0].next_off[0] = 0;1324 1325 cfg[0].pins[1] = sai->soc_data->pins;1326 cfg[0].mask[1] = soc_dl;1327 cfg[0].start_off[1] = 0;1328 cfg[0].next_off[1] = 0;1329 for (i = 1, index = 0; i < num_cfg + 1; i++) {1330 /*1331 * type of dataline1332 * 0 means default mode1333 * 1 means I2S mode1334 * 2 means PDM mode1335 */1336 ret = of_property_read_u32_index(np, propname, index++, &type);1337 if (ret)1338 return -EINVAL;1339 1340 ret = of_property_read_u32_index(np, propname, index++, &rx);1341 if (ret)1342 return -EINVAL;1343 1344 ret = of_property_read_u32_index(np, propname, index++, &tx);1345 if (ret)1346 return -EINVAL;1347 1348 if ((rx & ~soc_dl) || (tx & ~soc_dl)) {1349 dev_err(dev, "dataline cfg[%d] setting error, mask is 0x%x\n", i, soc_dl);1350 return -EINVAL;1351 }1352 1353 rx = rx & soc_dl;1354 tx = tx & soc_dl;1355 1356 cfg[i].type = type;1357 cfg[i].pins[0] = hweight8(rx);1358 cfg[i].mask[0] = rx;1359 dl_mask = rx;1360 cfg[i].start_off[0] = find_first_bit(&dl_mask, FSL_SAI_DL_NUM);1361 cfg[i].next_off[0] = fsl_sai_calc_dl_off(rx);1362 1363 cfg[i].pins[1] = hweight8(tx);1364 cfg[i].mask[1] = tx;1365 dl_mask = tx;1366 cfg[i].start_off[1] = find_first_bit(&dl_mask, FSL_SAI_DL_NUM);1367 cfg[i].next_off[1] = fsl_sai_calc_dl_off(tx);1368 }1369 1370 sai->dl_cfg = cfg;1371 sai->dl_cfg_cnt = num_cfg + 1;1372 return 0;1373}1374 1375static int fsl_sai_runtime_suspend(struct device *dev);1376static int fsl_sai_runtime_resume(struct device *dev);1377 1378static int fsl_sai_probe(struct platform_device *pdev)1379{1380 struct device_node *np = pdev->dev.of_node;1381 struct device *dev = &pdev->dev;1382 struct fsl_sai *sai;1383 struct regmap *gpr;1384 void __iomem *base;1385 char tmp[8];1386 int irq, ret, i;1387 int index;1388 u32 dmas[4];1389 1390 sai = devm_kzalloc(dev, sizeof(*sai), GFP_KERNEL);1391 if (!sai)1392 return -ENOMEM;1393 1394 sai->pdev = pdev;1395 sai->soc_data = of_device_get_match_data(dev);1396 1397 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");1398 1399 base = devm_platform_get_and_ioremap_resource(pdev, 0, &sai->res);1400 if (IS_ERR(base))1401 return PTR_ERR(base);1402 1403 if (sai->soc_data->reg_offset == 8) {1404 fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8;1405 fsl_sai_regmap_config.max_register = FSL_SAI_MDIV;1406 fsl_sai_regmap_config.num_reg_defaults =1407 ARRAY_SIZE(fsl_sai_reg_defaults_ofs8);1408 }1409 1410 sai->regmap = devm_regmap_init_mmio(dev, base, &fsl_sai_regmap_config);1411 if (IS_ERR(sai->regmap)) {1412 dev_err(dev, "regmap init failed\n");1413 return PTR_ERR(sai->regmap);1414 }1415 1416 sai->bus_clk = devm_clk_get(dev, "bus");1417 /* Compatible with old DTB cases */1418 if (IS_ERR(sai->bus_clk) && PTR_ERR(sai->bus_clk) != -EPROBE_DEFER)1419 sai->bus_clk = devm_clk_get(dev, "sai");1420 if (IS_ERR(sai->bus_clk)) {1421 dev_err(dev, "failed to get bus clock: %ld\n",1422 PTR_ERR(sai->bus_clk));1423 /* -EPROBE_DEFER */1424 return PTR_ERR(sai->bus_clk);1425 }1426 1427 for (i = 1; i < FSL_SAI_MCLK_MAX; i++) {1428 sprintf(tmp, "mclk%d", i);1429 sai->mclk_clk[i] = devm_clk_get(dev, tmp);1430 if (IS_ERR(sai->mclk_clk[i])) {1431 dev_err(dev, "failed to get mclk%d clock: %ld\n",1432 i, PTR_ERR(sai->mclk_clk[i]));1433 sai->mclk_clk[i] = NULL;1434 }1435 }1436 1437 if (sai->soc_data->mclk0_is_mclk1)1438 sai->mclk_clk[0] = sai->mclk_clk[1];1439 else1440 sai->mclk_clk[0] = sai->bus_clk;1441 1442 fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk,1443 &sai->pll11k_clk);1444 1445 /* Use Multi FIFO mode depending on the support from SDMA script */1446 ret = of_property_read_u32_array(np, "dmas", dmas, 4);1447 if (!sai->soc_data->use_edma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)1448 sai->is_multi_fifo_dma = true;1449 1450 /* read dataline mask for rx and tx*/1451 ret = fsl_sai_read_dlcfg(sai);1452 if (ret < 0) {1453 dev_err(dev, "failed to read dlcfg %d\n", ret);1454 return ret;1455 }1456 1457 irq = platform_get_irq(pdev, 0);1458 if (irq < 0)1459 return irq;1460 1461 ret = devm_request_irq(dev, irq, fsl_sai_isr, IRQF_SHARED,1462 np->name, sai);1463 if (ret) {1464 dev_err(dev, "failed to claim irq %u\n", irq);1465 return ret;1466 }1467 1468 memcpy(&sai->cpu_dai_drv, fsl_sai_dai_template,1469 sizeof(*fsl_sai_dai_template) * ARRAY_SIZE(fsl_sai_dai_template));1470 1471 /* Sync Tx with Rx as default by following old DT binding */1472 sai->synchronous[RX] = true;1473 sai->synchronous[TX] = false;1474 sai->cpu_dai_drv[0].symmetric_rate = 1;1475 sai->cpu_dai_drv[0].symmetric_channels = 1;1476 sai->cpu_dai_drv[0].symmetric_sample_bits = 1;1477 1478 if (of_property_read_bool(np, "fsl,sai-synchronous-rx") &&1479 of_property_read_bool(np, "fsl,sai-asynchronous")) {1480 /* error out if both synchronous and asynchronous are present */1481 dev_err(dev, "invalid binding for synchronous mode\n");1482 return -EINVAL;1483 }1484 1485 if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) {1486 /* Sync Rx with Tx */1487 sai->synchronous[RX] = false;1488 sai->synchronous[TX] = true;1489 } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) {1490 /* Discard all settings for asynchronous mode */1491 sai->synchronous[RX] = false;1492 sai->synchronous[TX] = false;1493 sai->cpu_dai_drv[0].symmetric_rate = 0;1494 sai->cpu_dai_drv[0].symmetric_channels = 0;1495 sai->cpu_dai_drv[0].symmetric_sample_bits = 0;1496 }1497 1498 sai->mclk_direction_output = of_property_read_bool(np, "fsl,sai-mclk-direction-output");1499 1500 if (sai->mclk_direction_output &&1501 of_device_is_compatible(np, "fsl,imx6ul-sai")) {1502 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");1503 if (IS_ERR(gpr)) {1504 dev_err(dev, "cannot find iomuxc registers\n");1505 return PTR_ERR(gpr);1506 }1507 1508 index = of_alias_get_id(np, "sai");1509 if (index < 0)1510 return index;1511 1512 regmap_update_bits(gpr, IOMUXC_GPR1, MCLK_DIR(index),1513 MCLK_DIR(index));1514 }1515 1516 sai->dma_params_rx.addr = sai->res->start + FSL_SAI_RDR0;1517 sai->dma_params_tx.addr = sai->res->start + FSL_SAI_TDR0;1518 sai->dma_params_rx.maxburst =1519 sai->soc_data->max_burst[RX] ? sai->soc_data->max_burst[RX] : FSL_SAI_MAXBURST_RX;1520 sai->dma_params_tx.maxburst =1521 sai->soc_data->max_burst[TX] ? sai->soc_data->max_burst[TX] : FSL_SAI_MAXBURST_TX;1522 1523 sai->pinctrl = devm_pinctrl_get(&pdev->dev);1524 1525 platform_set_drvdata(pdev, sai);1526 pm_runtime_enable(dev);1527 if (!pm_runtime_enabled(dev)) {1528 ret = fsl_sai_runtime_resume(dev);1529 if (ret)1530 goto err_pm_disable;1531 }1532 1533 ret = pm_runtime_resume_and_get(dev);1534 if (ret < 0)1535 goto err_pm_get_sync;1536 1537 /* Get sai version */1538 ret = fsl_sai_check_version(dev);1539 if (ret < 0)1540 dev_warn(dev, "Error reading SAI version: %d\n", ret);1541 1542 /* Select MCLK direction */1543 if (sai->mclk_direction_output &&1544 sai->soc_data->max_register >= FSL_SAI_MCTL) {1545 regmap_update_bits(sai->regmap, FSL_SAI_MCTL,1546 FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);1547 }1548 1549 ret = pm_runtime_put_sync(dev);1550 if (ret < 0 && ret != -ENOSYS)1551 goto err_pm_get_sync;1552 1553 /*1554 * Register platform component before registering cpu dai for there1555 * is not defer probe for platform component in snd_soc_add_pcm_runtime().1556 */1557 if (sai->soc_data->use_imx_pcm) {1558 ret = imx_pcm_dma_init(pdev);1559 if (ret) {1560 dev_err_probe(dev, ret, "PCM DMA init failed\n");1561 if (!IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA))1562 dev_err(dev, "Error: You must enable the imx-pcm-dma support!\n");1563 goto err_pm_get_sync;1564 }1565 } else {1566 ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);1567 if (ret) {1568 dev_err_probe(dev, ret, "Registering PCM dmaengine failed\n");1569 goto err_pm_get_sync;1570 }1571 }1572 1573 ret = devm_snd_soc_register_component(dev, &fsl_component,1574 sai->cpu_dai_drv, ARRAY_SIZE(fsl_sai_dai_template));1575 if (ret)1576 goto err_pm_get_sync;1577 1578 return ret;1579 1580err_pm_get_sync:1581 if (!pm_runtime_status_suspended(dev))1582 fsl_sai_runtime_suspend(dev);1583err_pm_disable:1584 pm_runtime_disable(dev);1585 1586 return ret;1587}1588 1589static void fsl_sai_remove(struct platform_device *pdev)1590{1591 pm_runtime_disable(&pdev->dev);1592 if (!pm_runtime_status_suspended(&pdev->dev))1593 fsl_sai_runtime_suspend(&pdev->dev);1594}1595 1596static const struct fsl_sai_soc_data fsl_sai_vf610_data = {1597 .use_imx_pcm = false,1598 .use_edma = false,1599 .fifo_depth = 32,1600 .pins = 1,1601 .reg_offset = 0,1602 .mclk0_is_mclk1 = false,1603 .flags = 0,1604 .max_register = FSL_SAI_RMR,1605};1606 1607static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = {1608 .use_imx_pcm = true,1609 .use_edma = false,1610 .fifo_depth = 32,1611 .pins = 1,1612 .reg_offset = 0,1613 .mclk0_is_mclk1 = true,1614 .flags = 0,1615 .max_register = FSL_SAI_RMR,1616};1617 1618static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = {1619 .use_imx_pcm = true,1620 .use_edma = false,1621 .fifo_depth = 16,1622 .pins = 2,1623 .reg_offset = 8,1624 .mclk0_is_mclk1 = false,1625 .flags = PMQOS_CPU_LATENCY,1626 .max_register = FSL_SAI_RMR,1627};1628 1629static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = {1630 .use_imx_pcm = true,1631 .use_edma = false,1632 .fifo_depth = 128,1633 .pins = 8,1634 .reg_offset = 8,1635 .mclk0_is_mclk1 = false,1636 .flags = 0,1637 .max_register = FSL_SAI_RMR,1638};1639 1640static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = {1641 .use_imx_pcm = true,1642 .use_edma = true,1643 .fifo_depth = 64,1644 .pins = 4,1645 .reg_offset = 0,1646 .mclk0_is_mclk1 = false,1647 .flags = 0,1648 .max_register = FSL_SAI_RMR,1649};1650 1651static const struct fsl_sai_soc_data fsl_sai_imx8mm_data = {1652 .use_imx_pcm = true,1653 .use_edma = false,1654 .fifo_depth = 128,1655 .reg_offset = 8,1656 .mclk0_is_mclk1 = false,1657 .pins = 8,1658 .flags = 0,1659 .max_register = FSL_SAI_MCTL,1660};1661 1662static const struct fsl_sai_soc_data fsl_sai_imx8mn_data = {1663 .use_imx_pcm = true,1664 .use_edma = false,1665 .fifo_depth = 128,1666 .reg_offset = 8,1667 .mclk0_is_mclk1 = false,1668 .pins = 8,1669 .flags = 0,1670 .max_register = FSL_SAI_MDIV,1671};1672 1673static const struct fsl_sai_soc_data fsl_sai_imx8mp_data = {1674 .use_imx_pcm = true,1675 .use_edma = false,1676 .fifo_depth = 128,1677 .reg_offset = 8,1678 .mclk0_is_mclk1 = false,1679 .pins = 8,1680 .flags = 0,1681 .max_register = FSL_SAI_MDIV,1682 .mclk_with_tere = true,1683};1684 1685static const struct fsl_sai_soc_data fsl_sai_imx8ulp_data = {1686 .use_imx_pcm = true,1687 .use_edma = true,1688 .fifo_depth = 16,1689 .reg_offset = 8,1690 .mclk0_is_mclk1 = false,1691 .pins = 4,1692 .flags = PMQOS_CPU_LATENCY,1693 .max_register = FSL_SAI_RTCAP,1694};1695 1696static const struct fsl_sai_soc_data fsl_sai_imx93_data = {1697 .use_imx_pcm = true,1698 .use_edma = true,1699 .fifo_depth = 128,1700 .reg_offset = 8,1701 .mclk0_is_mclk1 = false,1702 .pins = 4,1703 .flags = 0,1704 .max_register = FSL_SAI_MCTL,1705 .max_burst = {8, 8},1706};1707 1708static const struct fsl_sai_soc_data fsl_sai_imx95_data = {1709 .use_imx_pcm = true,1710 .use_edma = true,1711 .fifo_depth = 128,1712 .reg_offset = 8,1713 .mclk0_is_mclk1 = false,1714 .pins = 8,1715 .flags = 0,1716 .max_register = FSL_SAI_MCTL,1717 .max_burst = {8, 8},1718};1719 1720static const struct of_device_id fsl_sai_ids[] = {1721 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },1722 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },1723 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },1724 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },1725 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },1726 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },1727 { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data },1728 { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data },1729 { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data },1730 { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mn_data },1731 { .compatible = "fsl,imx93-sai", .data = &fsl_sai_imx93_data },1732 { .compatible = "fsl,imx95-sai", .data = &fsl_sai_imx95_data },1733 { /* sentinel */ }1734};1735MODULE_DEVICE_TABLE(of, fsl_sai_ids);1736 1737static int fsl_sai_runtime_suspend(struct device *dev)1738{1739 struct fsl_sai *sai = dev_get_drvdata(dev);1740 1741 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))1742 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);1743 1744 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))1745 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);1746 1747 clk_disable_unprepare(sai->bus_clk);1748 1749 if (sai->soc_data->flags & PMQOS_CPU_LATENCY)1750 cpu_latency_qos_remove_request(&sai->pm_qos_req);1751 1752 regcache_cache_only(sai->regmap, true);1753 1754 return 0;1755}1756 1757static int fsl_sai_runtime_resume(struct device *dev)1758{1759 struct fsl_sai *sai = dev_get_drvdata(dev);1760 unsigned int ofs = sai->soc_data->reg_offset;1761 int ret;1762 1763 ret = clk_prepare_enable(sai->bus_clk);1764 if (ret) {1765 dev_err(dev, "failed to enable bus clock: %d\n", ret);1766 return ret;1767 }1768 1769 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {1770 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);1771 if (ret)1772 goto disable_bus_clk;1773 }1774 1775 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {1776 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);1777 if (ret)1778 goto disable_tx_clk;1779 }1780 1781 if (sai->soc_data->flags & PMQOS_CPU_LATENCY)1782 cpu_latency_qos_add_request(&sai->pm_qos_req, 0);1783 1784 regcache_cache_only(sai->regmap, false);1785 regcache_mark_dirty(sai->regmap);1786 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);1787 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);1788 usleep_range(1000, 2000);1789 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);1790 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);1791 1792 ret = regcache_sync(sai->regmap);1793 if (ret)1794 goto disable_rx_clk;1795 1796 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)1797 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),1798 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);1799 1800 return 0;1801 1802disable_rx_clk:1803 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))1804 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);1805disable_tx_clk:1806 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))1807 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);1808disable_bus_clk:1809 clk_disable_unprepare(sai->bus_clk);1810 1811 return ret;1812}1813 1814static const struct dev_pm_ops fsl_sai_pm_ops = {1815 SET_RUNTIME_PM_OPS(fsl_sai_runtime_suspend,1816 fsl_sai_runtime_resume, NULL)1817 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,1818 pm_runtime_force_resume)1819};1820 1821static struct platform_driver fsl_sai_driver = {1822 .probe = fsl_sai_probe,1823 .remove = fsl_sai_remove,1824 .driver = {1825 .name = "fsl-sai",1826 .pm = &fsl_sai_pm_ops,1827 .of_match_table = fsl_sai_ids,1828 },1829};1830module_platform_driver(fsl_sai_driver);1831 1832MODULE_DESCRIPTION("Freescale Soc SAI Interface");1833MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>");1834MODULE_ALIAS("platform:fsl-sai");1835MODULE_LICENSE("GPL");1836