brintos

brintos / linux-shallow public Read only

0
0
Text · 48.5 KiB · 634168d Raw
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