fsl_sai.c 26.3 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
static irqreturn_t fsl_sai_isr(int irq, void *devid)
{
	struct fsl_sai *sai = (struct fsl_sai *)devid;
	struct device *dev = &sai->pdev->dev;
44 45 46 47 48 49 50 51
	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.
	 */
52 53 54 55
	mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;

	/* Tx IRQ */
	regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
56 57 58 59 60 61
	flags = xcsr & mask;

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

63
	if (flags & FSL_SAI_CSR_WSF)
64 65
		dev_dbg(dev, "isr: Start of Tx word detected\n");

66
	if (flags & FSL_SAI_CSR_SEF)
67
		dev_dbg(dev, "isr: Tx Frame sync error detected\n");
68

69
	if (flags & FSL_SAI_CSR_FEF) {
70
		dev_dbg(dev, "isr: Transmit underrun detected\n");
71 72 73 74
		/* FIFO reset for safety */
		xcsr |= FSL_SAI_CSR_FR;
	}

75
	if (flags & FSL_SAI_CSR_FWF)
76 77
		dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");

78
	if (flags & FSL_SAI_CSR_FRF)
79 80
		dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");

81 82 83 84 85
	flags &= FSL_SAI_CSR_xF_W_MASK;
	xcsr &= ~FSL_SAI_CSR_xF_MASK;

	if (flags)
		regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
86

87
irq_rx:
88 89
	/* Rx IRQ */
	regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
90
	flags = xcsr & mask;
91

92 93 94 95 96 97
	if (flags)
		irq_none = false;
	else
		goto out;

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

100
	if (flags & FSL_SAI_CSR_SEF)
101
		dev_dbg(dev, "isr: Rx Frame sync error detected\n");
102

103
	if (flags & FSL_SAI_CSR_FEF) {
104
		dev_dbg(dev, "isr: Receive overflow detected\n");
105 106 107 108
		/* FIFO reset for safety */
		xcsr |= FSL_SAI_CSR_FR;
	}

109
	if (flags & FSL_SAI_CSR_FWF)
110 111
		dev_dbg(dev, "isr: Enabled receive FIFO is full\n");

112
	if (flags & FSL_SAI_CSR_FRF)
113 114
		dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");

115 116
	flags &= FSL_SAI_CSR_xF_W_MASK;
	xcsr &= ~FSL_SAI_CSR_xF_MASK;
117

118
	if (flags)
119
		regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
120 121 122 123 124 125

out:
	if (irq_none)
		return IRQ_NONE;
	else
		return IRQ_HANDLED;
126 127
}

128 129 130 131 132 133 134 135 136 137 138
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;
}

139 140 141 142
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);
143 144
	bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
	u32 val_cr2 = 0;
X
Xiubo Li 已提交
145

146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
	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 已提交
162

163 164
	regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
			   FSL_SAI_CR2_MSEL_MASK, val_cr2);
165 166 167 168 169 170 171

	return 0;
}

static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
		int clk_id, unsigned int freq, int dir)
{
172
	int ret;
173 174 175 176 177 178 179

	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) {
180
		dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
181
		return ret;
182 183 184 185
	}

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

189
	return ret;
190 191 192 193 194 195
}

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);
196 197
	bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
	u32 val_cr2 = 0, val_cr4 = 0;
198

199
	if (!sai->is_lsb_first)
200
		val_cr4 |= FSL_SAI_CR4_MF;
201

202
	/* DAI mode */
203 204
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
205 206 207 208 209 210
		/*
		 * 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.
		 */
211
		val_cr2 |= FSL_SAI_CR2_BCP;
212 213 214
		val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
215 216 217 218
		/*
		 * Frame high, one word length for frame sync,
		 * frame sync asserts with the first bit of the frame.
		 */
219
		val_cr2 |= FSL_SAI_CR2_BCP;
220
		break;
221 222 223 224 225 226 227
	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.
		 */
228
		val_cr2 |= FSL_SAI_CR2_BCP;
229 230 231 232 233 234 235 236
		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.
		 */
237
		val_cr2 |= FSL_SAI_CR2_BCP;
238 239
		sai->is_dsp_mode = true;
		break;
240 241
	case SND_SOC_DAIFMT_RIGHT_J:
		/* To be done */
242 243 244 245
	default:
		return -EINVAL;
	}

246
	/* DAI clock inversion */
247 248
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_IB_IF:
249 250 251
		/* Invert both clocks */
		val_cr2 ^= FSL_SAI_CR2_BCP;
		val_cr4 ^= FSL_SAI_CR4_FSP;
252 253
		break;
	case SND_SOC_DAIFMT_IB_NF:
254 255
		/* Invert bit clock */
		val_cr2 ^= FSL_SAI_CR2_BCP;
256 257
		break;
	case SND_SOC_DAIFMT_NB_IF:
258 259
		/* Invert frame clock */
		val_cr4 ^= FSL_SAI_CR4_FSP;
260 261
		break;
	case SND_SOC_DAIFMT_NB_NF:
262
		/* Nothing to do for both normal cases */
263 264 265 266 267
		break;
	default:
		return -EINVAL;
	}

268
	/* DAI clock master masks */
269 270 271 272
	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;
273
		sai->is_slave_mode = false;
274 275
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
276
		sai->is_slave_mode = true;
277
		break;
278 279
	case SND_SOC_DAIFMT_CBS_CFM:
		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
280
		sai->is_slave_mode = false;
281 282 283
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
284
		sai->is_slave_mode = true;
285
		break;
286 287 288 289
	default:
		return -EINVAL;
	}

290 291 292 293 294
	regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
			   FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
	regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
			   FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
			   FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
295 296 297 298 299 300

	return 0;
}

static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
301
	int ret;
302 303 304

	ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
	if (ret) {
305
		dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
306
		return ret;
307 308 309
	}

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

313
	return ret;
314 315
}

316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
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);
	unsigned long clk_rate;
	u32 savediv = 0, ratio, savesub = freq;
	u32 id;
	int ret = 0;

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

	for (id = 0; id < FSL_SAI_MCLK_MAX; id++) {
		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;
	}

369 370 371 372 373 374 375 376 377 378 379 380
	/*
	 * 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.
	 */
	if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
	    (!tx && !sai->synchronous[RX])) {
381 382 383 384 385
		regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
				   FSL_SAI_CR2_MSEL_MASK,
				   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
		regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
				   FSL_SAI_CR2_DIV_MASK, savediv - 1);
386 387
	} else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
		   (tx && !sai->synchronous[TX])) {
388 389 390 391 392 393 394 395 396 397 398 399 400
		regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
				   FSL_SAI_CR2_MSEL_MASK,
				   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
		regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
				   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;
}

401 402 403 404
static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params,
		struct snd_soc_dai *cpu_dai)
{
405
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
406
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
407
	unsigned int channels = params_channels(params);
408
	u32 word_width = params_width(params);
409
	u32 val_cr4 = 0, val_cr5 = 0;
410 411
	u32 slots = (channels == 1) ? 2 : channels;
	u32 slot_width = word_width;
412 413
	int ret;

414 415 416 417 418 419
	if (sai->slots)
		slots = sai->slots;

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

420 421
	if (!sai->is_slave_mode) {
		ret = fsl_sai_set_bclk(cpu_dai, tx,
422
				slots * slot_width * params_rate(params));
423 424 425 426 427 428 429 430 431 432 433 434
		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);
		}
	}
435

436
	if (!sai->is_dsp_mode)
437
		val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);
438

439 440
	val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
	val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
441

442
	if (sai->is_lsb_first)
443
		val_cr5 |= FSL_SAI_CR5_FBT(0);
444 445
	else
		val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
446

447
	val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
448

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
	/*
	 * 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),
	 * RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync
	 * error.
	 */

	if (!sai->is_slave_mode) {
		if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
			regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
				FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
				val_cr4);
			regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
				FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
				FSL_SAI_CR5_FBT_MASK, val_cr5);
			regmap_write(sai->regmap, FSL_SAI_TMR,
				~0UL - ((1 << channels) - 1));
		} else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
			regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
				FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
				val_cr4);
			regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
				FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
				FSL_SAI_CR5_FBT_MASK, val_cr5);
			regmap_write(sai->regmap, FSL_SAI_RMR,
				~0UL - ((1 << channels) - 1));
		}
	}
477

478 479 480 481 482 483 484
	regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
			   FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
			   val_cr4);
	regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx),
			   FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
			   FSL_SAI_CR5_FBT_MASK, val_cr5);
	regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
485 486 487 488

	return 0;
}

489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
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;

	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;
}


505 506 507 508
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);
509
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
510
	u32 xcsr, count = 100;
511

512
	/*
513 514 515
	 * 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.
516
	 */
517 518
	regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
		           sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
519
	regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
520
			   sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
521

522 523 524 525
	/*
	 * It is recommended that the transmitter is the last enabled
	 * and the first disabled.
	 */
526 527 528 529
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
530 531 532
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
				   FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);

533 534 535 536
		regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
		regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
537

538 539
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
				   FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
540 541 542 543
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
544 545
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
				   FSL_SAI_CSR_FRDE, 0);
546 547
		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
				   FSL_SAI_CSR_xIE_MASK, 0);
548

549
		/* Check if the opposite FRDE is also disabled */
550 551
		regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
		if (!(xcsr & FSL_SAI_CSR_FRDE)) {
552
			/* Disable both directions and reset their FIFOs */
553
			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
554
					   FSL_SAI_CSR_TERE, 0);
555
			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
556 557 558 559 560 561 562 563 564 565 566 567
					   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), &xcsr);
			} while (--count && xcsr & FSL_SAI_CSR_TERE);

			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
					   FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
					   FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585

			/*
			 * 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 for both Tx and Rx */
				regmap_write(sai->regmap,
					     FSL_SAI_TCSR, FSL_SAI_CSR_SR);
				regmap_write(sai->regmap,
					     FSL_SAI_RCSR, FSL_SAI_CSR_SR);
				/* Clear SR bit to finish the reset */
				regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
				regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
			}
586 587 588 589 590 591 592 593 594 595 596 597 598
		}
		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);
599
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
600 601
	int ret;

602
	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
603 604
			   FSL_SAI_CR3_TRCE);

605 606 607 608
	ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
			SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);

	return ret;
609 610 611 612 613 614
}

static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
		struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
615
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
616

617
	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
618 619 620 621 622
}

static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
	.set_sysclk	= fsl_sai_set_dai_sysclk,
	.set_fmt	= fsl_sai_set_dai_fmt,
623
	.set_tdm_slot	= fsl_sai_set_dai_tdm_slot,
624
	.hw_params	= fsl_sai_hw_params,
625
	.hw_free	= fsl_sai_hw_free,
626 627 628 629 630 631 632 633
	.trigger	= fsl_sai_trigger,
	.startup	= fsl_sai_startup,
	.shutdown	= fsl_sai_shutdown,
};

static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
634

635 636 637 638 639 640 641
	/* Software Reset for both Tx and Rx */
	regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
	regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
	/* Clear SR bit to finish the reset */
	regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
	regmap_write(sai->regmap, FSL_SAI_RCSR, 0);

642
	regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
643
			   sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX);
644 645
	regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
			   FSL_SAI_MAXBURST_RX - 1);
646

647 648
	snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
				&sai->dma_params_rx);
649 650 651 652 653 654 655 656 657

	snd_soc_dai_set_drvdata(cpu_dai, sai);

	return 0;
}

static struct snd_soc_dai_driver fsl_sai_dai = {
	.probe = fsl_sai_dai_probe,
	.playback = {
658
		.stream_name = "CPU-Playback",
659
		.channels_min = 1,
660
		.channels_max = 32,
661 662 663
		.rate_min = 8000,
		.rate_max = 192000,
		.rates = SNDRV_PCM_RATE_KNOT,
664 665 666
		.formats = FSL_SAI_FORMATS,
	},
	.capture = {
667
		.stream_name = "CPU-Capture",
668
		.channels_min = 1,
669
		.channels_max = 32,
670 671 672
		.rate_min = 8000,
		.rate_max = 192000,
		.rates = SNDRV_PCM_RATE_KNOT,
673 674 675 676 677 678 679 680 681
		.formats = FSL_SAI_FORMATS,
	},
	.ops = &fsl_sai_pcm_dai_ops,
};

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

682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
static struct reg_default fsl_sai_reg_defaults[] = {
	{FSL_SAI_TCR1, 0},
	{FSL_SAI_TCR2, 0},
	{FSL_SAI_TCR3, 0},
	{FSL_SAI_TCR4, 0},
	{FSL_SAI_TCR5, 0},
	{FSL_SAI_TDR,  0},
	{FSL_SAI_TMR,  0},
	{FSL_SAI_RCR1, 0},
	{FSL_SAI_RCR2, 0},
	{FSL_SAI_RCR3, 0},
	{FSL_SAI_RCR4, 0},
	{FSL_SAI_RCR5, 0},
	{FSL_SAI_RMR,  0},
};

698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case FSL_SAI_TCSR:
	case FSL_SAI_TCR1:
	case FSL_SAI_TCR2:
	case FSL_SAI_TCR3:
	case FSL_SAI_TCR4:
	case FSL_SAI_TCR5:
	case FSL_SAI_TFR:
	case FSL_SAI_TMR:
	case FSL_SAI_RCSR:
	case FSL_SAI_RCR1:
	case FSL_SAI_RCR2:
	case FSL_SAI_RCR3:
	case FSL_SAI_RCR4:
	case FSL_SAI_RCR5:
	case FSL_SAI_RDR:
	case FSL_SAI_RFR:
	case FSL_SAI_RMR:
		return true;
	default:
		return false;
	}
}

static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
727 728
	case FSL_SAI_TCSR:
	case FSL_SAI_RCSR:
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
	case FSL_SAI_TFR:
	case FSL_SAI_RFR:
	case FSL_SAI_RDR:
		return true;
	default:
		return false;
	}
}

static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case FSL_SAI_TCSR:
	case FSL_SAI_TCR1:
	case FSL_SAI_TCR2:
	case FSL_SAI_TCR3:
	case FSL_SAI_TCR4:
	case FSL_SAI_TCR5:
	case FSL_SAI_TDR:
	case FSL_SAI_TMR:
	case FSL_SAI_RCSR:
	case FSL_SAI_RCR1:
	case FSL_SAI_RCR2:
	case FSL_SAI_RCR3:
	case FSL_SAI_RCR4:
	case FSL_SAI_RCR5:
	case FSL_SAI_RMR:
		return true;
	default:
		return false;
	}
}

762
static const struct regmap_config fsl_sai_regmap_config = {
763 764 765 766 767
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,

	.max_register = FSL_SAI_RMR,
768 769
	.reg_defaults = fsl_sai_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults),
770 771 772
	.readable_reg = fsl_sai_readable_reg,
	.volatile_reg = fsl_sai_volatile_reg,
	.writeable_reg = fsl_sai_writeable_reg,
773
	.cache_type = REGCACHE_FLAT,
774 775
};

776 777
static int fsl_sai_probe(struct platform_device *pdev)
{
778
	struct device_node *np = pdev->dev.of_node;
779
	struct fsl_sai *sai;
780
	struct regmap *gpr;
781
	struct resource *res;
782
	void __iomem *base;
783 784
	char tmp[8];
	int irq, ret, i;
785
	int index;
786 787 788 789 790

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

791
	sai->pdev = pdev;
L
Lucas Stach 已提交
792
	sai->soc_data = of_device_get_match_data(&pdev->dev);
793

794
	sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
795

796
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
797 798 799 800 801
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
802 803 804 805 806 807
			"bus", base, &fsl_sai_regmap_config);

	/* Compatible with old DTB cases */
	if (IS_ERR(sai->regmap))
		sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
				"sai", base, &fsl_sai_regmap_config);
808 809 810
	if (IS_ERR(sai->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(sai->regmap);
811 812
	}

813 814 815 816 817 818 819 820
	/* 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;
	}

821 822 823
	sai->mclk_clk[0] = sai->bus_clk;
	for (i = 1; i < FSL_SAI_MCLK_MAX; i++) {
		sprintf(tmp, "mclk%d", i);
824 825 826 827 828 829 830 831
		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;
		}
	}

832 833
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
834
		dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
835 836 837 838 839 840 841 842 843
		return irq;
	}

	ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai);
	if (ret) {
		dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
		return ret;
	}

844 845 846 847 848 849 850
	/* Sync Tx with Rx as default by following old DT binding */
	sai->synchronous[RX] = true;
	sai->synchronous[TX] = false;
	fsl_sai_dai.symmetric_rates = 1;
	fsl_sai_dai.symmetric_channels = 1;
	fsl_sai_dai.symmetric_samplebits = 1;

851 852 853 854 855 856 857
	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;
	}

858 859 860 861 862 863 864 865 866 867 868 869 870
	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;
		fsl_sai_dai.symmetric_rates = 0;
		fsl_sai_dai.symmetric_channels = 0;
		fsl_sai_dai.symmetric_samplebits = 0;
	}

871
	if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
F
Fabio Estevam 已提交
872
	    of_device_is_compatible(np, "fsl,imx6ul-sai")) {
873 874 875 876 877 878 879 880 881 882 883 884 885 886
		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));
	}

887 888 889 890 891 892 893
	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
	sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;

	platform_set_drvdata(pdev, sai);

894 895
	pm_runtime_enable(&pdev->dev);

896 897 898 899 900
	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
			&fsl_sai_dai, 1);
	if (ret)
		return ret;

L
Lucas Stach 已提交
901
	if (sai->soc_data->use_imx_pcm)
902
		return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
903
	else
904
		return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
905 906
}

907 908 909
static int fsl_sai_remove(struct platform_device *pdev)
{
	pm_runtime_disable(&pdev->dev);
910 911

	return 0;
912 913
}

L
Lucas Stach 已提交
914 915
static const struct fsl_sai_soc_data fsl_sai_vf610_data = {
	.use_imx_pcm = false,
916
	.fifo_depth = 32,
L
Lucas Stach 已提交
917 918 919 920
};

static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = {
	.use_imx_pcm = true,
921
	.fifo_depth = 32,
L
Lucas Stach 已提交
922 923
};

924
static const struct of_device_id fsl_sai_ids[] = {
L
Lucas Stach 已提交
925 926 927
	{ .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 },
928 929
	{ /* sentinel */ }
};
930
MODULE_DEVICE_TABLE(of, fsl_sai_ids);
931

932 933
#ifdef CONFIG_PM
static int fsl_sai_runtime_suspend(struct device *dev)
934 935 936
{
	struct fsl_sai *sai = dev_get_drvdata(dev);

937 938 939 940 941 942 943 944
	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);

945 946 947 948 949 950
	regcache_cache_only(sai->regmap, true);
	regcache_mark_dirty(sai->regmap);

	return 0;
}

951
static int fsl_sai_runtime_resume(struct device *dev)
952 953
{
	struct fsl_sai *sai = dev_get_drvdata(dev);
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
	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;
	}
973 974 975 976

	regcache_cache_only(sai->regmap, false);
	regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
	regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
977
	usleep_range(1000, 2000);
978 979
	regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
	regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996

	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;
997
}
998
#endif /* CONFIG_PM */
999 1000

static const struct dev_pm_ops fsl_sai_pm_ops = {
1001 1002 1003 1004
	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)
1005 1006
};

1007 1008
static struct platform_driver fsl_sai_driver = {
	.probe = fsl_sai_probe,
1009
	.remove = fsl_sai_remove,
1010 1011
	.driver = {
		.name = "fsl-sai",
1012
		.pm = &fsl_sai_pm_ops,
1013 1014 1015 1016 1017 1018 1019 1020 1021
		.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");