fsl_ssi.c 44.8 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
/*
 * In AC97 mode, TXDIR bit is forced to 0 and TFDIR bit is forced to 1:
 *  - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS
 *  - Also have NB_NF to mark these two clocks will not be inverted
 */
#define FSLSSI_AC97_DAIFMT \
	(SND_SOC_DAIFMT_AC97 | \
	 SND_SOC_DAIFMT_CBM_CFS | \
	 SND_SOC_DAIFMT_NB_NF)

103 104 105 106 107 108 109 110 111 112 113 114
#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)
115 116 117 118

enum fsl_ssi_type {
	FSL_SSI_MCP8610,
	FSL_SSI_MX21,
119
	FSL_SSI_MX35,
120 121 122
	FSL_SSI_MX51,
};

123
struct fsl_ssi_regvals {
124 125 126 127 128 129
	u32 sier;
	u32 srcr;
	u32 stcr;
	u32 scr;
};

130 131 132
static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
133 134
	case REG_SSI_SACCEN:
	case REG_SSI_SACCDIS:
135 136 137 138 139 140 141 142 143
		return false;
	default:
		return true;
	}
}

static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
144 145 146 147 148 149 150 151 152 153 154 155
	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:
156 157 158 159 160 161
		return true;
	default:
		return false;
	}
}

162 163 164
static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
165 166 167 168 169 170
	case REG_SSI_SRX0:
	case REG_SSI_SRX1:
	case REG_SSI_SISR:
	case REG_SSI_SACADD:
	case REG_SSI_SACDAT:
	case REG_SSI_SATAG:
171 172 173 174 175 176
		return true;
	default:
		return false;
	}
}

177 178 179
static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
180 181 182
	case REG_SSI_SRX0:
	case REG_SSI_SRX1:
	case REG_SSI_SACCST:
183 184 185 186 187 188
		return false;
	default:
		return true;
	}
}

M
Markus Pargmann 已提交
189
static const struct regmap_config fsl_ssi_regconfig = {
190
	.max_register = REG_SSI_SACCDIS,
M
Markus Pargmann 已提交
191 192 193 194
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.val_format_endian = REGMAP_ENDIAN_NATIVE,
195
	.num_reg_defaults_raw = REG_SSI_SACCDIS / sizeof(uint32_t) + 1,
196 197
	.readable_reg = fsl_ssi_readable_reg,
	.volatile_reg = fsl_ssi_volatile_reg,
198
	.precious_reg = fsl_ssi_precious_reg,
199
	.writeable_reg = fsl_ssi_writeable_reg,
200
	.cache_type = REGCACHE_FLAT,
M
Markus Pargmann 已提交
201
};
202

203 204
struct fsl_ssi_soc_data {
	bool imx;
205
	bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
206 207 208 209
	bool offline_config;
	u32 sisr_write_mask;
};

210
/**
211
 * fsl_ssi: per-SSI private data
212
 *
N
Nicolin Chen 已提交
213
 * @regs: Pointer to the regmap registers
214
 * @irq: IRQ of this SSI
215 216 217
 * @cpu_dai_drv: CPU DAI driver for this device
 *
 * @dai_fmt: DAI configuration this device is currently used with
218
 * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
219
 * @i2s_net: I2S and Network mode configurations of SCR register
220
 * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
221
 * @use_dma: DMA is used or FIQ with stream filter
N
Nicolin Chen 已提交
222 223 224 225 226
 * @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
227
 * @regvals: Specific RX/TX register settings
228
 *
N
Nicolin Chen 已提交
229 230
 * @clk: Clock source to access register
 * @baudclk: Clock source to generate bit and frame-sync clocks
231 232
 * @baudclk_streams: Active streams that are using baudclk
 *
N
Nicolin Chen 已提交
233 234 235
 * @regcache_sfcsr: Cache sfcsr register value during suspend and resume
 * @regcache_sacnt: Cache sacnt register value during suspend and resume
 *
236 237 238 239 240 241
 * @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 已提交
242 243
 * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only)
 *        TODO: Should be replaced with simple-sound-card
244 245 246
 *
 * @dbg_stats: Debugging statistics
 *
247
 * @soc: SoC specific data
N
Nicolin Chen 已提交
248 249 250 251 252 253 254
 * @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.
255
 *
N
Nicolin Chen 已提交
256
 * @ac97_reg_lock: Mutex lock to serialize AC97 register access operations
257
 */
258
struct fsl_ssi {
M
Markus Pargmann 已提交
259
	struct regmap *regs;
260
	int irq;
261
	struct snd_soc_dai_driver cpu_dai_drv;
262

263
	unsigned int dai_fmt;
264
	u8 streams;
265
	u8 i2s_net;
266
	bool synchronous;
267
	bool use_dma;
268
	bool use_dual_fifo;
269
	bool has_ipg_clk_name;
270
	unsigned int fifo_depth;
271 272
	unsigned int slot_width;
	unsigned int slots;
273
	struct fsl_ssi_regvals regvals[2];
274

275
	struct clk *clk;
276
	struct clk *baudclk;
277
	unsigned int baudclk_streams;
278

279
	u32 regcache_sfcsr;
280
	u32 regcache_sacnt;
281

282 283
	struct snd_dmaengine_dai_dma_data dma_params_tx;
	struct snd_dmaengine_dai_dma_data dma_params_rx;
284 285
	dma_addr_t ssi_phys;

286
	struct imx_pcm_fiq_params fiq_params;
287 288

	struct platform_device *pdev;
289

290
	struct fsl_ssi_dbg dbg_stats;
291

292
	const struct fsl_ssi_soc_data *soc;
293
	struct device *dev;
294 295 296

	u32 fifo_watermark;
	u32 dma_maxburst;
297 298

	struct mutex ac97_reg_lock;
299
};
300 301

/*
N
Nicolin Chen 已提交
302
 * SoC specific data
303
 *
N
Nicolin Chen 已提交
304 305 306 307 308 309 310 311 312 313 314
 * 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.
315 316
 */

317 318 319
static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
	.imx = false,
	.offline_config = true,
320
	.sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
321 322
			   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
			   SSI_SISR_TUE0 | SSI_SISR_TUE1,
323 324 325 326
};

static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
	.imx = true,
327
	.imx21regs = true,
328 329 330 331 332 333 334
	.offline_config = true,
	.sisr_write_mask = 0,
};

static struct fsl_ssi_soc_data fsl_ssi_imx35 = {
	.imx = true,
	.offline_config = true,
335
	.sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
336 337
			   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
			   SSI_SISR_TUE0 | SSI_SISR_TUE1,
338 339 340 341 342
};

static struct fsl_ssi_soc_data fsl_ssi_imx51 = {
	.imx = true,
	.offline_config = false,
343
	.sisr_write_mask = SSI_SISR_ROE0 | SSI_SISR_ROE1 |
344
			   SSI_SISR_TUE0 | SSI_SISR_TUE1,
345 346 347 348 349 350 351 352 353 354 355
};

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

356
static bool fsl_ssi_is_ac97(struct fsl_ssi *ssi)
357
{
358
	return (ssi->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
359
		SND_SOC_DAIFMT_AC97;
360 361
}

362
static bool fsl_ssi_is_i2s_master(struct fsl_ssi *ssi)
363
{
364
	return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
365 366 367
		SND_SOC_DAIFMT_CBS_CFS;
}

368
static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi *ssi)
369
{
370
	return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
371 372
		SND_SOC_DAIFMT_CBM_CFS;
}
N
Nicolin Chen 已提交
373

374
/**
N
Nicolin Chen 已提交
375
 * Interrupt handler to gather states
376 377 378
 */
static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
{
379 380
	struct fsl_ssi *ssi = dev_id;
	struct regmap *regs = ssi->regs;
381
	__be32 sisr;
382
	__be32 sisr2;
383

384
	regmap_read(regs, REG_SSI_SISR, &sisr);
385

386
	sisr2 = sisr & ssi->soc->sisr_write_mask;
387 388
	/* Clear the bits that we set */
	if (sisr2)
389
		regmap_write(regs, REG_SSI_SISR, sisr2);
390

391
	fsl_ssi_dbg_isr(&ssi->dbg_stats, sisr);
392

393
	return IRQ_HANDLED;
394 395
}

N
Nicolin Chen 已提交
396
/**
397 398 399 400 401 402
 * 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
403
 */
404
static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx)
405
{
406
	struct fsl_ssi_regvals *vals = ssi->regvals;
407 408
	int dir = tx ? TX : RX;
	u32 sier, srcr, stcr;
409

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
	/* 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;
430
	} else {
431 432 433 434
		/* Otherwise, only set bits for the current stream */
		srcr = vals[dir].srcr;
		stcr = vals[dir].stcr;
		sier = vals[dir].sier;
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 462 463 464 465 466 467 468 469 470 471 472 473

	/* 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);
474 475
}

N
Nicolin Chen 已提交
476
/**
477
 * Exclude bits that are used by the opposite stream
478
 *
479 480
 * When both streams are active, disabling some bits for the current stream
 * might break the other stream if these bits are used by it.
481
 *
482 483 484
 * @vals : regvals of the current stream
 * @avals: regvals of the opposite stream
 * @aactive: active state of the opposite stream
485
 *
486 487 488
 *  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
489
 */
490 491 492 493 494
#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))
495

N
Nicolin Chen 已提交
496
/**
497 498 499 500 501 502
 * 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
503
 */
504
static void fsl_ssi_config_disable(struct fsl_ssi *ssi, bool tx)
505
{
506 507
	struct fsl_ssi_regvals *vals, *avals;
	u32 sier, srcr, stcr, scr;
508 509
	int adir = tx ? RX : TX;
	int dir = tx ? TX : RX;
510
	bool aactive;
M
Markus Pargmann 已提交
511

512 513
	/* Check if the opposite stream is active */
	aactive = ssi->streams & BIT(adir);
514

515
	vals = &ssi->regvals[dir];
516

517 518
	/* Get regvals of the opposite stream to keep opposite stream safe */
	avals = &ssi->regvals[adir];
519 520

	/*
521 522
	 * To keep the other stream safe, exclude shared bits between
	 * both streams, and get safe bits to disable current stream
523
	 */
524
	scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
525

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

529 530
	/* Log the disabled stream to the mask */
	ssi->streams &= ~BIT(dir);
531

532 533 534 535 536 537
	/*
	 * 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;
538

539 540 541 542 543 544
	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 {
545
		/*
N
Nicolin Chen 已提交
546 547
		 * To keep the other stream safe, exclude shared bits between
		 * both streams, and get safe bits to disable current stream
548
		 */
549 550 551
		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);
552 553
	}

554 555 556 557
	/* 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);
558

559 560 561 562
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));
563 564
}

565
static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
566
{
567
	struct regmap *regs = ssi->regs;
568 569

	/* no SACC{ST,EN,DIS} regs on imx21-class SSI */
570
	if (!ssi->soc->imx21regs) {
N
Nicolin Chen 已提交
571
		/* Disable all channel slots */
572
		regmap_write(regs, REG_SSI_SACCDIS, 0xff);
N
Nicolin Chen 已提交
573
		/* Enable slots 3 & 4 -- PCM Playback Left & Right channels */
574
		regmap_write(regs, REG_SSI_SACCEN, 0x300);
575 576 577
	}
}

N
Nicolin Chen 已提交
578 579
/**
 * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely
580
 */
581
static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
582
{
583
	struct fsl_ssi_regvals *vals = ssi->regvals;
584

585
	vals[RX].sier = SSI_SIER_RFF0_EN | FSLSSI_SIER_DBG_RX_FLAGS;
586
	vals[RX].srcr = SSI_SRCR_RFEN0;
587 588
	vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
	vals[TX].sier = SSI_SIER_TFE0_EN | FSLSSI_SIER_DBG_TX_FLAGS;
589
	vals[TX].stcr = SSI_STCR_TFEN0;
590
	vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
591

N
Nicolin Chen 已提交
592
	/* AC97 has already enabled SSIEN, RE and TE, so ignore them */
593 594
	if (fsl_ssi_is_ac97(ssi))
		vals[RX].scr = vals[TX].scr = 0;
595

596 597 598 599 600
	if (ssi->use_dual_fifo) {
		vals[RX].srcr |= SSI_SRCR_RFEN1;
		vals[TX].stcr |= SSI_STCR_TFEN1;
	}

601
	if (ssi->use_dma) {
602 603
		vals[RX].sier |= SSI_SIER_RDMAE;
		vals[TX].sier |= SSI_SIER_TDMAE;
604
	} else {
605 606
		vals[RX].sier |= SSI_SIER_RIE;
		vals[TX].sier |= SSI_SIER_TIE;
607 608 609
	}
}

610
static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi)
611
{
612
	struct regmap *regs = ssi->regs;
613

N
Nicolin Chen 已提交
614
	/* Setup the clock control register */
615 616
	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));
617

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

N
Nicolin Chen 已提交
621
	/* AC97 has to communicate with codec before starting a stream */
622
	regmap_update_bits(regs, REG_SSI_SCR,
623 624
			   SSI_SCR_SSIEN | SSI_SCR_TE | SSI_SCR_RE,
			   SSI_SCR_SSIEN | SSI_SCR_TE | SSI_SCR_RE);
625

626
	regmap_write(regs, REG_SSI_SOR, SSI_SOR_WAIT(3));
627 628
}

629 630
static int fsl_ssi_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
631 632
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
633
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
634 635
	int ret;

636
	ret = clk_prepare_enable(ssi->clk);
637 638
	if (ret)
		return ret;
639

N
Nicolin Chen 已提交
640 641
	/*
	 * When using dual fifo mode, it is safer to ensure an even period
642 643 644 645
	 * 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.
	 */
646
	if (ssi->use_dual_fifo)
647
		snd_pcm_hw_constraint_step(substream->runtime, 0,
648
					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
649

650 651 652
	return 0;
}

653
static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
654
			     struct snd_soc_dai *dai)
655 656
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
657
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
658

659
	clk_disable_unprepare(ssi->clk);
660 661
}

662
/**
N
Nicolin Chen 已提交
663
 * Configure Digital Audio Interface bit clock
664 665 666 667
 *
 * Note: This function can be only called when using SSI as DAI master
 *
 * Quick instruction for parameters:
668 669
 * freq: Output BCLK frequency = samplerate * slots * slot_width
 *       (In 2-channel I2S Master mode, slot_width is fixed 32)
670
 */
671
static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
672
			    struct snd_soc_dai *dai,
673
			    struct snd_pcm_hw_params *hw_params)
674
{
675
	bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
676
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
677
	struct regmap *regs = ssi->regs;
678
	u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
679
	unsigned long clkrate, baudrate, tmprate;
680 681
	unsigned int slots = params_channels(hw_params);
	unsigned int slot_width = 32;
682
	u64 sub, savesub = 100000;
683
	unsigned int freq;
684
	bool baudclk_is_used;
685
	int ret;
686

687
	/* Override slots and slot_width if being specifically set... */
688 689
	if (ssi->slots)
		slots = ssi->slots;
690
	/* ...but keep 32 bits if slots is 2 -- I2S Master mode */
691 692
	if (ssi->slot_width && slots != 2)
		slot_width = ssi->slot_width;
693 694 695

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

	/* Don't apply it to any non-baudclk circumstance */
698
	if (IS_ERR(ssi->baudclk))
699 700
		return -EINVAL;

701 702 703 704
	/*
	 * Hardware limitation: The bclk rate must be
	 * never greater than 1/5 IPG clock rate
	 */
705
	if (freq * 5 > clk_get_rate(ssi->clk)) {
706
		dev_err(dai->dev, "bitclk > ipgclk / 5\n");
707 708 709
		return -EINVAL;
	}

710
	baudclk_is_used = ssi->baudclk_streams & ~(BIT(substream->stream));
711

712 713 714 715 716 717 718
	/* 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++) {
719
		tmprate = freq * factor * (i + 1);
720 721

		if (baudclk_is_used)
722
			clkrate = clk_get_rate(ssi->baudclk);
723
		else
724
			clkrate = clk_round_rate(ssi->baudclk, tmprate);
725

726 727
		clkrate /= factor;
		afreq = clkrate / (i + 1);
728 729 730 731 732 733 734 735 736 737 738 739 740 741

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

742
		if (sub < savesub && !(i == 0 && psr == 0 && div2 == 0)) {
743 744 745 746 747 748 749 750 751 752 753 754
			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) {
755
		dev_err(dai->dev, "failed to handle the required sysclk\n");
756 757 758
		return -EINVAL;
	}

759 760
	stccr = SSI_SxCCR_PM(pm + 1) | (div2 ? SSI_SxCCR_DIV2 : 0) |
		(psr ? SSI_SxCCR_PSR : 0);
761
	mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR;
762

763
	/* STCCR is used for RX in synchronous mode */
764
	tx2 = tx || ssi->synchronous;
765
	regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr);
766

767
	if (!baudclk_is_used) {
768
		ret = clk_set_rate(ssi->baudclk, baudrate);
769
		if (ret) {
770
			dev_err(dai->dev, "failed to set baudclk rate\n");
771 772 773 774 775 776 777
			return -EINVAL;
		}
	}

	return 0;
}

778
/**
N
Nicolin Chen 已提交
779
 * Configure SSI based on PCM hardware parameters
780
 *
N
Nicolin Chen 已提交
781 782 783 784 785 786 787
 * 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.
788
 */
789
static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
790
			     struct snd_pcm_hw_params *hw_params,
791
			     struct snd_soc_dai *dai)
792
{
793
	bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
794
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
795
	struct regmap *regs = ssi->regs;
796
	unsigned int channels = params_channels(hw_params);
797
	unsigned int sample_size = params_width(hw_params);
798
	u32 wl = SSI_SxCCR_WL(sample_size);
799
	int ret;
800
	u32 scr;
M
Markus Pargmann 已提交
801 802
	int enabled;

803 804
	regmap_read(regs, REG_SSI_SCR, &scr);
	enabled = scr & SSI_SCR_SSIEN;
805

806
	/*
N
Nicolin Chen 已提交
807 808 809 810
	 * 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.
811
	 */
812
	if (enabled && ssi->synchronous)
813
		return 0;
814

815
	if (fsl_ssi_is_i2s_master(ssi)) {
816
		ret = fsl_ssi_set_bclk(substream, dai, hw_params);
817 818
		if (ret)
			return ret;
819 820

		/* Do not enable the clock if it is already enabled */
821 822
		if (!(ssi->baudclk_streams & BIT(substream->stream))) {
			ret = clk_prepare_enable(ssi->baudclk);
823 824 825
			if (ret)
				return ret;

826
			ssi->baudclk_streams |= BIT(substream->stream);
827
		}
828 829
	}

830
	if (!fsl_ssi_is_ac97(ssi)) {
N
Nicolin Chen 已提交
831
		/* Normal + Network mode to send 16-bit data in 32-bit frames */
832
		if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
833 834 835 836 837
			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;
838

839
		regmap_update_bits(regs, REG_SSI_SCR,
840
				   SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
841 842
	}

843
	/* In synchronous mode, the SSI uses STCCR for capture */
844
	tx2 = tx || ssi->synchronous;
845
	regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl);
846 847 848 849

	return 0;
}

850
static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
851
			   struct snd_soc_dai *dai)
852 853
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
854
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
855

856
	if (fsl_ssi_is_i2s_master(ssi) &&
857
	    ssi->baudclk_streams & BIT(substream->stream)) {
858 859
		clk_disable_unprepare(ssi->baudclk);
		ssi->baudclk_streams &= ~BIT(substream->stream);
860 861 862 863 864
	}

	return 0;
}

865
static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt)
866
{
867
	u32 strcr = 0, scr = 0, stcr, srcr, mask;
868

869
	ssi->dai_fmt = fmt;
870

N
Nicolin Chen 已提交
871
	/* Synchronize frame sync clock for TE to avoid data slipping */
872
	scr |= SSI_SCR_SYNC_TX_FS;
873

874 875
	/* Set to default shifting settings: LSB_ALIGNED */
	strcr |= SSI_STCR_TXBIT0;
876

N
Nicolin Chen 已提交
877
	/* Use Network mode as default */
878
	ssi->i2s_net = SSI_SCR_NET;
879 880 881 882
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
		case SND_SOC_DAIFMT_CBS_CFS:
883 884 885 886 887 888 889
			if (IS_ERR(ssi->baudclk)) {
				dev_err(ssi->dev,
					"missing baudclk for master mode\n");
				return -EINVAL;
			}
			/* fall through */
		case SND_SOC_DAIFMT_CBM_CFS:
890
			ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER;
891 892
			break;
		case SND_SOC_DAIFMT_CBM_CFM:
893
			ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE;
894 895 896 897 898
			break;
		default:
			return -EINVAL;
		}

899 900 901 902 903
		regmap_update_bits(ssi->regs, REG_SSI_STCCR,
				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
		regmap_update_bits(ssi->regs, REG_SSI_SRCCR,
				   SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));

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

927
	scr |= ssi->i2s_net;
928 929 930 931 932 933 934 935

	/* 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 */
936
		strcr ^= SSI_STCR_TSCKP;
937 938 939
		break;
	case SND_SOC_DAIFMT_NB_IF:
		/* Invert frame clock */
940
		strcr ^= SSI_STCR_TFSI;
941 942 943
		break;
	case SND_SOC_DAIFMT_IB_IF:
		/* Invert both clocks */
944 945
		strcr ^= SSI_STCR_TSCKP;
		strcr ^= SSI_STCR_TFSI;
946 947 948 949 950 951 952 953
		break;
	default:
		return -EINVAL;
	}

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

969 970
	stcr = strcr;
	srcr = strcr;
971

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

978 979 980 981 982 983 984 985 986
	mask = SSI_STCR_TFDIR | SSI_STCR_TXDIR | SSI_STCR_TSCKP |
	       SSI_STCR_TFSL | SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;

	regmap_update_bits(ssi->regs, REG_SSI_STCR, mask, stcr);
	regmap_update_bits(ssi->regs, REG_SSI_SRCR, mask, srcr);

	mask = SSI_SCR_SYNC_TX_FS | SSI_SCR_I2S_MODE_MASK |
	       SSI_SCR_SYS_CLK_EN | SSI_SCR_SYN;
	regmap_update_bits(ssi->regs, REG_SSI_SCR, mask, scr);
987 988

	return 0;
989 990 991
}

/**
N
Nicolin Chen 已提交
992
 * Configure Digital Audio Interface (DAI) Format
993
 */
994
static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
995
{
996
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
997

N
Nicolin Chen 已提交
998
	/* AC97 configured DAIFMT earlier in the probe() */
999
	if (fsl_ssi_is_ac97(ssi))
1000 1001
		return 0;

1002
	return _fsl_ssi_set_dai_fmt(ssi, fmt);
1003 1004 1005
}

/**
N
Nicolin Chen 已提交
1006
 * Set TDM slot number and slot width
1007
 */
1008
static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
1009
				    u32 rx_mask, int slots, int slot_width)
1010
{
1011
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
1012
	struct regmap *regs = ssi->regs;
1013 1014
	u32 val;

1015 1016
	/* The word length should be 8, 10, 12, 16, 18, 20, 22 or 24 */
	if (slot_width & 1 || slot_width < 8 || slot_width > 24) {
1017
		dev_err(dai->dev, "invalid slot width: %d\n", slot_width);
1018 1019 1020
		return -EINVAL;
	}

1021
	/* The slot number should be >= 2 if using Network mode or I2S mode */
1022
	if (ssi->i2s_net && slots < 2) {
1023
		dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n");
1024 1025 1026
		return -EINVAL;
	}

1027 1028 1029 1030
	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));
1031

1032
	/* Save the SCR register value */
1033
	regmap_read(regs, REG_SSI_SCR, &val);
N
Nicolin Chen 已提交
1034
	/* Temporarily enable SSI to allow SxMSKs to be configurable */
1035
	regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN);
1036

1037 1038
	regmap_write(regs, REG_SSI_STMSK, ~tx_mask);
	regmap_write(regs, REG_SSI_SRMSK, ~rx_mask);
1039

N
Nicolin Chen 已提交
1040
	/* Restore the value of SSIEN bit */
1041
	regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, val);
1042

1043 1044
	ssi->slot_width = slot_width;
	ssi->slots = slots;
1045

1046 1047 1048
	return 0;
}

1049
/**
N
Nicolin Chen 已提交
1050
 * Start or stop SSI and corresponding DMA transaction.
1051 1052 1053 1054
 *
 * The DMA channel is in external master start and pause mode, which
 * means the SSI completely controls the flow of data.
 */
1055 1056
static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
			   struct snd_soc_dai *dai)
1057 1058
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
1059
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
1060
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1061

1062 1063
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
1064
	case SNDRV_PCM_TRIGGER_RESUME:
1065
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
		/*
		 * 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);
1076 1077 1078
		break;

	case SNDRV_PCM_TRIGGER_STOP:
1079
	case SNDRV_PCM_TRIGGER_SUSPEND:
1080
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1081
		fsl_ssi_config_disable(ssi, tx);
1082 1083 1084 1085 1086 1087 1088 1089 1090
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

1091 1092
static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
{
1093
	struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
1094

1095 1096 1097
	if (ssi->soc->imx && ssi->use_dma)
		snd_soc_dai_init_dma_data(dai, &ssi->dma_params_tx,
					  &ssi->dma_params_rx);
1098 1099 1100 1101

	return 0;
}

1102
static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
1103 1104 1105 1106 1107 1108 1109
	.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,
1110 1111
};

1112
static struct snd_soc_dai_driver fsl_ssi_dai_template = {
1113
	.probe = fsl_ssi_dai_probe,
1114
	.playback = {
1115
		.stream_name = "CPU-Playback",
1116
		.channels_min = 1,
1117
		.channels_max = 32,
1118
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
1119 1120 1121
		.formats = FSLSSI_I2S_FORMATS,
	},
	.capture = {
1122
		.stream_name = "CPU-Capture",
1123
		.channels_min = 1,
1124
		.channels_max = 32,
1125
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
1126 1127
		.formats = FSLSSI_I2S_FORMATS,
	},
1128
	.ops = &fsl_ssi_dai_ops,
1129 1130
};

1131
static const struct snd_soc_component_driver fsl_ssi_component = {
1132
	.name = "fsl-ssi",
1133 1134
};

1135
static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
1136
	.bus_control = true,
1137
	.probe = fsl_ssi_dai_probe,
1138 1139 1140 1141 1142
	.playback = {
		.stream_name = "AC97 Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
1143
		.formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S20,
1144 1145 1146 1147 1148 1149
	},
	.capture = {
		.stream_name = "AC97 Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_48000,
1150 1151
		/* 16-bit capture is broken (errata ERR003778) */
		.formats = SNDRV_PCM_FMTBIT_S20,
1152
	},
1153
	.ops = &fsl_ssi_dai_ops,
1154 1155
};

1156
static struct fsl_ssi *fsl_ac97_data;
1157

1158
static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
1159
			       unsigned short val)
1160
{
M
Markus Pargmann 已提交
1161
	struct regmap *regs = fsl_ac97_data->regs;
1162 1163
	unsigned int lreg;
	unsigned int lval;
1164
	int ret;
1165 1166 1167 1168

	if (reg > 0x7f)
		return;

1169 1170
	mutex_lock(&fsl_ac97_data->ac97_reg_lock);

1171 1172 1173 1174
	ret = clk_prepare_enable(fsl_ac97_data->clk);
	if (ret) {
		pr_err("ac97 write clk_prepare_enable failed: %d\n",
			ret);
1175
		goto ret_unlock;
1176
	}
1177 1178

	lreg = reg <<  12;
1179
	regmap_write(regs, REG_SSI_SACADD, lreg);
1180 1181

	lval = val << 4;
1182
	regmap_write(regs, REG_SSI_SACDAT, lval);
1183

1184 1185
	regmap_update_bits(regs, REG_SSI_SACNT,
			   SSI_SACNT_RDWR_MASK, SSI_SACNT_WR);
1186
	udelay(100);
1187 1188

	clk_disable_unprepare(fsl_ac97_data->clk);
1189 1190 1191

ret_unlock:
	mutex_unlock(&fsl_ac97_data->ac97_reg_lock);
1192 1193
}

1194
static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
1195
					unsigned short reg)
1196
{
M
Markus Pargmann 已提交
1197
	struct regmap *regs = fsl_ac97_data->regs;
1198
	unsigned short val = 0;
M
Markus Pargmann 已提交
1199
	u32 reg_val;
1200
	unsigned int lreg;
1201 1202
	int ret;

1203 1204
	mutex_lock(&fsl_ac97_data->ac97_reg_lock);

1205 1206
	ret = clk_prepare_enable(fsl_ac97_data->clk);
	if (ret) {
1207
		pr_err("ac97 read clk_prepare_enable failed: %d\n", ret);
1208
		goto ret_unlock;
1209
	}
1210 1211

	lreg = (reg & 0x7f) <<  12;
1212
	regmap_write(regs, REG_SSI_SACADD, lreg);
1213 1214
	regmap_update_bits(regs, REG_SSI_SACNT,
			   SSI_SACNT_RDWR_MASK, SSI_SACNT_RD);
1215 1216 1217

	udelay(100);

1218
	regmap_read(regs, REG_SSI_SACDAT, &reg_val);
M
Markus Pargmann 已提交
1219
	val = (reg_val >> 4) & 0xffff;
1220

1221 1222
	clk_disable_unprepare(fsl_ac97_data->clk);

1223 1224
ret_unlock:
	mutex_unlock(&fsl_ac97_data->ac97_reg_lock);
1225 1226 1227 1228
	return val;
}

static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
1229 1230
	.read = fsl_ssi_ac97_read,
	.write = fsl_ssi_ac97_write,
1231 1232
};

1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
/**
 * Initialize SSI registers
 */
static int fsl_ssi_hw_init(struct fsl_ssi *ssi)
{
	u32 wm = ssi->fifo_watermark;

	/* Initialize regvals */
	fsl_ssi_setup_regvals(ssi);

	/* Set watermarks */
	regmap_write(ssi->regs, REG_SSI_SFCSR,
		     SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
		     SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));

	/* Enable Dual FIFO mode */
	if (ssi->use_dual_fifo)
		regmap_update_bits(ssi->regs, REG_SSI_SCR,
				   SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);

1253 1254
	/* AC97 should start earlier to communicate with CODECs */
	if (fsl_ssi_is_ac97(ssi)) {
1255
		_fsl_ssi_set_dai_fmt(ssi, ssi->dai_fmt);
1256 1257 1258
		fsl_ssi_setup_ac97(ssi);
	}

1259 1260 1261
	return 0;
}

1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279
/**
 * Clear SSI registers
 */
static void fsl_ssi_hw_clean(struct fsl_ssi *ssi)
{
	/* Disable registers for AC97 */
	if (fsl_ssi_is_ac97(ssi)) {
		/* Disable TE and RE bits first */
		regmap_update_bits(ssi->regs, REG_SSI_SCR,
				   SSI_SCR_TE | SSI_SCR_RE, 0);
		/* Disable AC97 mode */
		regmap_write(ssi->regs, REG_SSI_SACNT, 0);
		/* Unset WAIT bits */
		regmap_write(ssi->regs, REG_SSI_SOR, 0);
		/* Disable SSI -- software reset */
		regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0);
	}
}
1280
/**
1281
 * Make every character in a string lower-case
1282
 */
1283 1284
static void make_lowercase(char *s)
{
1285 1286 1287 1288
	if (!s)
		return;
	for (; *s; s++)
		*s = tolower(*s);
1289 1290
}

1291
static int fsl_ssi_imx_probe(struct platform_device *pdev,
1292
			     struct fsl_ssi *ssi, void __iomem *iomem)
1293 1294
{
	struct device_node *np = pdev->dev.of_node;
1295
	struct device *dev = &pdev->dev;
1296
	u32 dmas[4];
1297 1298
	int ret;

N
Nicolin Chen 已提交
1299
	/* Backward compatible for a DT without ipg clock name assigned */
1300
	if (ssi->has_ipg_clk_name)
1301
		ssi->clk = devm_clk_get(dev, "ipg");
1302
	else
1303
		ssi->clk = devm_clk_get(dev, NULL);
1304 1305
	if (IS_ERR(ssi->clk)) {
		ret = PTR_ERR(ssi->clk);
1306
		dev_err(dev, "failed to get clock: %d\n", ret);
1307 1308 1309
		return ret;
	}

N
Nicolin Chen 已提交
1310
	/* Enable the clock since regmap will not handle it in this case */
1311 1312
	if (!ssi->has_ipg_clk_name) {
		ret = clk_prepare_enable(ssi->clk);
1313
		if (ret) {
1314
			dev_err(dev, "clk_prepare_enable failed: %d\n", ret);
1315 1316
			return ret;
		}
1317 1318
	}

N
Nicolin Chen 已提交
1319
	/* Do not error out for slave cases that live without a baud clock */
1320
	ssi->baudclk = devm_clk_get(dev, "baud");
1321
	if (IS_ERR(ssi->baudclk))
1322
		dev_dbg(dev, "failed to get baud clock: %ld\n",
1323
			 PTR_ERR(ssi->baudclk));
1324

1325 1326
	ssi->dma_params_tx.maxburst = ssi->dma_maxburst;
	ssi->dma_params_rx.maxburst = ssi->dma_maxburst;
1327 1328
	ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0;
	ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0;
1329

N
Nicolin Chen 已提交
1330
	/* Set to dual FIFO mode according to the SDMA sciprt */
1331
	ret = of_property_read_u32_array(np, "dmas", dmas, 4);
1332 1333
	if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
		ssi->use_dual_fifo = true;
N
Nicolin Chen 已提交
1334 1335 1336
		/*
		 * Use even numbers to avoid channel swap due to SDMA
		 * script design
1337
		 */
1338 1339
		ssi->dma_params_tx.maxburst &= ~0x1;
		ssi->dma_params_rx.maxburst &= ~0x1;
1340 1341
	}

1342
	if (!ssi->use_dma) {
1343
		/*
N
Nicolin Chen 已提交
1344 1345
		 * Some boards use an incompatible codec. Use imx-fiq-pcm-audio
		 * to get it working, as DMA is not possible in this situation.
1346
		 */
1347 1348 1349 1350
		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;
1351

1352
		ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
1353 1354 1355
		if (ret)
			goto error_pcm;
	} else {
1356
		ret = imx_pcm_dma_init(pdev, IMX_SSI_DMABUF_SIZE);
1357 1358 1359 1360
		if (ret)
			goto error_pcm;
	}

1361
	return 0;
1362 1363

error_pcm:
1364 1365
	if (!ssi->has_ipg_clk_name)
		clk_disable_unprepare(ssi->clk);
1366

1367
	return ret;
1368 1369
}

1370
static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi)
1371
{
1372
	if (!ssi->use_dma)
1373
		imx_pcm_fiq_exit(pdev);
1374 1375
	if (!ssi->has_ipg_clk_name)
		clk_disable_unprepare(ssi->clk);
1376 1377
}

1378
static int fsl_ssi_probe(struct platform_device *pdev)
1379
{
1380
	struct fsl_ssi *ssi;
1381
	int ret = 0;
1382
	struct device_node *np = pdev->dev.of_node;
1383
	struct device *dev = &pdev->dev;
1384
	const struct of_device_id *of_id;
1385
	const char *p, *sprop;
1386
	const __be32 *iprop;
1387
	struct resource *res;
M
Markus Pargmann 已提交
1388
	void __iomem *iomem;
1389
	char name[64];
1390
	struct regmap_config regconfig = fsl_ssi_regconfig;
1391

1392
	of_id = of_match_device(fsl_ssi_ids, dev);
1393
	if (!of_id || !of_id->data)
1394 1395
		return -EINVAL;

1396
	ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
1397
	if (!ssi)
1398
		return -ENOMEM;
1399

1400
	ssi->soc = of_id->data;
1401
	ssi->dev = dev;
1402

N
Nicolin Chen 已提交
1403
	/* Check if being used in AC97 mode */
1404 1405 1406
	sprop = of_get_property(np, "fsl,mode", NULL);
	if (sprop) {
		if (!strcmp(sprop, "ac97-slave"))
1407
			ssi->dai_fmt = FSLSSI_AC97_DAIFMT;
1408 1409
	}

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

1413 1414
	if (fsl_ssi_is_ac97(ssi)) {
		memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai,
1415
		       sizeof(fsl_ssi_ac97_dai));
1416
		fsl_ac97_data = ssi;
1417
	} else {
1418
		memcpy(&ssi->cpu_dai_drv, &fsl_ssi_dai_template,
1419 1420
		       sizeof(fsl_ssi_dai_template));
	}
1421
	ssi->cpu_dai_drv.name = dev_name(dev);
1422

1423
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1424
	iomem = devm_ioremap_resource(dev, res);
1425 1426
	if (IS_ERR(iomem))
		return PTR_ERR(iomem);
1427
	ssi->ssi_phys = res->start;
M
Markus Pargmann 已提交
1428

1429
	if (ssi->soc->imx21regs) {
N
Nicolin Chen 已提交
1430
		/* No SACC{ST,EN,DIS} regs in imx21-class SSI */
1431
		regconfig.max_register = REG_SSI_SRMSK;
1432
		regconfig.num_reg_defaults_raw =
1433
			REG_SSI_SRMSK / sizeof(uint32_t) + 1;
1434 1435
	}

1436 1437
	ret = of_property_match_string(np, "clock-names", "ipg");
	if (ret < 0) {
1438
		ssi->has_ipg_clk_name = false;
1439
		ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig);
1440
	} else {
1441
		ssi->has_ipg_clk_name = true;
1442 1443
		ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem,
						      &regconfig);
1444
	}
1445
	if (IS_ERR(ssi->regs)) {
1446
		dev_err(dev, "failed to init register map\n");
1447
		return PTR_ERR(ssi->regs);
M
Markus Pargmann 已提交
1448
	}
1449

1450 1451
	ssi->irq = platform_get_irq(pdev, 0);
	if (ssi->irq < 0) {
1452
		dev_err(dev, "no irq for node %s\n", pdev->name);
1453
		return ssi->irq;
1454 1455
	}

N
Nicolin Chen 已提交
1456
	/* Set software limitations for synchronous mode */
1457
	if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
1458 1459 1460
		if (!fsl_ssi_is_ac97(ssi)) {
			ssi->cpu_dai_drv.symmetric_rates = 1;
			ssi->cpu_dai_drv.symmetric_samplebits = 1;
1461
			ssi->synchronous = true;
1462
		}
1463

1464
		ssi->cpu_dai_drv.symmetric_channels = 1;
1465
	}
1466

N
Nicolin Chen 已提交
1467
	/* Fetch FIFO depth; Set to 8 for older DT without this property */
1468 1469
	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
	if (iprop)
1470
		ssi->fifo_depth = be32_to_cpup(iprop);
1471
	else
1472
		ssi->fifo_depth = 8;
1473

1474
	/*
N
Nicolin Chen 已提交
1475
	 * Configure TX and RX DMA watermarks -- when to send a DMA request
1476
	 *
N
Nicolin Chen 已提交
1477 1478
	 * Values should be tested to avoid FIFO under/over run. Set maxburst
	 * to fifo_watermark to maxiumize DMA transaction to reduce overhead.
1479
	 */
1480
	switch (ssi->fifo_depth) {
1481 1482
	case 15:
		/*
N
Nicolin Chen 已提交
1483 1484 1485 1486 1487 1488
		 * 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
1489
		 */
1490 1491
		ssi->fifo_watermark = 8;
		ssi->dma_maxburst = 8;
1492 1493 1494
		break;
	case 8:
	default:
N
Nicolin Chen 已提交
1495
		/* Safely use old watermark configurations for older chips */
1496 1497
		ssi->fifo_watermark = ssi->fifo_depth - 2;
		ssi->dma_maxburst = ssi->fifo_depth - 2;
1498 1499 1500
		break;
	}

1501
	dev_set_drvdata(dev, ssi);
1502

1503 1504
	if (ssi->soc->imx) {
		ret = fsl_ssi_imx_probe(pdev, ssi, iomem);
1505
		if (ret)
F
Fabio Estevam 已提交
1506
			return ret;
1507 1508
	}

1509 1510
	if (fsl_ssi_is_ac97(ssi)) {
		mutex_init(&ssi->ac97_reg_lock);
1511 1512
		ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
		if (ret) {
1513
			dev_err(dev, "failed to set AC'97 ops\n");
1514 1515 1516 1517
			goto error_ac97_ops;
		}
	}

1518
	ret = devm_snd_soc_register_component(dev, &fsl_ssi_component,
1519
					      &ssi->cpu_dai_drv, 1);
1520
	if (ret) {
1521
		dev_err(dev, "failed to register DAI: %d\n", ret);
1522 1523 1524
		goto error_asoc_register;
	}

1525
	if (ssi->use_dma) {
1526 1527
		ret = devm_request_irq(dev, ssi->irq, fsl_ssi_isr, 0,
				       dev_name(dev), ssi);
1528
		if (ret < 0) {
1529
			dev_err(dev, "failed to claim irq %u\n", ssi->irq);
1530
			goto error_asoc_register;
1531
		}
1532 1533
	}

1534
	ret = fsl_ssi_debugfs_create(&ssi->dbg_stats, dev);
1535
	if (ret)
1536
		goto error_asoc_register;
1537

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

N
Nicolin Chen 已提交
1542 1543 1544 1545
	/*
	 * 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.
1546
	 */
1547 1548
	sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
	/* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
1549 1550 1551 1552 1553 1554
	p = strrchr(sprop, ',');
	if (p)
		sprop = p + 1;
	snprintf(name, sizeof(name), "snd-soc-%s", sprop);
	make_lowercase(name);

1555
	ssi->pdev = platform_device_register_data(dev, name, 0, NULL, 0);
1556 1557
	if (IS_ERR(ssi->pdev)) {
		ret = PTR_ERR(ssi->pdev);
1558
		dev_err(dev, "failed to register platform: %d\n", ret);
1559
		goto error_sound_card;
M
Mark Brown 已提交
1560
	}
1561

1562
done:
1563 1564 1565
	/* Initially configures SSI registers */
	fsl_ssi_hw_init(ssi);

1566
	if (fsl_ssi_is_ac97(ssi)) {
1567 1568 1569 1570
		u32 ssi_idx;

		ret = of_property_read_u32(np, "cell-index", &ssi_idx);
		if (ret) {
1571
			dev_err(dev, "failed to get SSI index property\n");
1572 1573 1574
			goto error_sound_card;
		}

1575 1576
		ssi->pdev = platform_device_register_data(NULL, "ac97-codec",
							  ssi_idx, NULL, 0);
1577 1578
		if (IS_ERR(ssi->pdev)) {
			ret = PTR_ERR(ssi->pdev);
1579
			dev_err(dev,
1580 1581 1582 1583 1584 1585
				"failed to register AC97 codec platform: %d\n",
				ret);
			goto error_sound_card;
		}
	}

1586
	return 0;
1587

1588
error_sound_card:
1589
	fsl_ssi_debugfs_remove(&ssi->dbg_stats);
1590
error_asoc_register:
1591
	if (fsl_ssi_is_ac97(ssi))
1592 1593
		snd_soc_set_ac97_ops(NULL);
error_ac97_ops:
1594 1595
	if (fsl_ssi_is_ac97(ssi))
		mutex_destroy(&ssi->ac97_reg_lock);
1596

1597 1598
	if (ssi->soc->imx)
		fsl_ssi_imx_clean(pdev, ssi);
1599

1600
	return ret;
1601 1602
}

1603
static int fsl_ssi_remove(struct platform_device *pdev)
1604
{
1605
	struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev);
1606

1607
	fsl_ssi_debugfs_remove(&ssi->dbg_stats);
1608

1609 1610
	if (ssi->pdev)
		platform_device_unregister(ssi->pdev);
1611

1612 1613 1614
	/* Clean up SSI registers */
	fsl_ssi_hw_clean(ssi);

1615 1616
	if (ssi->soc->imx)
		fsl_ssi_imx_clean(pdev, ssi);
1617

1618
	if (fsl_ssi_is_ac97(ssi)) {
1619
		snd_soc_set_ac97_ops(NULL);
1620
		mutex_destroy(&ssi->ac97_reg_lock);
1621
	}
1622

1623
	return 0;
1624
}
1625

1626 1627 1628
#ifdef CONFIG_PM_SLEEP
static int fsl_ssi_suspend(struct device *dev)
{
1629 1630
	struct fsl_ssi *ssi = dev_get_drvdata(dev);
	struct regmap *regs = ssi->regs;
1631

1632 1633
	regmap_read(regs, REG_SSI_SFCSR, &ssi->regcache_sfcsr);
	regmap_read(regs, REG_SSI_SACNT, &ssi->regcache_sacnt);
1634 1635 1636 1637 1638 1639 1640 1641 1642

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

	return 0;
}

static int fsl_ssi_resume(struct device *dev)
{
1643 1644
	struct fsl_ssi *ssi = dev_get_drvdata(dev);
	struct regmap *regs = ssi->regs;
1645 1646 1647

	regcache_cache_only(regs, false);

1648
	regmap_update_bits(regs, REG_SSI_SFCSR,
1649 1650 1651
			   SSI_SFCSR_RFWM1_MASK | SSI_SFCSR_TFWM1_MASK |
			   SSI_SFCSR_RFWM0_MASK | SSI_SFCSR_TFWM0_MASK,
			   ssi->regcache_sfcsr);
1652
	regmap_write(regs, REG_SSI_SACNT, ssi->regcache_sacnt);
1653 1654 1655 1656 1657 1658 1659 1660 1661

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

1662
static struct platform_driver fsl_ssi_driver = {
1663 1664 1665
	.driver = {
		.name = "fsl-ssi-dai",
		.of_match_table = fsl_ssi_ids,
1666
		.pm = &fsl_ssi_pm,
1667 1668 1669 1670
	},
	.probe = fsl_ssi_probe,
	.remove = fsl_ssi_remove,
};
1671

1672
module_platform_driver(fsl_ssi_driver);
1673

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