fsl_sai.c 34.0 KB
Newer Older
1 2 3 4 5
// SPDX-License-Identifier: GPL-2.0+
//
// Freescale ALSA SoC Digital Audio Interface (SAI) driver.
//
// Copyright 2012-2015 Freescale Semiconductor, Inc.
6 7 8 9 10 11

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/module.h>
#include <linux/of_address.h>
L
Lucas Stach 已提交
12
#include <linux/of_device.h>
13
#include <linux/pm_runtime.h>
14
#include <linux/regmap.h>
15
#include <linux/slab.h>
16
#include <linux/time.h>
17 18 19
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
20 21
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
22 23

#include "fsl_sai.h"
24
#include "imx-pcm.h"
25

26 27 28
#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
		       FSL_SAI_CSR_FEIE)

29
static const unsigned int fsl_sai_rates[] = {
30 31 32 33 34
	8000, 11025, 12000, 16000, 22050,
	24000, 32000, 44100, 48000, 64000,
	88200, 96000, 176400, 192000
};

35
static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
36 37 38 39
	.count = ARRAY_SIZE(fsl_sai_rates),
	.list = fsl_sai_rates,
};

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/**
 * fsl_sai_dir_is_synced - Check if stream is synced by the opposite stream
 *
 * SAI supports synchronous mode using bit/frame clocks of either Transmitter's
 * or Receiver's for both streams. This function is used to check if clocks of
 * the stream's are synced by the opposite stream.
 *
 * @sai: SAI context
 * @dir: stream direction
 */
static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir)
{
	int adir = (dir == TX) ? RX : TX;

	/* current dir in async mode while opposite dir in sync mode */
	return !sai->synchronous[dir] && sai->synchronous[adir];
}

58 59 60
static irqreturn_t fsl_sai_isr(int irq, void *devid)
{
	struct fsl_sai *sai = (struct fsl_sai *)devid;
61
	unsigned int ofs = sai->soc_data->reg_offset;
62
	struct device *dev = &sai->pdev->dev;
63 64 65 66 67 68 69 70
	u32 flags, xcsr, mask;
	bool irq_none = true;

	/*
	 * Both IRQ status bits and IRQ mask bits are in the xCSR but
	 * different shifts. And we here create a mask only for those
	 * IRQs that we activated.
	 */
71 72 73
	mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;

	/* Tx IRQ */
74
	regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr);
75 76 77 78 79 80
	flags = xcsr & mask;

	if (flags)
		irq_none = false;
	else
		goto irq_rx;
81

82
	if (flags & FSL_SAI_CSR_WSF)
83 84
		dev_dbg(dev, "isr: Start of Tx word detected\n");

85
	if (flags & FSL_SAI_CSR_SEF)
86
		dev_dbg(dev, "isr: Tx Frame sync error detected\n");
87

88
	if (flags & FSL_SAI_CSR_FEF) {
89
		dev_dbg(dev, "isr: Transmit underrun detected\n");
90 91 92 93
		/* FIFO reset for safety */
		xcsr |= FSL_SAI_CSR_FR;
	}

94
	if (flags & FSL_SAI_CSR_FWF)
95 96
		dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");

97
	if (flags & FSL_SAI_CSR_FRF)
98 99
		dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");

100 101 102 103
	flags &= FSL_SAI_CSR_xF_W_MASK;
	xcsr &= ~FSL_SAI_CSR_xF_MASK;

	if (flags)
104
		regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr);
105

106
irq_rx:
107
	/* Rx IRQ */
108
	regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr);
109
	flags = xcsr & mask;
110

111 112 113 114 115 116
	if (flags)
		irq_none = false;
	else
		goto out;

	if (flags & FSL_SAI_CSR_WSF)
117 118
		dev_dbg(dev, "isr: Start of Rx word detected\n");

119
	if (flags & FSL_SAI_CSR_SEF)
120
		dev_dbg(dev, "isr: Rx Frame sync error detected\n");
121

122
	if (flags & FSL_SAI_CSR_FEF) {
123
		dev_dbg(dev, "isr: Receive overflow detected\n");
124 125 126 127
		/* FIFO reset for safety */
		xcsr |= FSL_SAI_CSR_FR;
	}

128
	if (flags & FSL_SAI_CSR_FWF)
129 130
		dev_dbg(dev, "isr: Enabled receive FIFO is full\n");

131
	if (flags & FSL_SAI_CSR_FRF)
132 133
		dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");

134 135
	flags &= FSL_SAI_CSR_xF_W_MASK;
	xcsr &= ~FSL_SAI_CSR_xF_MASK;
136

137
	if (flags)
138
		regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr);
139 140 141 142 143 144

out:
	if (irq_none)
		return IRQ_NONE;
	else
		return IRQ_HANDLED;
145 146
}

147 148 149 150 151 152 153 154 155 156 157
static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
				u32 rx_mask, int slots, int slot_width)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);

	sai->slots = slots;
	sai->slot_width = slot_width;

	return 0;
}

158 159 160 161 162 163 164 165 166 167
static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai,
				      unsigned int ratio)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);

	sai->bclk_ratio = ratio;

	return 0;
}

168 169 170 171
static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
		int clk_id, unsigned int freq, int fsl_dir)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
172
	unsigned int ofs = sai->soc_data->reg_offset;
173 174
	bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
	u32 val_cr2 = 0;
X
Xiubo Li 已提交
175

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
	switch (clk_id) {
	case FSL_SAI_CLK_BUS:
		val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
		break;
	case FSL_SAI_CLK_MAST1:
		val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
		break;
	case FSL_SAI_CLK_MAST2:
		val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
		break;
	case FSL_SAI_CLK_MAST3:
		val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
		break;
	default:
		return -EINVAL;
	}
X
Xiubo Li 已提交
192

193
	regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
194
			   FSL_SAI_CR2_MSEL_MASK, val_cr2);
195 196 197 198 199 200 201

	return 0;
}

static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
		int clk_id, unsigned int freq, int dir)
{
202
	int ret;
203 204 205 206 207 208 209

	if (dir == SND_SOC_CLOCK_IN)
		return 0;

	ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
					FSL_FMT_TRANSMITTER);
	if (ret) {
210
		dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
211
		return ret;
212 213 214 215
	}

	ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
					FSL_FMT_RECEIVER);
216
	if (ret)
217
		dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);
218

219
	return ret;
220 221 222 223 224 225
}

static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
				unsigned int fmt, int fsl_dir)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
226
	unsigned int ofs = sai->soc_data->reg_offset;
227 228
	bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
	u32 val_cr2 = 0, val_cr4 = 0;
229

230
	if (!sai->is_lsb_first)
231
		val_cr4 |= FSL_SAI_CR4_MF;
232

233
	/* DAI mode */
234 235
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
236 237 238 239 240 241
		/*
		 * Frame low, 1clk before data, one word length for frame sync,
		 * frame sync starts one serial clock cycle earlier,
		 * that is, together with the last bit of the previous
		 * data word.
		 */
242
		val_cr2 |= FSL_SAI_CR2_BCP;
243 244 245
		val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
246 247 248 249
		/*
		 * Frame high, one word length for frame sync,
		 * frame sync asserts with the first bit of the frame.
		 */
250
		val_cr2 |= FSL_SAI_CR2_BCP;
251
		break;
252 253 254 255 256 257 258
	case SND_SOC_DAIFMT_DSP_A:
		/*
		 * Frame high, 1clk before data, one bit for frame sync,
		 * frame sync starts one serial clock cycle earlier,
		 * that is, together with the last bit of the previous
		 * data word.
		 */
259
		val_cr2 |= FSL_SAI_CR2_BCP;
260 261 262 263 264 265 266 267
		val_cr4 |= FSL_SAI_CR4_FSE;
		sai->is_dsp_mode = true;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		/*
		 * Frame high, one bit for frame sync,
		 * frame sync asserts with the first bit of the frame.
		 */
268
		val_cr2 |= FSL_SAI_CR2_BCP;
269 270
		sai->is_dsp_mode = true;
		break;
271 272
	case SND_SOC_DAIFMT_RIGHT_J:
		/* To be done */
273 274 275 276
	default:
		return -EINVAL;
	}

277
	/* DAI clock inversion */
278 279
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_IB_IF:
280 281 282
		/* Invert both clocks */
		val_cr2 ^= FSL_SAI_CR2_BCP;
		val_cr4 ^= FSL_SAI_CR4_FSP;
283 284
		break;
	case SND_SOC_DAIFMT_IB_NF:
285 286
		/* Invert bit clock */
		val_cr2 ^= FSL_SAI_CR2_BCP;
287 288
		break;
	case SND_SOC_DAIFMT_NB_IF:
289 290
		/* Invert frame clock */
		val_cr4 ^= FSL_SAI_CR4_FSP;
291 292
		break;
	case SND_SOC_DAIFMT_NB_NF:
293
		/* Nothing to do for both normal cases */
294 295 296 297 298
		break;
	default:
		return -EINVAL;
	}

299
	/* DAI clock master masks */
300 301 302 303
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
304
		sai->is_slave_mode = false;
305 306
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
307
		sai->is_slave_mode = true;
308
		break;
309 310
	case SND_SOC_DAIFMT_CBS_CFM:
		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
311
		sai->is_slave_mode = false;
312 313 314
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
315
		sai->is_slave_mode = true;
316
		break;
317 318 319 320
	default:
		return -EINVAL;
	}

321
	regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
322
			   FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
323
	regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
324 325
			   FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
			   FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
326 327 328 329 330 331

	return 0;
}

static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
332
	int ret;
333 334 335

	ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
	if (ret) {
336
		dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
337
		return ret;
338 339 340
	}

	ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
341
	if (ret)
342
		dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
343

344
	return ret;
345 346
}

347 348 349
static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
350
	unsigned int ofs = sai->soc_data->reg_offset;
351 352
	unsigned long clk_rate;
	u32 savediv = 0, ratio, savesub = freq;
353 354
	int adir = tx ? RX : TX;
	int dir = tx ? TX : RX;
355 356 357 358 359 360 361
	u32 id;
	int ret = 0;

	/* Don't apply to slave mode */
	if (sai->is_slave_mode)
		return 0;

362 363 364 365 366 367 368 369
	/*
	 * There is no point in polling MCLK0 if it is identical to MCLK1.
	 * And given that MQS use case has to use MCLK1 though two clocks
	 * are the same, we simply skip MCLK0 and start to find from MCLK1.
	 */
	id = sai->soc_data->mclk0_is_mclk1 ? 1 : 0;

	for (; id < FSL_SAI_MCLK_MAX; id++) {
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
		clk_rate = clk_get_rate(sai->mclk_clk[id]);
		if (!clk_rate)
			continue;

		ratio = clk_rate / freq;

		ret = clk_rate - ratio * freq;

		/*
		 * Drop the source that can not be
		 * divided into the required rate.
		 */
		if (ret != 0 && clk_rate / ret < 1000)
			continue;

		dev_dbg(dai->dev,
			"ratio %d for freq %dHz based on clock %ldHz\n",
			ratio, freq, clk_rate);

		if (ratio % 2 == 0 && ratio >= 2 && ratio <= 512)
			ratio /= 2;
		else
			continue;

		if (ret < savesub) {
			savediv = ratio;
			sai->mclk_id[tx] = id;
			savesub = ret;
		}

		if (ret == 0)
			break;
	}

	if (savediv == 0) {
		dev_err(dai->dev, "failed to derive required %cx rate: %d\n",
				tx ? 'T' : 'R', freq);
		return -EINVAL;
	}

410 411 412 413 414 415 416 417 418 419
	/*
	 * 1) For Asynchronous mode, we must set RCR2 register for capture, and
	 *    set TCR2 register for playback.
	 * 2) For Tx sync with Rx clock, we must set RCR2 register for playback
	 *    and capture.
	 * 3) For Rx sync with Tx clock, we must set TCR2 register for playback
	 *    and capture.
	 * 4) For Tx and Rx are both Synchronous with another SAI, we just
	 *    ignore it.
	 */
420 421
	if (fsl_sai_dir_is_synced(sai, adir)) {
		regmap_update_bits(sai->regmap, FSL_SAI_xCR2(!tx, ofs),
422 423
				   FSL_SAI_CR2_MSEL_MASK,
				   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
424
		regmap_update_bits(sai->regmap, FSL_SAI_xCR2(!tx, ofs),
425
				   FSL_SAI_CR2_DIV_MASK, savediv - 1);
426 427
	} else if (!sai->synchronous[dir]) {
		regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
428 429
				   FSL_SAI_CR2_MSEL_MASK,
				   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
430
		regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
431 432 433 434 435 436 437 438 439
				   FSL_SAI_CR2_DIV_MASK, savediv - 1);
	}

	dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n",
			sai->mclk_id[tx], savediv, savesub);

	return 0;
}

440 441 442 443
static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params,
		struct snd_soc_dai *cpu_dai)
{
444
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
445
	unsigned int ofs = sai->soc_data->reg_offset;
446
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
447
	unsigned int channels = params_channels(params);
448
	u32 word_width = params_width(params);
449
	u32 val_cr4 = 0, val_cr5 = 0;
450 451
	u32 slots = (channels == 1) ? 2 : channels;
	u32 slot_width = word_width;
452
	int adir = tx ? RX : TX;
453
	u32 pins;
454 455
	int ret;

456 457 458 459 460 461
	if (sai->slots)
		slots = sai->slots;

	if (sai->slot_width)
		slot_width = sai->slot_width;

462 463
	pins = DIV_ROUND_UP(channels, slots);

464
	if (!sai->is_slave_mode) {
465 466 467 468 469 470 471 472
		if (sai->bclk_ratio)
			ret = fsl_sai_set_bclk(cpu_dai, tx,
					       sai->bclk_ratio *
					       params_rate(params));
		else
			ret = fsl_sai_set_bclk(cpu_dai, tx,
					       slots * slot_width *
					       params_rate(params));
473 474 475 476 477 478 479 480 481 482 483 484
		if (ret)
			return ret;

		/* Do not enable the clock if it is already enabled */
		if (!(sai->mclk_streams & BIT(substream->stream))) {
			ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);
			if (ret)
				return ret;

			sai->mclk_streams |= BIT(substream->stream);
		}
	}
485

486
	if (!sai->is_dsp_mode)
487
		val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);
488

489 490
	val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
	val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
491

492
	if (sai->is_lsb_first)
493
		val_cr5 |= FSL_SAI_CR5_FBT(0);
494 495
	else
		val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
496

497
	val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
498

499 500 501 502
	/* Set to output mode to avoid tri-stated data pins */
	if (tx)
		val_cr4 |= FSL_SAI_CR4_CHMOD;

503 504 505
	/*
	 * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will
	 * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4),
506
	 * RCR5(TCR5) for playback(capture), or there will be sync error.
507 508
	 */

509 510
	if (!sai->is_slave_mode && fsl_sai_dir_is_synced(sai, adir)) {
		regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs),
511 512
				   FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
				   FSL_SAI_CR4_CHMOD_MASK,
513 514 515 516
				   val_cr4);
		regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs),
				   FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
				   FSL_SAI_CR5_FBT_MASK, val_cr5);
517
	}
518

519 520 521
	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
			   FSL_SAI_CR3_TRCE_MASK,
			   FSL_SAI_CR3_TRCE((1 << pins) - 1));
522
	regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
523 524
			   FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
			   FSL_SAI_CR4_CHMOD_MASK,
525
			   val_cr4);
526
	regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
527 528
			   FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
			   FSL_SAI_CR5_FBT_MASK, val_cr5);
529 530
	regmap_write(sai->regmap, FSL_SAI_xMR(tx),
		     ~0UL - ((1 << min(channels, slots)) - 1));
531 532 533 534

	return 0;
}

535 536 537 538 539
static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
		struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
540 541 542 543
	unsigned int ofs = sai->soc_data->reg_offset;

	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
			   FSL_SAI_CR3_TRCE_MASK, 0);
544 545 546 547 548 549 550 551 552 553

	if (!sai->is_slave_mode &&
			sai->mclk_streams & BIT(substream->stream)) {
		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
		sai->mclk_streams &= ~BIT(substream->stream);
	}

	return 0;
}

554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)
{
	unsigned int ofs = sai->soc_data->reg_offset;
	bool tx = dir == TX;
	u32 xcsr, count = 100;

	regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
			   FSL_SAI_CSR_TERE, 0);

	/* TERE will remain set till the end of current frame */
	do {
		udelay(10);
		regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr);
	} while (--count && xcsr & FSL_SAI_CSR_TERE);

	regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
			   FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);

	/*
	 * For sai master mode, after several open/close sai,
	 * there will be no frame clock, and can't recover
	 * anymore. Add software reset to fix this issue.
	 * This is a hardware bug, and will be fix in the
	 * next sai version.
	 */
	if (!sai->is_slave_mode) {
		/* Software Reset */
		regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR);
		/* Clear SR bit to finish the reset */
		regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0);
	}
}
586

587 588 589 590
static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
		struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
591 592
	unsigned int ofs = sai->soc_data->reg_offset;

593
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
594 595 596
	int adir = tx ? RX : TX;
	int dir = tx ? TX : RX;
	u32 xcsr;
597

598
	/*
599 600 601
	 * Asynchronous mode: Clear SYNC for both Tx and Rx.
	 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
	 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
602
	 */
603 604 605
	regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC,
			   sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
	regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC,
606
			   sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
607

608 609 610 611
	/*
	 * It is recommended that the transmitter is the last enabled
	 * and the first disabled.
	 */
612 613 614 615
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
616
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
617 618
				   FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);

619
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
620
				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
621 622 623 624 625 626 627 628 629 630 631 632 633 634
		/*
		 * Enable the opposite direction for synchronous mode
		 * 1. Tx sync with Rx: only set RE for Rx; set TE & RE for Tx
		 * 2. Rx sync with Tx: only set TE for Tx; set RE & TE for Rx
		 *
		 * RM recommends to enable RE after TE for case 1 and to enable
		 * TE after RE for case 2, but we here may not always guarantee
		 * that happens: "arecord 1.wav; aplay 2.wav" in case 1 enables
		 * TE after RE, which is against what RM recommends but should
		 * be safe to do, judging by years of testing results.
		 */
		if (fsl_sai_dir_is_synced(sai, adir))
			regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs),
					   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
635

636
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
637
				   FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
638 639 640 641
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
642
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
643
				   FSL_SAI_CSR_FRDE, 0);
644
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
645
				   FSL_SAI_CSR_xIE_MASK, 0);
646

647
		/* Check if the opposite FRDE is also disabled */
648
		regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr);
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665

		/*
		 * If opposite stream provides clocks for synchronous mode and
		 * it is inactive, disable it before disabling the current one
		 */
		if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE))
			fsl_sai_config_disable(sai, adir);

		/*
		 * Disable current stream if either of:
		 * 1. current stream doesn't provide clocks for synchronous mode
		 * 2. current stream provides clocks for synchronous mode but no
		 *    more stream is active.
		 */
		if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE))
			fsl_sai_config_disable(sai, dir);

666 667 668 669 670 671 672 673 674 675 676 677
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int fsl_sai_startup(struct snd_pcm_substream *substream,
		struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
678
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
679 680
	int ret;

681 682 683 684 685 686 687 688 689 690
	/*
	 * EDMA controller needs period size to be a multiple of
	 * tx/rx maxburst
	 */
	if (sai->soc_data->use_edma)
		snd_pcm_hw_constraint_step(substream->runtime, 0,
					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
					   tx ? sai->dma_params_tx.maxburst :
					   sai->dma_params_rx.maxburst);

691 692 693 694
	ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
			SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);

	return ret;
695 696 697
}

static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
698
	.set_bclk_ratio	= fsl_sai_set_dai_bclk_ratio,
699 700
	.set_sysclk	= fsl_sai_set_dai_sysclk,
	.set_fmt	= fsl_sai_set_dai_fmt,
701
	.set_tdm_slot	= fsl_sai_set_dai_tdm_slot,
702
	.hw_params	= fsl_sai_hw_params,
703
	.hw_free	= fsl_sai_hw_free,
704 705 706 707 708 709 710
	.trigger	= fsl_sai_trigger,
	.startup	= fsl_sai_startup,
};

static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
711
	unsigned int ofs = sai->soc_data->reg_offset;
712

713
	/* Software Reset for both Tx and Rx */
714 715
	regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
	regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
716
	/* Clear SR bit to finish the reset */
717 718
	regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
	regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
719

720
	regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs),
721
			   FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
722
			   sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX);
723
	regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs),
724 725
			   FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
			   FSL_SAI_MAXBURST_RX - 1);
726

727 728
	snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
				&sai->dma_params_rx);
729 730 731 732 733 734

	snd_soc_dai_set_drvdata(cpu_dai, sai);

	return 0;
}

735
static struct snd_soc_dai_driver fsl_sai_dai_template = {
736 737
	.probe = fsl_sai_dai_probe,
	.playback = {
738
		.stream_name = "CPU-Playback",
739
		.channels_min = 1,
740
		.channels_max = 32,
741 742 743
		.rate_min = 8000,
		.rate_max = 192000,
		.rates = SNDRV_PCM_RATE_KNOT,
744 745 746
		.formats = FSL_SAI_FORMATS,
	},
	.capture = {
747
		.stream_name = "CPU-Capture",
748
		.channels_min = 1,
749
		.channels_max = 32,
750 751 752
		.rate_min = 8000,
		.rate_max = 192000,
		.rates = SNDRV_PCM_RATE_KNOT,
753 754 755 756 757 758 759 760 761
		.formats = FSL_SAI_FORMATS,
	},
	.ops = &fsl_sai_pcm_dai_ops,
};

static const struct snd_soc_component_driver fsl_component = {
	.name           = "fsl-sai",
};

762 763 764 765 766 767
static struct reg_default fsl_sai_reg_defaults_ofs0[] = {
	{FSL_SAI_TCR1(0), 0},
	{FSL_SAI_TCR2(0), 0},
	{FSL_SAI_TCR3(0), 0},
	{FSL_SAI_TCR4(0), 0},
	{FSL_SAI_TCR5(0), 0},
768 769 770 771 772 773 774 775
	{FSL_SAI_TDR0, 0},
	{FSL_SAI_TDR1, 0},
	{FSL_SAI_TDR2, 0},
	{FSL_SAI_TDR3, 0},
	{FSL_SAI_TDR4, 0},
	{FSL_SAI_TDR5, 0},
	{FSL_SAI_TDR6, 0},
	{FSL_SAI_TDR7, 0},
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
	{FSL_SAI_TMR, 0},
	{FSL_SAI_RCR1(0), 0},
	{FSL_SAI_RCR2(0), 0},
	{FSL_SAI_RCR3(0), 0},
	{FSL_SAI_RCR4(0), 0},
	{FSL_SAI_RCR5(0), 0},
	{FSL_SAI_RMR, 0},
};

static struct reg_default fsl_sai_reg_defaults_ofs8[] = {
	{FSL_SAI_TCR1(8), 0},
	{FSL_SAI_TCR2(8), 0},
	{FSL_SAI_TCR3(8), 0},
	{FSL_SAI_TCR4(8), 0},
	{FSL_SAI_TCR5(8), 0},
	{FSL_SAI_TDR0, 0},
	{FSL_SAI_TDR1, 0},
	{FSL_SAI_TDR2, 0},
	{FSL_SAI_TDR3, 0},
	{FSL_SAI_TDR4, 0},
	{FSL_SAI_TDR5, 0},
	{FSL_SAI_TDR6, 0},
	{FSL_SAI_TDR7, 0},
	{FSL_SAI_TMR, 0},
	{FSL_SAI_RCR1(8), 0},
	{FSL_SAI_RCR2(8), 0},
	{FSL_SAI_RCR3(8), 0},
	{FSL_SAI_RCR4(8), 0},
	{FSL_SAI_RCR5(8), 0},
	{FSL_SAI_RMR, 0},
806 807
	{FSL_SAI_MCTL, 0},
	{FSL_SAI_MDIV, 0},
808 809
};

810 811
static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
{
812 813 814 815 816 817 818 819 820
	struct fsl_sai *sai = dev_get_drvdata(dev);
	unsigned int ofs = sai->soc_data->reg_offset;

	if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs))
		return true;

	if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs))
		return true;

821
	switch (reg) {
822 823 824 825 826 827 828 829
	case FSL_SAI_TFR0:
	case FSL_SAI_TFR1:
	case FSL_SAI_TFR2:
	case FSL_SAI_TFR3:
	case FSL_SAI_TFR4:
	case FSL_SAI_TFR5:
	case FSL_SAI_TFR6:
	case FSL_SAI_TFR7:
830
	case FSL_SAI_TMR:
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
	case FSL_SAI_RDR0:
	case FSL_SAI_RDR1:
	case FSL_SAI_RDR2:
	case FSL_SAI_RDR3:
	case FSL_SAI_RDR4:
	case FSL_SAI_RDR5:
	case FSL_SAI_RDR6:
	case FSL_SAI_RDR7:
	case FSL_SAI_RFR0:
	case FSL_SAI_RFR1:
	case FSL_SAI_RFR2:
	case FSL_SAI_RFR3:
	case FSL_SAI_RFR4:
	case FSL_SAI_RFR5:
	case FSL_SAI_RFR6:
	case FSL_SAI_RFR7:
847
	case FSL_SAI_RMR:
848 849 850 851 852 853 854 855 856 857 858 859
	case FSL_SAI_MCTL:
	case FSL_SAI_MDIV:
	case FSL_SAI_VERID:
	case FSL_SAI_PARAM:
	case FSL_SAI_TTCTN:
	case FSL_SAI_RTCTN:
	case FSL_SAI_TTCTL:
	case FSL_SAI_TBCTN:
	case FSL_SAI_TTCAP:
	case FSL_SAI_RTCTL:
	case FSL_SAI_RBCTN:
	case FSL_SAI_RTCAP:
860 861 862 863 864 865 866 867
		return true;
	default:
		return false;
	}
}

static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
{
868 869 870 871 872 873
	struct fsl_sai *sai = dev_get_drvdata(dev);
	unsigned int ofs = sai->soc_data->reg_offset;

	if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs))
		return true;

874 875 876 877
	/* Set VERID and PARAM be volatile for reading value in probe */
	if (ofs == 8 && (reg == FSL_SAI_VERID || reg == FSL_SAI_PARAM))
		return true;

878
	switch (reg) {
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
	case FSL_SAI_TFR0:
	case FSL_SAI_TFR1:
	case FSL_SAI_TFR2:
	case FSL_SAI_TFR3:
	case FSL_SAI_TFR4:
	case FSL_SAI_TFR5:
	case FSL_SAI_TFR6:
	case FSL_SAI_TFR7:
	case FSL_SAI_RFR0:
	case FSL_SAI_RFR1:
	case FSL_SAI_RFR2:
	case FSL_SAI_RFR3:
	case FSL_SAI_RFR4:
	case FSL_SAI_RFR5:
	case FSL_SAI_RFR6:
	case FSL_SAI_RFR7:
	case FSL_SAI_RDR0:
	case FSL_SAI_RDR1:
	case FSL_SAI_RDR2:
	case FSL_SAI_RDR3:
	case FSL_SAI_RDR4:
	case FSL_SAI_RDR5:
	case FSL_SAI_RDR6:
	case FSL_SAI_RDR7:
903 904 905 906 907 908 909 910
		return true;
	default:
		return false;
	}
}

static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
{
911 912 913 914 915 916 917 918 919
	struct fsl_sai *sai = dev_get_drvdata(dev);
	unsigned int ofs = sai->soc_data->reg_offset;

	if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs))
		return true;

	if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs))
		return true;

920
	switch (reg) {
921 922 923 924 925 926 927 928
	case FSL_SAI_TDR0:
	case FSL_SAI_TDR1:
	case FSL_SAI_TDR2:
	case FSL_SAI_TDR3:
	case FSL_SAI_TDR4:
	case FSL_SAI_TDR5:
	case FSL_SAI_TDR6:
	case FSL_SAI_TDR7:
929 930
	case FSL_SAI_TMR:
	case FSL_SAI_RMR:
931 932 933 934
	case FSL_SAI_MCTL:
	case FSL_SAI_MDIV:
	case FSL_SAI_TTCTL:
	case FSL_SAI_RTCTL:
935 936 937 938 939 940
		return true;
	default:
		return false;
	}
}

941
static struct regmap_config fsl_sai_regmap_config = {
942 943 944
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
945
	.fast_io = true,
946 947

	.max_register = FSL_SAI_RMR,
948 949
	.reg_defaults = fsl_sai_reg_defaults_ofs0,
	.num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0),
950 951 952
	.readable_reg = fsl_sai_readable_reg,
	.volatile_reg = fsl_sai_volatile_reg,
	.writeable_reg = fsl_sai_writeable_reg,
953
	.cache_type = REGCACHE_FLAT,
954 955
};

956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
static int fsl_sai_check_version(struct device *dev)
{
	struct fsl_sai *sai = dev_get_drvdata(dev);
	unsigned char ofs = sai->soc_data->reg_offset;
	unsigned int val;
	int ret;

	if (FSL_SAI_TCSR(ofs) == FSL_SAI_VERID)
		return 0;

	ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
	if (ret < 0)
		return ret;

	dev_dbg(dev, "VERID: 0x%016X\n", val);

	sai->verid.major = (val & FSL_SAI_VERID_MAJOR_MASK) >>
			   FSL_SAI_VERID_MAJOR_SHIFT;
	sai->verid.minor = (val & FSL_SAI_VERID_MINOR_MASK) >>
			   FSL_SAI_VERID_MINOR_SHIFT;
	sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;

	ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
	if (ret < 0)
		return ret;

	dev_dbg(dev, "PARAM: 0x%016X\n", val);

	/* Max slots per frame, power of 2 */
	sai->param.slot_num = 1 <<
		((val & FSL_SAI_PARAM_SPF_MASK) >> FSL_SAI_PARAM_SPF_SHIFT);

	/* Words per fifo, power of 2 */
	sai->param.fifo_depth = 1 <<
		((val & FSL_SAI_PARAM_WPF_MASK) >> FSL_SAI_PARAM_WPF_SHIFT);

	/* Number of datalines implemented */
	sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;

	return 0;
}

998 999
static int fsl_sai_probe(struct platform_device *pdev)
{
1000
	struct device_node *np = pdev->dev.of_node;
1001
	struct fsl_sai *sai;
1002
	struct regmap *gpr;
1003
	struct resource *res;
1004
	void __iomem *base;
1005 1006
	char tmp[8];
	int irq, ret, i;
1007
	int index;
1008 1009 1010 1011 1012

	sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
	if (!sai)
		return -ENOMEM;

1013
	sai->pdev = pdev;
L
Lucas Stach 已提交
1014
	sai->soc_data = of_device_get_match_data(&pdev->dev);
1015

1016
	sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
1017

1018
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1019 1020 1021 1022
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

1023 1024
	if (sai->soc_data->reg_offset == 8) {
		fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8;
1025
		fsl_sai_regmap_config.max_register = FSL_SAI_MDIV;
1026 1027 1028 1029
		fsl_sai_regmap_config.num_reg_defaults =
			ARRAY_SIZE(fsl_sai_reg_defaults_ofs8);
	}

1030
	sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
1031 1032 1033
			"bus", base, &fsl_sai_regmap_config);

	/* Compatible with old DTB cases */
1034
	if (IS_ERR(sai->regmap) && PTR_ERR(sai->regmap) != -EPROBE_DEFER)
1035 1036
		sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
				"sai", base, &fsl_sai_regmap_config);
1037 1038 1039
	if (IS_ERR(sai->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(sai->regmap);
1040 1041
	}

1042 1043 1044 1045 1046 1047 1048 1049
	/* No error out for old DTB cases but only mark the clock NULL */
	sai->bus_clk = devm_clk_get(&pdev->dev, "bus");
	if (IS_ERR(sai->bus_clk)) {
		dev_err(&pdev->dev, "failed to get bus clock: %ld\n",
				PTR_ERR(sai->bus_clk));
		sai->bus_clk = NULL;
	}

1050 1051
	for (i = 1; i < FSL_SAI_MCLK_MAX; i++) {
		sprintf(tmp, "mclk%d", i);
1052 1053 1054 1055 1056 1057 1058 1059
		sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
		if (IS_ERR(sai->mclk_clk[i])) {
			dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n",
					i + 1, PTR_ERR(sai->mclk_clk[i]));
			sai->mclk_clk[i] = NULL;
		}
	}

1060 1061 1062 1063 1064
	if (sai->soc_data->mclk0_is_mclk1)
		sai->mclk_clk[0] = sai->mclk_clk[1];
	else
		sai->mclk_clk[0] = sai->bus_clk;

1065
	irq = platform_get_irq(pdev, 0);
1066
	if (irq < 0)
1067 1068
		return irq;

M
Michael Walle 已提交
1069 1070
	ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, IRQF_SHARED,
			       np->name, sai);
1071 1072 1073 1074 1075
	if (ret) {
		dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
		return ret;
	}

1076 1077 1078
	memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template,
	       sizeof(fsl_sai_dai_template));

1079 1080 1081
	/* Sync Tx with Rx as default by following old DT binding */
	sai->synchronous[RX] = true;
	sai->synchronous[TX] = false;
1082 1083 1084
	sai->cpu_dai_drv.symmetric_rates = 1;
	sai->cpu_dai_drv.symmetric_channels = 1;
	sai->cpu_dai_drv.symmetric_samplebits = 1;
1085

1086 1087 1088 1089 1090 1091 1092
	if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
	    of_find_property(np, "fsl,sai-asynchronous", NULL)) {
		/* error out if both synchronous and asynchronous are present */
		dev_err(&pdev->dev, "invalid binding for synchronous mode\n");
		return -EINVAL;
	}

1093 1094 1095 1096 1097 1098 1099 1100
	if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
		/* Sync Rx with Tx */
		sai->synchronous[RX] = false;
		sai->synchronous[TX] = true;
	} else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
		/* Discard all settings for asynchronous mode */
		sai->synchronous[RX] = false;
		sai->synchronous[TX] = false;
1101 1102 1103
		sai->cpu_dai_drv.symmetric_rates = 0;
		sai->cpu_dai_drv.symmetric_channels = 0;
		sai->cpu_dai_drv.symmetric_samplebits = 0;
1104 1105
	}

1106
	if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
F
Fabio Estevam 已提交
1107
	    of_device_is_compatible(np, "fsl,imx6ul-sai")) {
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
		gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
		if (IS_ERR(gpr)) {
			dev_err(&pdev->dev, "cannot find iomuxc registers\n");
			return PTR_ERR(gpr);
		}

		index = of_alias_get_id(np, "sai");
		if (index < 0)
			return index;

		regmap_update_bits(gpr, IOMUXC_GPR1, MCLK_DIR(index),
				   MCLK_DIR(index));
	}

1122 1123
	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0;
	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0;
1124 1125 1126 1127 1128
	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
	sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;

	platform_set_drvdata(pdev, sai);

1129 1130 1131 1132 1133
	/* Get sai version */
	ret = fsl_sai_check_version(&pdev->dev);
	if (ret < 0)
		dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret);

1134 1135 1136 1137 1138 1139 1140
	/* Select MCLK direction */
	if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
	    sai->verid.major >= 3 && sai->verid.minor >= 1) {
		regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
				   FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
	}

1141
	pm_runtime_enable(&pdev->dev);
1142
	regcache_cache_only(sai->regmap, true);
1143

1144
	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
1145
					      &sai->cpu_dai_drv, 1);
1146
	if (ret)
1147
		goto err_pm_disable;
1148

1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
	if (sai->soc_data->use_imx_pcm) {
		ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
		if (ret)
			goto err_pm_disable;
	} else {
		ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
		if (ret)
			goto err_pm_disable;
	}

	return ret;

err_pm_disable:
	pm_runtime_disable(&pdev->dev);

	return ret;
1165 1166
}

1167 1168 1169
static int fsl_sai_remove(struct platform_device *pdev)
{
	pm_runtime_disable(&pdev->dev);
1170 1171

	return 0;
1172 1173
}

L
Lucas Stach 已提交
1174 1175
static const struct fsl_sai_soc_data fsl_sai_vf610_data = {
	.use_imx_pcm = false,
1176
	.use_edma = false,
1177
	.fifo_depth = 32,
1178
	.reg_offset = 0,
1179
	.mclk0_is_mclk1 = false,
L
Lucas Stach 已提交
1180 1181 1182 1183
};

static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = {
	.use_imx_pcm = true,
1184
	.use_edma = false,
1185
	.fifo_depth = 32,
1186
	.reg_offset = 0,
1187
	.mclk0_is_mclk1 = true,
L
Lucas Stach 已提交
1188 1189
};

1190 1191
static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = {
	.use_imx_pcm = true,
1192
	.use_edma = false,
1193 1194
	.fifo_depth = 16,
	.reg_offset = 8,
1195
	.mclk0_is_mclk1 = false,
1196 1197 1198 1199
};

static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = {
	.use_imx_pcm = true,
1200
	.use_edma = false,
1201 1202
	.fifo_depth = 128,
	.reg_offset = 8,
1203
	.mclk0_is_mclk1 = false,
1204 1205
};

1206 1207
static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = {
	.use_imx_pcm = true,
1208
	.use_edma = true,
1209 1210
	.fifo_depth = 64,
	.reg_offset = 0,
1211
	.mclk0_is_mclk1 = false,
1212 1213
};

1214
static const struct of_device_id fsl_sai_ids[] = {
L
Lucas Stach 已提交
1215 1216 1217
	{ .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },
	{ .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },
	{ .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },
1218 1219
	{ .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },
	{ .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },
1220
	{ .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },
1221 1222
	{ /* sentinel */ }
};
1223
MODULE_DEVICE_TABLE(of, fsl_sai_ids);
1224

1225 1226
#ifdef CONFIG_PM
static int fsl_sai_runtime_suspend(struct device *dev)
1227 1228 1229
{
	struct fsl_sai *sai = dev_get_drvdata(dev);

1230 1231 1232 1233 1234 1235 1236 1237
	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);

	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);

	clk_disable_unprepare(sai->bus_clk);

1238 1239 1240 1241 1242
	regcache_cache_only(sai->regmap, true);

	return 0;
}

1243
static int fsl_sai_runtime_resume(struct device *dev)
1244 1245
{
	struct fsl_sai *sai = dev_get_drvdata(dev);
1246
	unsigned int ofs = sai->soc_data->reg_offset;
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
	int ret;

	ret = clk_prepare_enable(sai->bus_clk);
	if (ret) {
		dev_err(dev, "failed to enable bus clock: %d\n", ret);
		return ret;
	}

	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
		ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
		if (ret)
			goto disable_bus_clk;
	}

	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
		ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
		if (ret)
			goto disable_tx_clk;
	}
1266 1267

	regcache_cache_only(sai->regmap, false);
1268
	regcache_mark_dirty(sai->regmap);
1269 1270
	regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
	regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
1271
	usleep_range(1000, 2000);
1272 1273
	regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
	regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290

	ret = regcache_sync(sai->regmap);
	if (ret)
		goto disable_rx_clk;

	return 0;

disable_rx_clk:
	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
disable_tx_clk:
	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
disable_bus_clk:
	clk_disable_unprepare(sai->bus_clk);

	return ret;
1291
}
1292
#endif /* CONFIG_PM */
1293 1294

static const struct dev_pm_ops fsl_sai_pm_ops = {
1295 1296 1297 1298
	SET_RUNTIME_PM_OPS(fsl_sai_runtime_suspend,
			   fsl_sai_runtime_resume, NULL)
	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
				pm_runtime_force_resume)
1299 1300
};

1301 1302
static struct platform_driver fsl_sai_driver = {
	.probe = fsl_sai_probe,
1303
	.remove = fsl_sai_remove,
1304 1305
	.driver = {
		.name = "fsl-sai",
1306
		.pm = &fsl_sai_pm_ops,
1307 1308 1309 1310 1311 1312 1313 1314 1315
		.of_match_table = fsl_sai_ids,
	},
};
module_platform_driver(fsl_sai_driver);

MODULE_DESCRIPTION("Freescale Soc SAI Interface");
MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>");
MODULE_ALIAS("platform:fsl-sai");
MODULE_LICENSE("GPL");