fsl_ssi.c 44.0 KB
Newer Older
1 2 3 4 5
/*
 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
 *
 * Author: Timur Tabi <timur@freescale.com>
 *
6 7 8 9 10
 * Copyright 2007-2010 Freescale Semiconductor, Inc.
 *
 * This file is licensed under the terms of the GNU General Public License
 * version 2.  This program is licensed "as is" without any warranty of any
 * kind, whether express or implied.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 *
 * Some notes why imx-pcm-fiq is used instead of DMA on some boards:
 *
 * The i.MX SSI core has some nasty limitations in AC97 mode. While most
 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
 * one FIFO which combines all valid receive slots. We cannot even select
 * which slots we want to receive. The WM9712 with which this driver
 * was developed with always sends GPIO status data in slot 12 which
 * we receive in our (PCM-) data stream. The only chance we have is to
 * manually skip this data in the FIQ handler. With sampling rates different
 * from 48000Hz not every frame has valid receive data, so the ratio
 * between pcm data and GPIO status data changes. Our FIQ handler is not
 * able to handle this, hence this driver only works with 48000Hz sampling
 * rate.
 * Reading and writing AC97 registers is another challenge. The core
 * provides us status bits when the read register is updated with *another*
 * value. When we read the same register two times (and the register still
 * contains the same value) these status bits are not set. We work
 * around this by not polling these bits but only wait a fixed delay.
31 32 33
 */

#include <linux/init.h>
34
#include <linux/io.h>
35 36
#include <linux/module.h>
#include <linux/interrupt.h>
37
#include <linux/clk.h>
38
#include <linux/ctype.h>
39 40
#include <linux/device.h>
#include <linux/delay.h>
41
#include <linux/mutex.h>
42
#include <linux/slab.h>
43
#include <linux/spinlock.h>
44
#include <linux/of.h>
45 46
#include <linux/of_address.h>
#include <linux/of_irq.h>
47
#include <linux/of_platform.h>
48 49 50 51 52 53

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/soc.h>
54
#include <sound/dmaengine_pcm.h>
55 56

#include "fsl_ssi.h"
57
#include "imx-pcm.h"
58

59 60 61 62
/* Define RX and TX to index ssi->regvals array; Can be 0 or 1 only */
#define RX 0
#define TX 1

63 64 65 66 67 68 69 70 71 72 73 74 75
/**
 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
 *
 * The SSI has a limitation in that the samples must be in the same byte
 * order as the host CPU.  This is because when multiple bytes are written
 * to the STX register, the bytes and bits must be written in the same
 * order.  The STX is a shift register, so all the bits need to be aligned
 * (bit-endianness must match byte-endianness).  Processors typically write
 * the bits within a byte in the same order that the bytes of a word are
 * written in.  So if the host CPU is big-endian, then only big-endian
 * samples will be written to STX properly.
 */
#ifdef __BIG_ENDIAN
76 77 78 79 80 81 82
#define FSLSSI_I2S_FORMATS \
	(SNDRV_PCM_FMTBIT_S8 | \
	 SNDRV_PCM_FMTBIT_S16_BE | \
	 SNDRV_PCM_FMTBIT_S18_3BE | \
	 SNDRV_PCM_FMTBIT_S20_3BE | \
	 SNDRV_PCM_FMTBIT_S24_3BE | \
	 SNDRV_PCM_FMTBIT_S24_BE)
83
#else
84 85 86 87 88 89 90
#define FSLSSI_I2S_FORMATS \
	(SNDRV_PCM_FMTBIT_S8 | \
	 SNDRV_PCM_FMTBIT_S16_LE | \
	 SNDRV_PCM_FMTBIT_S18_3LE | \
	 SNDRV_PCM_FMTBIT_S20_3LE | \
	 SNDRV_PCM_FMTBIT_S24_3LE | \
	 SNDRV_PCM_FMTBIT_S24_LE)
91 92
#endif

93 94 95 96 97 98 99 100 101 102 103 104
#define FSLSSI_SIER_DBG_RX_FLAGS \
	(SSI_SIER_RFF0_EN | \
	 SSI_SIER_RLS_EN | \
	 SSI_SIER_RFS_EN | \
	 SSI_SIER_ROE0_EN | \
	 SSI_SIER_RFRC_EN)
#define FSLSSI_SIER_DBG_TX_FLAGS \
	(SSI_SIER_TFE0_EN | \
	 SSI_SIER_TLS_EN | \
	 SSI_SIER_TFS_EN | \
	 SSI_SIER_TUE0_EN | \
	 SSI_SIER_TFRC_EN)
105 106 107 108

enum fsl_ssi_type {
	FSL_SSI_MCP8610,
	FSL_SSI_MX21,
109
	FSL_SSI_MX35,
110 111 112
	FSL_SSI_MX51,
};

113
struct fsl_ssi_regvals {
114 115 116 117 118 119
	u32 sier;
	u32 srcr;
	u32 stcr;
	u32 scr;
};

120 121 122
static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
123 124
	case REG_SSI_SACCEN:
	case REG_SSI_SACCDIS:
125 126 127 128 129 130 131 132 133
		return false;
	default:
		return true;
	}
}

static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
134 135 136 137 138 139 140 141 142 143 144 145
	case REG_SSI_STX0:
	case REG_SSI_STX1:
	case REG_SSI_SRX0:
	case REG_SSI_SRX1:
	case REG_SSI_SISR:
	case REG_SSI_SFCSR:
	case REG_SSI_SACNT:
	case REG_SSI_SACADD:
	case REG_SSI_SACDAT:
	case REG_SSI_SATAG:
	case REG_SSI_SACCST:
	case REG_SSI_SOR:
146 147 148 149 150 151
		return true;
	default:
		return false;
	}
}

152 153 154
static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
155 156 157 158 159 160
	case REG_SSI_SRX0:
	case REG_SSI_SRX1:
	case REG_SSI_SISR:
	case REG_SSI_SACADD:
	case REG_SSI_SACDAT:
	case REG_SSI_SATAG:
161 162 163 164 165 166
		return true;
	default:
		return false;
	}
}

167 168 169
static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
170 171 172
	case REG_SSI_SRX0:
	case REG_SSI_SRX1:
	case REG_SSI_SACCST:
173 174 175 176 177 178
		return false;
	default:
		return true;
	}
}

M
Markus Pargmann 已提交
179
static const struct regmap_config fsl_ssi_regconfig = {
180
	.max_register = REG_SSI_SACCDIS,
M
Markus Pargmann 已提交
181 182 183 184
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.val_format_endian = REGMAP_ENDIAN_NATIVE,
185
	.num_reg_defaults_raw = REG_SSI_SACCDIS / sizeof(uint32_t) + 1,
186 187
	.readable_reg = fsl_ssi_readable_reg,
	.volatile_reg = fsl_ssi_volatile_reg,
188
	.precious_reg = fsl_ssi_precious_reg,
189
	.writeable_reg = fsl_ssi_writeable_reg,
190
	.cache_type = REGCACHE_FLAT,
M
Markus Pargmann 已提交
191
};
192

193 194
struct fsl_ssi_soc_data {
	bool imx;
195
	bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
196 197 198 199
	bool offline_config;
	u32 sisr_write_mask;
};

200
/**
201
 * fsl_ssi: per-SSI private data
202
 *
N
Nicolin Chen 已提交
203
 * @regs: Pointer to the regmap registers
204
 * @irq: IRQ of this SSI
205 206 207
 * @cpu_dai_drv: CPU DAI driver for this device
 *
 * @dai_fmt: DAI configuration this device is currently used with
208
 * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
209
 * @i2s_net: I2S and Network mode configurations of SCR register
210
 * @use_dma: DMA is used or FIQ with stream filter
N
Nicolin Chen 已提交
211 212 213 214 215
 * @use_dual_fifo: DMA with support for dual FIFO mode
 * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree
 * @fifo_depth: Depth of the SSI FIFOs
 * @slot_width: Width of each DAI slot
 * @slots: Number of slots
216
 * @regvals: Specific RX/TX register settings
217
 *
N
Nicolin Chen 已提交
218 219
 * @clk: Clock source to access register
 * @baudclk: Clock source to generate bit and frame-sync clocks
220 221
 * @baudclk_streams: Active streams that are using baudclk
 *
N
Nicolin Chen 已提交
222 223 224
 * @regcache_sfcsr: Cache sfcsr register value during suspend and resume
 * @regcache_sacnt: Cache sacnt register value during suspend and resume
 *
225 226 227 228 229 230
 * @dma_params_tx: DMA transmit parameters
 * @dma_params_rx: DMA receive parameters
 * @ssi_phys: physical address of the SSI registers
 *
 * @fiq_params: FIQ stream filtering parameters
 *
N
Nicolin Chen 已提交
231 232
 * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only)
 *        TODO: Should be replaced with simple-sound-card
233 234 235
 *
 * @dbg_stats: Debugging statistics
 *
236
 * @soc: SoC specific data
N
Nicolin Chen 已提交
237 238 239 240 241 242 243
 * @dev: Pointer to &pdev->dev
 *
 * @fifo_watermark: The FIFO watermark setting. Notifies DMA when there are
 *                  @fifo_watermark or fewer words in TX fifo or
 *                  @fifo_watermark or more empty words in RX fifo.
 * @dma_maxburst: Max number of words to transfer in one go. So far,
 *                this is always the same as fifo_watermark.
244
 *
N
Nicolin Chen 已提交
245
 * @ac97_reg_lock: Mutex lock to serialize AC97 register access operations
246
 */
247
struct fsl_ssi {
M
Markus Pargmann 已提交
248
	struct regmap *regs;
249
	int irq;
250
	struct snd_soc_dai_driver cpu_dai_drv;
251

252
	unsigned int dai_fmt;
253
	u8 streams;
254
	u8 i2s_net;
255
	bool use_dma;
256
	bool use_dual_fifo;
257
	bool has_ipg_clk_name;
258
	unsigned int fifo_depth;
259 260
	unsigned int slot_width;
	unsigned int slots;
261
	struct fsl_ssi_regvals regvals[2];
262

263
	struct clk *clk;
264
	struct clk *baudclk;
265
	unsigned int baudclk_streams;
266

267
	u32 regcache_sfcsr;
268
	u32 regcache_sacnt;
269

270 271
	struct snd_dmaengine_dai_dma_data dma_params_tx;
	struct snd_dmaengine_dai_dma_data dma_params_rx;
272 273
	dma_addr_t ssi_phys;

274
	struct imx_pcm_fiq_params fiq_params;
275 276

	struct platform_device *pdev;
277

278
	struct fsl_ssi_dbg dbg_stats;
279

280
	const struct fsl_ssi_soc_data *soc;
281
	struct device *dev;
282 283 284

	u32 fifo_watermark;
	u32 dma_maxburst;
285 286

	struct mutex ac97_reg_lock;
287
};
288 289

/*
N
Nicolin Chen 已提交
290
 * SoC specific data
291
 *
N
Nicolin Chen 已提交
292 293 294 295 296 297 298 299 300 301 302
 * Notes:
 * 1) SSI in earlier SoCS has critical bits in control registers that
 *    cannot be changed after SSI starts running -- a software reset
 *    (set SSIEN to 0) is required to change their values. So adding
 *    an offline_config flag for these SoCs.
 * 2) SDMA is available since imx35. However, imx35 does not support
 *    DMA bits changing when SSI is running, so set offline_config.
 * 3) imx51 and later versions support register configurations when
 *    SSI is running (SSIEN); For these versions, DMA needs to be
 *    configured before SSI sends DMA request to avoid an undefined
 *    DMA request on the SDMA side.
303 304
 */

305 306 307
static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
	.imx = false,
	.offline_config = true,
308
	.sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
309 310
			   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
			   SSI_SISR_TUE0 | SSI_SISR_TUE1,
311 312 313 314
};

static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
	.imx = true,
315
	.imx21regs = true,
316 317 318 319 320 321 322
	.offline_config = true,
	.sisr_write_mask = 0,
};

static struct fsl_ssi_soc_data fsl_ssi_imx35 = {
	.imx = true,
	.offline_config = true,
323
	.sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
324 325
			   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
			   SSI_SISR_TUE0 | SSI_SISR_TUE1,
326 327 328 329 330
};

static struct fsl_ssi_soc_data fsl_ssi_imx51 = {
	.imx = true,
	.offline_config = false,
331
	.sisr_write_mask = SSI_SISR_ROE0 | SSI_SISR_ROE1 |
332
			   SSI_SISR_TUE0 | SSI_SISR_TUE1,
333 334 335 336 337 338 339 340 341 342 343
};

static const struct of_device_id fsl_ssi_ids[] = {
	{ .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 },
	{ .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 },
	{ .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 },
	{ .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 },
	{}
};
MODULE_DEVICE_TABLE(of, fsl_ssi_ids);

344
static bool fsl_ssi_is_ac97(struct fsl_ssi *ssi)
345
{
346
	return (ssi->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
347
		SND_SOC_DAIFMT_AC97;
348 349
}

350
static bool fsl_ssi_is_i2s_master(struct fsl_ssi *ssi)
351
{
352
	return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
353 354 355
		SND_SOC_DAIFMT_CBS_CFS;
}

356
static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi *ssi)
357
{
358
	return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
359 360
		SND_SOC_DAIFMT_CBM_CFS;
}
N
Nicolin Chen 已提交
361

362
/**
N
Nicolin Chen 已提交
363
 * Interrupt handler to gather states
364 365 366
 */
static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
{
367 368
	struct fsl_ssi *ssi = dev_id;
	struct regmap *regs = ssi->regs;
369
	__be32 sisr;
370
	__be32 sisr2;
371

372
	regmap_read(regs, REG_SSI_SISR, &sisr);
373

374
	sisr2 = sisr & ssi->soc->sisr_write_mask;
375 376
	/* Clear the bits that we set */
	if (sisr2)
377
		regmap_write(regs, REG_SSI_SISR, sisr2);
378

379
	fsl_ssi_dbg_isr(&ssi->dbg_stats, sisr);
380

381
	return IRQ_HANDLED;
382 383
}

N
Nicolin Chen 已提交
384
/**
385 386 387 388 389 390
 * Set SCR, SIER, STCR and SRCR registers with cached values in regvals
 *
 * Notes:
 * 1) For offline_config SoCs, enable all necessary bits of both streams
 *    when 1st stream starts, even if the opposite stream will not start
 * 2) It also clears FIFO before setting regvals; SOR is safe to set online
391
 */
392
static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx)
393
{
394
	struct fsl_ssi_regvals *vals = ssi->regvals;
395 396
	int dir = tx ? TX : RX;
	u32 sier, srcr, stcr;
397

398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
	/* Clear dirty data in the FIFO; It also prevents channel slipping */
	regmap_update_bits(ssi->regs, REG_SSI_SOR,
			   SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));

	/*
	 * On offline_config SoCs, SxCR and SIER are already configured when
	 * the previous stream started. So skip all SxCR and SIER settings
	 * to prevent online reconfigurations, then jump to set SCR directly
	 */
	if (ssi->soc->offline_config && ssi->streams)
		goto enable_scr;

	if (ssi->soc->offline_config) {
		/*
		 * Online reconfiguration not supported, so enable all bits for
		 * both streams at once to avoid necessity of reconfigurations
		 */
		srcr = vals[RX].srcr | vals[TX].srcr;
		stcr = vals[RX].stcr | vals[TX].stcr;
		sier = vals[RX].sier | vals[TX].sier;
418
	} else {
419 420 421 422
		/* Otherwise, only set bits for the current stream */
		srcr = vals[dir].srcr;
		stcr = vals[dir].stcr;
		sier = vals[dir].sier;
423
	}
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461

	/* Configure SRCR, STCR and SIER at once */
	regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, srcr);
	regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, stcr);
	regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, sier);

enable_scr:
	/*
	 * Start DMA before setting TE to avoid FIFO underrun
	 * which may cause a channel slip or a channel swap
	 *
	 * TODO: FIQ cases might also need this upon testing
	 */
	if (ssi->use_dma && tx) {
		int try = 100;
		u32 sfcsr;

		/* Enable SSI first to send TX DMA request */
		regmap_update_bits(ssi->regs, REG_SSI_SCR,
				   SSI_SCR_SSIEN, SSI_SCR_SSIEN);

		/* Busy wait until TX FIFO not empty -- DMA working */
		do {
			regmap_read(ssi->regs, REG_SSI_SFCSR, &sfcsr);
			if (SSI_SFCSR_TFCNT0(sfcsr))
				break;
		} while (--try);

		/* FIFO still empty -- something might be wrong */
		if (!SSI_SFCSR_TFCNT0(sfcsr))
			dev_warn(ssi->dev, "Timeout waiting TX FIFO filling\n");
	}
	/* Enable all remaining bits in SCR */
	regmap_update_bits(ssi->regs, REG_SSI_SCR,
			   vals[dir].scr, vals[dir].scr);

	/* Log the enabled stream to the mask */
	ssi->streams |= BIT(dir);
462 463
}

N
Nicolin Chen 已提交
464
/**
465
 * Exclude bits that are used by the opposite stream
466
 *
467 468
 * When both streams are active, disabling some bits for the current stream
 * might break the other stream if these bits are used by it.
469
 *
470 471 472
 * @vals : regvals of the current stream
 * @avals: regvals of the opposite stream
 * @aactive: active state of the opposite stream
473
 *
474 475 476
 *  1) XOR vals and avals to get the differences if the other stream is active;
 *     Otherwise, return current vals if the other stream is not active
 *  2) AND the result of 1) with the current vals
477
 */
478 479 480 481 482
#define _ssi_xor_shared_bits(vals, avals, aactive) \
	((vals) ^ ((avals) * (aactive)))

#define ssi_excl_shared_bits(vals, avals, aactive) \
	((vals) & _ssi_xor_shared_bits(vals, avals, aactive))
483

N
Nicolin Chen 已提交
484
/**
485 486 487 488 489 490
 * Unset SCR, SIER, STCR and SRCR registers with cached values in regvals
 *
 * Notes:
 * 1) For offline_config SoCs, to avoid online reconfigurations, disable all
 *    bits of both streams at once when the last stream is abort to end
 * 2) It also clears FIFO after unsetting regvals; SOR is safe to set online
491
 */
492
static void fsl_ssi_config_disable(struct fsl_ssi *ssi, bool tx)
493
{
494 495
	struct fsl_ssi_regvals *vals, *avals;
	u32 sier, srcr, stcr, scr;
496 497
	int adir = tx ? RX : TX;
	int dir = tx ? TX : RX;
498
	bool aactive;
M
Markus Pargmann 已提交
499

500 501
	/* Check if the opposite stream is active */
	aactive = ssi->streams & BIT(adir);
502

503
	vals = &ssi->regvals[dir];
504

505 506
	/* Get regvals of the opposite stream to keep opposite stream safe */
	avals = &ssi->regvals[adir];
507 508

	/*
509 510
	 * To keep the other stream safe, exclude shared bits between
	 * both streams, and get safe bits to disable current stream
511
	 */
512
	scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
513

514 515
	/* Disable safe bits of SCR register for the current stream */
	regmap_update_bits(ssi->regs, REG_SSI_SCR, scr, 0);
516

517 518
	/* Log the disabled stream to the mask */
	ssi->streams &= ~BIT(dir);
519

520 521 522 523 524 525
	/*
	 * On offline_config SoCs, if the other stream is active, skip
	 * SxCR and SIER settings to prevent online reconfigurations
	 */
	if (ssi->soc->offline_config && aactive)
		goto fifo_clear;
526

527 528 529 530 531 532
	if (ssi->soc->offline_config) {
		/* Now there is only current stream active, disable all bits */
		srcr = vals->srcr | avals->srcr;
		stcr = vals->stcr | avals->stcr;
		sier = vals->sier | avals->sier;
	} else {
533
		/*
N
Nicolin Chen 已提交
534 535
		 * To keep the other stream safe, exclude shared bits between
		 * both streams, and get safe bits to disable current stream
536
		 */
537 538 539
		sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive);
		srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive);
		stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive);
540 541
	}

542 543 544 545
	/* Clear configurations of SRCR, STCR and SIER at once */
	regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, 0);
	regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, 0);
	regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, 0);
546

547 548 549 550
fifo_clear:
	/* Clear remaining data in the FIFO */
	regmap_update_bits(ssi->regs, REG_SSI_SOR,
			   SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
551 552
}

553
static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
554
{
555
	struct regmap *regs = ssi->regs;
556 557

	/* no SACC{ST,EN,DIS} regs on imx21-class SSI */
558
	if (!ssi->soc->imx21regs) {
N
Nicolin Chen 已提交
559
		/* Disable all channel slots */
560
		regmap_write(regs, REG_SSI_SACCDIS, 0xff);
N
Nicolin Chen 已提交
561
		/* Enable slots 3 & 4 -- PCM Playback Left & Right channels */
562
		regmap_write(regs, REG_SSI_SACCEN, 0x300);
563 564 565
	}
}

N
Nicolin Chen 已提交
566 567
/**
 * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely
568
 */
569
static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
570
{
571
	struct fsl_ssi_regvals *vals = ssi->regvals;
572

573 574 575 576 577 578
	vals[RX].sier = SSI_SIER_RFF0_EN;
	vals[RX].srcr = SSI_SRCR_RFEN0;
	vals[RX].scr = 0;
	vals[TX].sier = SSI_SIER_TFE0_EN;
	vals[TX].stcr = SSI_STCR_TFEN0;
	vals[TX].scr = 0;
579

N
Nicolin Chen 已提交
580
	/* AC97 has already enabled SSIEN, RE and TE, so ignore them */
581
	if (!fsl_ssi_is_ac97(ssi)) {
582 583
		vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
		vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
584 585
	}

586
	if (ssi->use_dma) {
587 588
		vals[RX].sier |= SSI_SIER_RDMAE;
		vals[TX].sier |= SSI_SIER_TDMAE;
589
	} else {
590 591
		vals[RX].sier |= SSI_SIER_RIE;
		vals[TX].sier |= SSI_SIER_TIE;
592 593
	}

594 595
	vals[RX].sier |= FSLSSI_SIER_DBG_RX_FLAGS;
	vals[TX].sier |= FSLSSI_SIER_DBG_TX_FLAGS;
596 597
}

598
static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi)
599
{
600
	struct regmap *regs = ssi->regs;
601

N
Nicolin Chen 已提交
602
	/* Setup the clock control register */
603 604
	regmap_write(regs, REG_SSI_STCCR, SSI_SxCCR_WL(17) | SSI_SxCCR_DC(13));
	regmap_write(regs, REG_SSI_SRCCR, SSI_SxCCR_WL(17) | SSI_SxCCR_DC(13));
605

N
Nicolin Chen 已提交
606
	/* Enable AC97 mode and startup the SSI */
607
	regmap_write(regs, REG_SSI_SACNT, SSI_SACNT_AC97EN | SSI_SACNT_FV);
608

N
Nicolin Chen 已提交
609
	/* AC97 has to communicate with codec before starting a stream */
610
	regmap_update_bits(regs, REG_SSI_SCR,
611 612
			   SSI_SCR_SSIEN | SSI_SCR_TE | SSI_SCR_RE,
			   SSI_SCR_SSIEN | SSI_SCR_TE | SSI_SCR_RE);
613

614
	regmap_write(regs, REG_SSI_SOR, SSI_SOR_WAIT(3));
615 616
}

617 618
static int fsl_ssi_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
619 620
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
621
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
622 623
	int ret;

624
	ret = clk_prepare_enable(ssi->clk);
625 626
	if (ret)
		return ret;
627

N
Nicolin Chen 已提交
628 629
	/*
	 * When using dual fifo mode, it is safer to ensure an even period
630 631 632 633
	 * size. If appearing to an odd number while DMA always starts its
	 * task from fifo0, fifo1 would be neglected at the end of each
	 * period. But SSI would still access fifo1 with an invalid data.
	 */
634
	if (ssi->use_dual_fifo)
635
		snd_pcm_hw_constraint_step(substream->runtime, 0,
636
					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
637

638 639 640
	return 0;
}

641
static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
642
			     struct snd_soc_dai *dai)
643 644
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
645
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
646

647
	clk_disable_unprepare(ssi->clk);
648 649
}

650
/**
N
Nicolin Chen 已提交
651
 * Configure Digital Audio Interface bit clock
652 653 654 655
 *
 * Note: This function can be only called when using SSI as DAI master
 *
 * Quick instruction for parameters:
656 657
 * freq: Output BCLK frequency = samplerate * slots * slot_width
 *       (In 2-channel I2S Master mode, slot_width is fixed 32)
658
 */
659
static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
660
			    struct snd_soc_dai *dai,
661
			    struct snd_pcm_hw_params *hw_params)
662
{
663
	bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
664
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
665 666
	struct regmap *regs = ssi->regs;
	int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret;
667
	u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
668
	unsigned long clkrate, baudrate, tmprate;
669 670
	unsigned int slots = params_channels(hw_params);
	unsigned int slot_width = 32;
671
	u64 sub, savesub = 100000;
672
	unsigned int freq;
673
	bool baudclk_is_used;
674

675
	/* Override slots and slot_width if being specifically set... */
676 677
	if (ssi->slots)
		slots = ssi->slots;
678
	/* ...but keep 32 bits if slots is 2 -- I2S Master mode */
679 680
	if (ssi->slot_width && slots != 2)
		slot_width = ssi->slot_width;
681 682 683

	/* Generate bit clock based on the slot number and slot width */
	freq = slots * slot_width * params_rate(hw_params);
684 685

	/* Don't apply it to any non-baudclk circumstance */
686
	if (IS_ERR(ssi->baudclk))
687 688
		return -EINVAL;

689 690 691 692
	/*
	 * Hardware limitation: The bclk rate must be
	 * never greater than 1/5 IPG clock rate
	 */
693
	if (freq * 5 > clk_get_rate(ssi->clk)) {
694
		dev_err(dai->dev, "bitclk > ipgclk / 5\n");
695 696 697
		return -EINVAL;
	}

698
	baudclk_is_used = ssi->baudclk_streams & ~(BIT(substream->stream));
699

700 701 702 703 704 705 706
	/* It should be already enough to divide clock by setting pm alone */
	psr = 0;
	div2 = 0;

	factor = (div2 + 1) * (7 * psr + 1) * 2;

	for (i = 0; i < 255; i++) {
707
		tmprate = freq * factor * (i + 1);
708 709

		if (baudclk_is_used)
710
			clkrate = clk_get_rate(ssi->baudclk);
711
		else
712
			clkrate = clk_round_rate(ssi->baudclk, tmprate);
713

714 715
		clkrate /= factor;
		afreq = clkrate / (i + 1);
716 717 718 719 720 721 722 723 724 725 726 727 728 729

		if (freq == afreq)
			sub = 0;
		else if (freq / afreq == 1)
			sub = freq - afreq;
		else if (afreq / freq == 1)
			sub = afreq - freq;
		else
			continue;

		/* Calculate the fraction */
		sub *= 100000;
		do_div(sub, freq);

730
		if (sub < savesub && !(i == 0 && psr == 0 && div2 == 0)) {
731 732 733 734 735 736 737 738 739 740 741 742
			baudrate = tmprate;
			savesub = sub;
			pm = i;
		}

		/* We are lucky */
		if (savesub == 0)
			break;
	}

	/* No proper pm found if it is still remaining the initial value */
	if (pm == 999) {
743
		dev_err(dai->dev, "failed to handle the required sysclk\n");
744 745 746
		return -EINVAL;
	}

747 748
	stccr = SSI_SxCCR_PM(pm + 1) | (div2 ? SSI_SxCCR_DIV2 : 0) |
		(psr ? SSI_SxCCR_PSR : 0);
749
	mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR;
750

751 752 753
	/* STCCR is used for RX in synchronous mode */
	tx2 = tx || synchronous;
	regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr);
754

755
	if (!baudclk_is_used) {
756
		ret = clk_set_rate(ssi->baudclk, baudrate);
757
		if (ret) {
758
			dev_err(dai->dev, "failed to set baudclk rate\n");
759 760 761 762 763 764 765
			return -EINVAL;
		}
	}

	return 0;
}

766
/**
N
Nicolin Chen 已提交
767
 * Configure SSI based on PCM hardware parameters
768
 *
N
Nicolin Chen 已提交
769 770 771 772 773 774 775
 * Notes:
 * 1) SxCCR.WL bits are critical bits that require SSI to be temporarily
 *    disabled on offline_config SoCs. Even for online configurable SoCs
 *    running in synchronous mode (both TX and RX use STCCR), it is not
 *    safe to re-configure them when both two streams start running.
 * 2) SxCCR.PM, SxCCR.DIV2 and SxCCR.PSR bits will be configured in the
 *    fsl_ssi_set_bclk() if SSI is the DAI clock master.
776
 */
777
static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
778
			     struct snd_pcm_hw_params *hw_params,
779
			     struct snd_soc_dai *dai)
780
{
781
	bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
782
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
783
	struct regmap *regs = ssi->regs;
784
	unsigned int channels = params_channels(hw_params);
785
	unsigned int sample_size = params_width(hw_params);
786
	u32 wl = SSI_SxCCR_WL(sample_size);
787
	int ret;
788
	u32 scr;
M
Markus Pargmann 已提交
789 790
	int enabled;

791 792
	regmap_read(regs, REG_SSI_SCR, &scr);
	enabled = scr & SSI_SCR_SSIEN;
793

794
	/*
N
Nicolin Chen 已提交
795 796 797 798
	 * SSI is properly configured if it is enabled and running in
	 * the synchronous mode; Note that AC97 mode is an exception
	 * that should set separate configurations for STCCR and SRCCR
	 * despite running in the synchronous mode.
799
	 */
800
	if (enabled && ssi->cpu_dai_drv.symmetric_rates)
801
		return 0;
802

803
	if (fsl_ssi_is_i2s_master(ssi)) {
804
		ret = fsl_ssi_set_bclk(substream, dai, hw_params);
805 806
		if (ret)
			return ret;
807 808

		/* Do not enable the clock if it is already enabled */
809 810
		if (!(ssi->baudclk_streams & BIT(substream->stream))) {
			ret = clk_prepare_enable(ssi->baudclk);
811 812 813
			if (ret)
				return ret;

814
			ssi->baudclk_streams |= BIT(substream->stream);
815
		}
816 817
	}

818
	if (!fsl_ssi_is_ac97(ssi)) {
N
Nicolin Chen 已提交
819
		/* Normal + Network mode to send 16-bit data in 32-bit frames */
820
		if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
821 822 823 824 825
			ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;

		/* Use Normal mode to send mono data at 1st slot of 2 slots */
		if (channels == 1)
			ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL;
826

827
		regmap_update_bits(regs, REG_SSI_SCR,
828
				   SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
829 830
	}

831
	/* In synchronous mode, the SSI uses STCCR for capture */
832 833
	tx2 = tx || ssi->cpu_dai_drv.symmetric_rates;
	regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl);
834 835 836 837

	return 0;
}

838
static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
839
			   struct snd_soc_dai *dai)
840 841
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
842
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
843

844
	if (fsl_ssi_is_i2s_master(ssi) &&
845
	    ssi->baudclk_streams & BIT(substream->stream)) {
846 847
		clk_disable_unprepare(ssi->baudclk);
		ssi->baudclk_streams &= ~BIT(substream->stream);
848 849 850 851 852
	}

	return 0;
}

853
static int _fsl_ssi_set_dai_fmt(struct device *dev,
854
				struct fsl_ssi *ssi, unsigned int fmt)
855
{
856
	struct regmap *regs = ssi->regs;
857
	u32 strcr = 0, stcr, srcr, scr, mask;
858 859
	u8 wm;

860
	ssi->dai_fmt = fmt;
861

862
	if (fsl_ssi_is_i2s_master(ssi) && IS_ERR(ssi->baudclk)) {
863
		dev_err(dev, "missing baudclk for master mode\n");
864 865 866
		return -EINVAL;
	}

867
	fsl_ssi_setup_regvals(ssi);
868

869 870
	regmap_read(regs, REG_SSI_SCR, &scr);
	scr &= ~(SSI_SCR_SYN | SSI_SCR_I2S_MODE_MASK);
N
Nicolin Chen 已提交
871
	/* Synchronize frame sync clock for TE to avoid data slipping */
872
	scr |= SSI_SCR_SYNC_TX_FS;
873

874
	mask = SSI_STCR_TXBIT0 | SSI_STCR_TFDIR | SSI_STCR_TXDIR |
875
	       SSI_STCR_TSCKP | SSI_STCR_TFSI | SSI_STCR_TFSL | SSI_STCR_TEFS;
876 877
	regmap_read(regs, REG_SSI_STCR, &stcr);
	regmap_read(regs, REG_SSI_SRCR, &srcr);
M
Markus Pargmann 已提交
878 879
	stcr &= ~mask;
	srcr &= ~mask;
880

N
Nicolin Chen 已提交
881
	/* Use Network mode as default */
882
	ssi->i2s_net = SSI_SCR_NET;
883 884
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
885
		regmap_update_bits(regs, REG_SSI_STCCR,
886
				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
887
		regmap_update_bits(regs, REG_SSI_SRCCR,
888
				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
889
		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
890
		case SND_SOC_DAIFMT_CBM_CFS:
891
		case SND_SOC_DAIFMT_CBS_CFS:
892
			ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER;
893 894
			break;
		case SND_SOC_DAIFMT_CBM_CFM:
895
			ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE;
896 897 898 899 900 901
			break;
		default:
			return -EINVAL;
		}

		/* Data on rising edge of bclk, frame low, 1clk before data */
902
		strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP |
903
			 SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
904 905 906
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		/* Data on rising edge of bclk, frame high */
907
		strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
908 909 910
		break;
	case SND_SOC_DAIFMT_DSP_A:
		/* Data on rising edge of bclk, frame high, 1clk before data */
911
		strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP |
912
			 SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
913 914 915
		break;
	case SND_SOC_DAIFMT_DSP_B:
		/* Data on rising edge of bclk, frame high */
916
		strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | SSI_STCR_TXBIT0;
917
		break;
918
	case SND_SOC_DAIFMT_AC97:
N
Nicolin Chen 已提交
919
		/* Data on falling edge of bclk, frame high, 1clk before data */
920
		ssi->i2s_net |= SSI_SCR_I2S_MODE_NORMAL;
921
		break;
922 923 924
	default:
		return -EINVAL;
	}
925
	scr |= ssi->i2s_net;
926 927 928 929 930 931 932 933

	/* DAI clock inversion */
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		/* Nothing to do for both normal cases */
		break;
	case SND_SOC_DAIFMT_IB_NF:
		/* Invert bit clock */
934
		strcr ^= SSI_STCR_TSCKP;
935 936 937
		break;
	case SND_SOC_DAIFMT_NB_IF:
		/* Invert frame clock */
938
		strcr ^= SSI_STCR_TFSI;
939 940 941
		break;
	case SND_SOC_DAIFMT_IB_IF:
		/* Invert both clocks */
942 943
		strcr ^= SSI_STCR_TSCKP;
		strcr ^= SSI_STCR_TFSI;
944 945 946 947 948 949 950 951
		break;
	default:
		return -EINVAL;
	}

	/* DAI clock master masks */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
N
Nicolin Chen 已提交
952
		/* Output bit and frame sync clocks */
953 954
		strcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;
		scr |= SSI_SCR_SYS_CLK_EN;
955 956
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
N
Nicolin Chen 已提交
957
		/* Input bit or frame sync clocks */
958
		scr &= ~SSI_SCR_SYS_CLK_EN;
959
		break;
960
	case SND_SOC_DAIFMT_CBM_CFS:
N
Nicolin Chen 已提交
961
		/* Input bit clock but output frame sync clock */
962 963 964
		strcr &= ~SSI_STCR_TXDIR;
		strcr |= SSI_STCR_TFDIR;
		scr &= ~SSI_SCR_SYS_CLK_EN;
965
		break;
966
	default:
967
		if (!fsl_ssi_is_ac97(ssi))
968
			return -EINVAL;
969 970 971 972 973
	}

	stcr |= strcr;
	srcr |= strcr;

N
Nicolin Chen 已提交
974
	/* Set SYN mode and clear RXDIR bit when using SYN or AC97 mode */
975
	if (ssi->cpu_dai_drv.symmetric_rates || fsl_ssi_is_ac97(ssi)) {
976 977
		srcr &= ~SSI_SRCR_RXDIR;
		scr |= SSI_SCR_SYN;
978 979
	}

980 981 982
	regmap_write(regs, REG_SSI_STCR, stcr);
	regmap_write(regs, REG_SSI_SRCR, srcr);
	regmap_write(regs, REG_SSI_SCR, scr);
983

984
	wm = ssi->fifo_watermark;
985

986
	regmap_write(regs, REG_SSI_SFCSR,
987 988
		     SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
		     SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));
989

990
	if (ssi->use_dual_fifo) {
991 992 993 994 995 996
		regmap_update_bits(regs, REG_SSI_SRCR,
				   SSI_SRCR_RFEN1, SSI_SRCR_RFEN1);
		regmap_update_bits(regs, REG_SSI_STCR,
				   SSI_STCR_TFEN1, SSI_STCR_TFEN1);
		regmap_update_bits(regs, REG_SSI_SCR,
				   SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);
997 998
	}

999
	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
1000
		fsl_ssi_setup_ac97(ssi);
1001

1002
	return 0;
1003 1004 1005
}

/**
N
Nicolin Chen 已提交
1006
 * Configure Digital Audio Interface (DAI) Format
1007
 */
1008
static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1009
{
1010
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
1011

N
Nicolin Chen 已提交
1012
	/* AC97 configured DAIFMT earlier in the probe() */
1013
	if (fsl_ssi_is_ac97(ssi))
1014 1015
		return 0;

1016
	return _fsl_ssi_set_dai_fmt(dai->dev, ssi, fmt);
1017 1018 1019
}

/**
N
Nicolin Chen 已提交
1020
 * Set TDM slot number and slot width
1021
 */
1022
static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
1023
				    u32 rx_mask, int slots, int slot_width)
1024
{
1025
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
1026
	struct regmap *regs = ssi->regs;
1027 1028
	u32 val;

1029 1030
	/* The word length should be 8, 10, 12, 16, 18, 20, 22 or 24 */
	if (slot_width & 1 || slot_width < 8 || slot_width > 24) {
1031
		dev_err(dai->dev, "invalid slot width: %d\n", slot_width);
1032 1033 1034
		return -EINVAL;
	}

1035
	/* The slot number should be >= 2 if using Network mode or I2S mode */
1036
	if (ssi->i2s_net && slots < 2) {
1037
		dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n");
1038 1039 1040
		return -EINVAL;
	}

1041 1042 1043 1044
	regmap_update_bits(regs, REG_SSI_STCCR,
			   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots));
	regmap_update_bits(regs, REG_SSI_SRCCR,
			   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots));
1045

1046
	/* Save the SCR register value */
1047
	regmap_read(regs, REG_SSI_SCR, &val);
N
Nicolin Chen 已提交
1048
	/* Temporarily enable SSI to allow SxMSKs to be configurable */
1049
	regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN);
1050

1051 1052
	regmap_write(regs, REG_SSI_STMSK, ~tx_mask);
	regmap_write(regs, REG_SSI_SRMSK, ~rx_mask);
1053

N
Nicolin Chen 已提交
1054
	/* Restore the value of SSIEN bit */
1055
	regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, val);
1056

1057 1058
	ssi->slot_width = slot_width;
	ssi->slots = slots;
1059

1060 1061 1062
	return 0;
}

1063
/**
N
Nicolin Chen 已提交
1064
 * Start or stop SSI and corresponding DMA transaction.
1065 1066 1067 1068
 *
 * The DMA channel is in external master start and pause mode, which
 * means the SSI completely controls the flow of data.
 */
1069 1070
static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
			   struct snd_soc_dai *dai)
1071 1072
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
1073
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
1074
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1075

1076 1077
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
1078
	case SNDRV_PCM_TRIGGER_RESUME:
1079
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
		/*
		 * SACCST might be modified via AC Link by a CODEC if it sends
		 * extra bits in their SLOTREQ requests, which'll accidentally
		 * send valid data to slots other than normal playback slots.
		 *
		 * To be safe, configure SACCST right before TX starts.
		 */
		if (tx && fsl_ssi_is_ac97(ssi))
			fsl_ssi_tx_ac97_saccst_setup(ssi);
		fsl_ssi_config_enable(ssi, tx);
1090 1091 1092
		break;

	case SNDRV_PCM_TRIGGER_STOP:
1093
	case SNDRV_PCM_TRIGGER_SUSPEND:
1094
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1095
		fsl_ssi_config_disable(ssi, tx);
1096 1097 1098 1099 1100 1101 1102 1103 1104
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

1105 1106
static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
{
1107
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
1108

1109 1110 1111
	if (ssi->soc->imx && ssi->use_dma) {
		dai->playback_dma_data = &ssi->dma_params_tx;
		dai->capture_dma_data = &ssi->dma_params_rx;
1112 1113 1114 1115 1116
	}

	return 0;
}

1117
static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
1118 1119 1120 1121 1122 1123 1124
	.startup = fsl_ssi_startup,
	.shutdown = fsl_ssi_shutdown,
	.hw_params = fsl_ssi_hw_params,
	.hw_free = fsl_ssi_hw_free,
	.set_fmt = fsl_ssi_set_dai_fmt,
	.set_tdm_slot = fsl_ssi_set_dai_tdm_slot,
	.trigger = fsl_ssi_trigger,
1125 1126
};

1127
static struct snd_soc_dai_driver fsl_ssi_dai_template = {
1128
	.probe = fsl_ssi_dai_probe,
1129
	.playback = {
1130
		.stream_name = "CPU-Playback",
1131
		.channels_min = 1,
1132
		.channels_max = 32,
1133
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
1134 1135 1136
		.formats = FSLSSI_I2S_FORMATS,
	},
	.capture = {
1137
		.stream_name = "CPU-Capture",
1138
		.channels_min = 1,
1139
		.channels_max = 32,
1140
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
1141 1142
		.formats = FSLSSI_I2S_FORMATS,
	},
1143
	.ops = &fsl_ssi_dai_ops,
1144 1145
};

1146
static const struct snd_soc_component_driver fsl_ssi_component = {
1147
	.name = "fsl-ssi",
1148 1149
};

1150
static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
1151
	.bus_control = true,
1152
	.probe = fsl_ssi_dai_probe,
1153 1154 1155 1156 1157
	.playback = {
		.stream_name = "AC97 Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
1158
		.formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S20,
1159 1160 1161 1162 1163 1164
	},
	.capture = {
		.stream_name = "AC97 Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_48000,
1165 1166
		/* 16-bit capture is broken (errata ERR003778) */
		.formats = SNDRV_PCM_FMTBIT_S20,
1167
	},
1168
	.ops = &fsl_ssi_dai_ops,
1169 1170
};

1171
static struct fsl_ssi *fsl_ac97_data;
1172

1173
static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
1174
			       unsigned short val)
1175
{
M
Markus Pargmann 已提交
1176
	struct regmap *regs = fsl_ac97_data->regs;
1177 1178
	unsigned int lreg;
	unsigned int lval;
1179
	int ret;
1180 1181 1182 1183

	if (reg > 0x7f)
		return;

1184 1185
	mutex_lock(&fsl_ac97_data->ac97_reg_lock);

1186 1187 1188 1189
	ret = clk_prepare_enable(fsl_ac97_data->clk);
	if (ret) {
		pr_err("ac97 write clk_prepare_enable failed: %d\n",
			ret);
1190
		goto ret_unlock;
1191
	}
1192 1193

	lreg = reg <<  12;
1194
	regmap_write(regs, REG_SSI_SACADD, lreg);
1195 1196

	lval = val << 4;
1197
	regmap_write(regs, REG_SSI_SACDAT, lval);
1198

1199 1200
	regmap_update_bits(regs, REG_SSI_SACNT,
			   SSI_SACNT_RDWR_MASK, SSI_SACNT_WR);
1201
	udelay(100);
1202 1203

	clk_disable_unprepare(fsl_ac97_data->clk);
1204 1205 1206

ret_unlock:
	mutex_unlock(&fsl_ac97_data->ac97_reg_lock);
1207 1208
}

1209
static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
1210
					unsigned short reg)
1211
{
M
Markus Pargmann 已提交
1212
	struct regmap *regs = fsl_ac97_data->regs;
1213
	unsigned short val = 0;
M
Markus Pargmann 已提交
1214
	u32 reg_val;
1215
	unsigned int lreg;
1216 1217
	int ret;

1218 1219
	mutex_lock(&fsl_ac97_data->ac97_reg_lock);

1220 1221
	ret = clk_prepare_enable(fsl_ac97_data->clk);
	if (ret) {
1222
		pr_err("ac97 read clk_prepare_enable failed: %d\n", ret);
1223
		goto ret_unlock;
1224
	}
1225 1226

	lreg = (reg & 0x7f) <<  12;
1227
	regmap_write(regs, REG_SSI_SACADD, lreg);
1228 1229
	regmap_update_bits(regs, REG_SSI_SACNT,
			   SSI_SACNT_RDWR_MASK, SSI_SACNT_RD);
1230 1231 1232

	udelay(100);

1233
	regmap_read(regs, REG_SSI_SACDAT, &reg_val);
M
Markus Pargmann 已提交
1234
	val = (reg_val >> 4) & 0xffff;
1235

1236 1237
	clk_disable_unprepare(fsl_ac97_data->clk);

1238 1239
ret_unlock:
	mutex_unlock(&fsl_ac97_data->ac97_reg_lock);
1240 1241 1242 1243
	return val;
}

static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
1244 1245
	.read = fsl_ssi_ac97_read,
	.write = fsl_ssi_ac97_write,
1246 1247
};

1248
/**
1249
 * Make every character in a string lower-case
1250
 */
1251 1252
static void make_lowercase(char *s)
{
1253 1254 1255 1256
	if (!s)
		return;
	for (; *s; s++)
		*s = tolower(*s);
1257 1258
}

1259
static int fsl_ssi_imx_probe(struct platform_device *pdev,
1260
			     struct fsl_ssi *ssi, void __iomem *iomem)
1261 1262
{
	struct device_node *np = pdev->dev.of_node;
1263
	struct device *dev = &pdev->dev;
1264
	u32 dmas[4];
1265 1266
	int ret;

N
Nicolin Chen 已提交
1267
	/* Backward compatible for a DT without ipg clock name assigned */
1268
	if (ssi->has_ipg_clk_name)
1269
		ssi->clk = devm_clk_get(dev, "ipg");
1270
	else
1271
		ssi->clk = devm_clk_get(dev, NULL);
1272 1273
	if (IS_ERR(ssi->clk)) {
		ret = PTR_ERR(ssi->clk);
1274
		dev_err(dev, "failed to get clock: %d\n", ret);
1275 1276 1277
		return ret;
	}

N
Nicolin Chen 已提交
1278
	/* Enable the clock since regmap will not handle it in this case */
1279 1280
	if (!ssi->has_ipg_clk_name) {
		ret = clk_prepare_enable(ssi->clk);
1281
		if (ret) {
1282
			dev_err(dev, "clk_prepare_enable failed: %d\n", ret);
1283 1284
			return ret;
		}
1285 1286
	}

N
Nicolin Chen 已提交
1287
	/* Do not error out for slave cases that live without a baud clock */
1288
	ssi->baudclk = devm_clk_get(dev, "baud");
1289
	if (IS_ERR(ssi->baudclk))
1290
		dev_dbg(dev, "failed to get baud clock: %ld\n",
1291
			 PTR_ERR(ssi->baudclk));
1292

1293 1294
	ssi->dma_params_tx.maxburst = ssi->dma_maxburst;
	ssi->dma_params_rx.maxburst = ssi->dma_maxburst;
1295 1296
	ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0;
	ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0;
1297

N
Nicolin Chen 已提交
1298
	/* Set to dual FIFO mode according to the SDMA sciprt */
1299
	ret = of_property_read_u32_array(np, "dmas", dmas, 4);
1300 1301
	if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
		ssi->use_dual_fifo = true;
N
Nicolin Chen 已提交
1302 1303 1304
		/*
		 * Use even numbers to avoid channel swap due to SDMA
		 * script design
1305
		 */
1306 1307
		ssi->dma_params_tx.maxburst &= ~0x1;
		ssi->dma_params_rx.maxburst &= ~0x1;
1308 1309
	}

1310
	if (!ssi->use_dma) {
1311
		/*
N
Nicolin Chen 已提交
1312 1313
		 * Some boards use an incompatible codec. Use imx-fiq-pcm-audio
		 * to get it working, as DMA is not possible in this situation.
1314
		 */
1315 1316 1317 1318
		ssi->fiq_params.irq = ssi->irq;
		ssi->fiq_params.base = iomem;
		ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx;
		ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
1319

1320
		ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
1321 1322 1323
		if (ret)
			goto error_pcm;
	} else {
1324
		ret = imx_pcm_dma_init(pdev, IMX_SSI_DMABUF_SIZE);
1325 1326 1327 1328
		if (ret)
			goto error_pcm;
	}

1329
	return 0;
1330 1331

error_pcm:
1332 1333
	if (!ssi->has_ipg_clk_name)
		clk_disable_unprepare(ssi->clk);
1334

1335
	return ret;
1336 1337
}

1338
static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi)
1339
{
1340
	if (!ssi->use_dma)
1341
		imx_pcm_fiq_exit(pdev);
1342 1343
	if (!ssi->has_ipg_clk_name)
		clk_disable_unprepare(ssi->clk);
1344 1345
}

1346
static int fsl_ssi_probe(struct platform_device *pdev)
1347
{
1348
	struct fsl_ssi *ssi;
1349
	int ret = 0;
1350
	struct device_node *np = pdev->dev.of_node;
1351
	struct device *dev = &pdev->dev;
1352
	const struct of_device_id *of_id;
1353
	const char *p, *sprop;
1354
	const __be32 *iprop;
1355
	struct resource *res;
M
Markus Pargmann 已提交
1356
	void __iomem *iomem;
1357
	char name[64];
1358
	struct regmap_config regconfig = fsl_ssi_regconfig;
1359

1360
	of_id = of_match_device(fsl_ssi_ids, dev);
1361
	if (!of_id || !of_id->data)
1362 1363
		return -EINVAL;

1364
	ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
1365
	if (!ssi)
1366
		return -ENOMEM;
1367

1368
	ssi->soc = of_id->data;
1369
	ssi->dev = dev;
1370

N
Nicolin Chen 已提交
1371
	/* Check if being used in AC97 mode */
1372 1373 1374
	sprop = of_get_property(np, "fsl,mode", NULL);
	if (sprop) {
		if (!strcmp(sprop, "ac97-slave"))
1375
			ssi->dai_fmt = SND_SOC_DAIFMT_AC97;
1376 1377
	}

N
Nicolin Chen 已提交
1378
	/* Select DMA or FIQ */
1379
	ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter");
1380

1381 1382
	if (fsl_ssi_is_ac97(ssi)) {
		memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai,
1383
		       sizeof(fsl_ssi_ac97_dai));
1384
		fsl_ac97_data = ssi;
1385
	} else {
1386
		memcpy(&ssi->cpu_dai_drv, &fsl_ssi_dai_template,
1387 1388
		       sizeof(fsl_ssi_dai_template));
	}
1389
	ssi->cpu_dai_drv.name = dev_name(dev);
1390

1391
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1392
	iomem = devm_ioremap_resource(dev, res);
1393 1394
	if (IS_ERR(iomem))
		return PTR_ERR(iomem);
1395
	ssi->ssi_phys = res->start;
M
Markus Pargmann 已提交
1396

1397
	if (ssi->soc->imx21regs) {
N
Nicolin Chen 已提交
1398
		/* No SACC{ST,EN,DIS} regs in imx21-class SSI */
1399
		regconfig.max_register = REG_SSI_SRMSK;
1400
		regconfig.num_reg_defaults_raw =
1401
			REG_SSI_SRMSK / sizeof(uint32_t) + 1;
1402 1403
	}

1404 1405
	ret = of_property_match_string(np, "clock-names", "ipg");
	if (ret < 0) {
1406
		ssi->has_ipg_clk_name = false;
1407
		ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig);
1408
	} else {
1409
		ssi->has_ipg_clk_name = true;
1410 1411
		ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem,
						      &regconfig);
1412
	}
1413
	if (IS_ERR(ssi->regs)) {
1414
		dev_err(dev, "failed to init register map\n");
1415
		return PTR_ERR(ssi->regs);
M
Markus Pargmann 已提交
1416
	}
1417

1418 1419
	ssi->irq = platform_get_irq(pdev, 0);
	if (ssi->irq < 0) {
1420
		dev_err(dev, "no irq for node %s\n", pdev->name);
1421
		return ssi->irq;
1422 1423
	}

N
Nicolin Chen 已提交
1424
	/* Set software limitations for synchronous mode */
1425
	if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
1426 1427 1428
		if (!fsl_ssi_is_ac97(ssi)) {
			ssi->cpu_dai_drv.symmetric_rates = 1;
			ssi->cpu_dai_drv.symmetric_samplebits = 1;
1429
		}
1430

1431
		ssi->cpu_dai_drv.symmetric_channels = 1;
1432
	}
1433

N
Nicolin Chen 已提交
1434
	/* Fetch FIFO depth; Set to 8 for older DT without this property */
1435 1436
	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
	if (iprop)
1437
		ssi->fifo_depth = be32_to_cpup(iprop);
1438
	else
1439
		ssi->fifo_depth = 8;
1440

1441
	/*
N
Nicolin Chen 已提交
1442
	 * Configure TX and RX DMA watermarks -- when to send a DMA request
1443
	 *
N
Nicolin Chen 已提交
1444 1445
	 * Values should be tested to avoid FIFO under/over run. Set maxburst
	 * to fifo_watermark to maxiumize DMA transaction to reduce overhead.
1446
	 */
1447
	switch (ssi->fifo_depth) {
1448 1449
	case 15:
		/*
N
Nicolin Chen 已提交
1450 1451 1452 1453 1454 1455
		 * Set to 8 as a balanced configuration -- When TX FIFO has 8
		 * empty slots, send a DMA request to fill these 8 slots. The
		 * remaining 7 slots should be able to allow DMA to finish the
		 * transaction before TX FIFO underruns; Same applies to RX.
		 *
		 * Tested with cases running at 48kHz @ 16 bits x 16 channels
1456
		 */
1457 1458
		ssi->fifo_watermark = 8;
		ssi->dma_maxburst = 8;
1459 1460 1461
		break;
	case 8:
	default:
N
Nicolin Chen 已提交
1462
		/* Safely use old watermark configurations for older chips */
1463 1464
		ssi->fifo_watermark = ssi->fifo_depth - 2;
		ssi->dma_maxburst = ssi->fifo_depth - 2;
1465 1466 1467
		break;
	}

1468
	dev_set_drvdata(dev, ssi);
1469

1470 1471
	if (ssi->soc->imx) {
		ret = fsl_ssi_imx_probe(pdev, ssi, iomem);
1472
		if (ret)
F
Fabio Estevam 已提交
1473
			return ret;
1474 1475
	}

1476 1477
	if (fsl_ssi_is_ac97(ssi)) {
		mutex_init(&ssi->ac97_reg_lock);
1478 1479
		ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
		if (ret) {
1480
			dev_err(dev, "failed to set AC'97 ops\n");
1481 1482 1483 1484
			goto error_ac97_ops;
		}
	}

1485
	ret = devm_snd_soc_register_component(dev, &fsl_ssi_component,
1486
					      &ssi->cpu_dai_drv, 1);
1487
	if (ret) {
1488
		dev_err(dev, "failed to register DAI: %d\n", ret);
1489 1490 1491
		goto error_asoc_register;
	}

1492
	if (ssi->use_dma) {
1493 1494
		ret = devm_request_irq(dev, ssi->irq, fsl_ssi_isr, 0,
				       dev_name(dev), ssi);
1495
		if (ret < 0) {
1496
			dev_err(dev, "failed to claim irq %u\n", ssi->irq);
1497
			goto error_asoc_register;
1498
		}
1499 1500
	}

1501
	ret = fsl_ssi_debugfs_create(&ssi->dbg_stats, dev);
1502
	if (ret)
1503
		goto error_asoc_register;
1504

N
Nicolin Chen 已提交
1505
	/* Bypass it if using newer DT bindings of ASoC machine drivers */
1506
	if (!of_get_property(np, "codec-handle", NULL))
1507 1508
		goto done;

N
Nicolin Chen 已提交
1509 1510 1511 1512
	/*
	 * Backward compatible for older bindings by manually triggering the
	 * machine driver's probe(). Use /compatible property, including the
	 * address of CPU DAI driver structure, as the name of machine driver.
1513
	 */
1514 1515
	sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
	/* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
1516 1517 1518 1519 1520 1521
	p = strrchr(sprop, ',');
	if (p)
		sprop = p + 1;
	snprintf(name, sizeof(name), "snd-soc-%s", sprop);
	make_lowercase(name);

1522
	ssi->pdev = platform_device_register_data(dev, name, 0, NULL, 0);
1523 1524
	if (IS_ERR(ssi->pdev)) {
		ret = PTR_ERR(ssi->pdev);
1525
		dev_err(dev, "failed to register platform: %d\n", ret);
1526
		goto error_sound_card;
M
Mark Brown 已提交
1527
	}
1528

1529
done:
1530
	if (ssi->dai_fmt)
1531
		_fsl_ssi_set_dai_fmt(dev, ssi, ssi->dai_fmt);
1532

1533
	if (fsl_ssi_is_ac97(ssi)) {
1534 1535 1536 1537
		u32 ssi_idx;

		ret = of_property_read_u32(np, "cell-index", &ssi_idx);
		if (ret) {
1538
			dev_err(dev, "failed to get SSI index property\n");
1539 1540 1541
			goto error_sound_card;
		}

1542 1543
		ssi->pdev = platform_device_register_data(NULL, "ac97-codec",
							  ssi_idx, NULL, 0);
1544 1545
		if (IS_ERR(ssi->pdev)) {
			ret = PTR_ERR(ssi->pdev);
1546
			dev_err(dev,
1547 1548 1549 1550 1551 1552
				"failed to register AC97 codec platform: %d\n",
				ret);
			goto error_sound_card;
		}
	}

1553
	return 0;
1554

1555
error_sound_card:
1556
	fsl_ssi_debugfs_remove(&ssi->dbg_stats);
1557
error_asoc_register:
1558
	if (fsl_ssi_is_ac97(ssi))
1559 1560
		snd_soc_set_ac97_ops(NULL);
error_ac97_ops:
1561 1562
	if (fsl_ssi_is_ac97(ssi))
		mutex_destroy(&ssi->ac97_reg_lock);
1563

1564 1565
	if (ssi->soc->imx)
		fsl_ssi_imx_clean(pdev, ssi);
1566

1567
	return ret;
1568 1569
}

1570
static int fsl_ssi_remove(struct platform_device *pdev)
1571
{
1572
	struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev);
1573

1574
	fsl_ssi_debugfs_remove(&ssi->dbg_stats);
1575

1576 1577
	if (ssi->pdev)
		platform_device_unregister(ssi->pdev);
1578

1579 1580
	if (ssi->soc->imx)
		fsl_ssi_imx_clean(pdev, ssi);
1581

1582
	if (fsl_ssi_is_ac97(ssi)) {
1583
		snd_soc_set_ac97_ops(NULL);
1584
		mutex_destroy(&ssi->ac97_reg_lock);
1585
	}
1586

1587
	return 0;
1588
}
1589

1590 1591 1592
#ifdef CONFIG_PM_SLEEP
static int fsl_ssi_suspend(struct device *dev)
{
1593 1594
	struct fsl_ssi *ssi = dev_get_drvdata(dev);
	struct regmap *regs = ssi->regs;
1595

1596 1597
	regmap_read(regs, REG_SSI_SFCSR, &ssi->regcache_sfcsr);
	regmap_read(regs, REG_SSI_SACNT, &ssi->regcache_sacnt);
1598 1599 1600 1601 1602 1603 1604 1605 1606

	regcache_cache_only(regs, true);
	regcache_mark_dirty(regs);

	return 0;
}

static int fsl_ssi_resume(struct device *dev)
{
1607 1608
	struct fsl_ssi *ssi = dev_get_drvdata(dev);
	struct regmap *regs = ssi->regs;
1609 1610 1611

	regcache_cache_only(regs, false);

1612
	regmap_update_bits(regs, REG_SSI_SFCSR,
1613 1614 1615
			   SSI_SFCSR_RFWM1_MASK | SSI_SFCSR_TFWM1_MASK |
			   SSI_SFCSR_RFWM0_MASK | SSI_SFCSR_TFWM0_MASK,
			   ssi->regcache_sfcsr);
1616
	regmap_write(regs, REG_SSI_SACNT, ssi->regcache_sacnt);
1617 1618 1619 1620 1621 1622 1623 1624 1625

	return regcache_sync(regs);
}
#endif /* CONFIG_PM_SLEEP */

static const struct dev_pm_ops fsl_ssi_pm = {
	SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume)
};

1626
static struct platform_driver fsl_ssi_driver = {
1627 1628 1629
	.driver = {
		.name = "fsl-ssi-dai",
		.of_match_table = fsl_ssi_ids,
1630
		.pm = &fsl_ssi_pm,
1631 1632 1633 1634
	},
	.probe = fsl_ssi_probe,
	.remove = fsl_ssi_remove,
};
1635

1636
module_platform_driver(fsl_ssi_driver);
1637

1638
MODULE_ALIAS("platform:fsl-ssi-dai");
1639 1640
MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
1641
MODULE_LICENSE("GPL v2");