/*
 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
 *
 * Author: Timur Tabi <timur@freescale.com>
 *
 * Copyright 2007-2015, Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * 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.
 *
 *
 * 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.
 */

#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/busfreq-imx.h>

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

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

/**
 * 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
#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)
#else
#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)
#endif

#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
		CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
		CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
#define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \
		CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \
		CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)

enum fsl_ssi_type {
	FSL_SSI_MCP8610,
	FSL_SSI_MX21,
	FSL_SSI_MX35,
	FSL_SSI_MX51,
};

struct fsl_ssi_reg_val {
	u32 sier;
	u32 srcr;
	u32 stcr;
	u32 scr;
};

struct fsl_ssi_rxtx_reg_val {
	struct fsl_ssi_reg_val rx;
	struct fsl_ssi_reg_val tx;
};

static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CCSR_SSI_SACCEN:
	case CCSR_SSI_SACCDIS:
		return false;
	default:
		return true;
	}
}

static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CCSR_SSI_STX0:
	case CCSR_SSI_STX1:
	case CCSR_SSI_SRX0:
	case CCSR_SSI_SRX1:
	case CCSR_SSI_SISR:
	case CCSR_SSI_SFCSR:
	case CCSR_SSI_SACNT:
	case CCSR_SSI_SACADD:
	case CCSR_SSI_SACDAT:
	case CCSR_SSI_SATAG:
	case CCSR_SSI_SACCST:
	case CCSR_SSI_SOR:
		return true;
	default:
		return false;
	}
}

static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CCSR_SSI_SRX0:
	case CCSR_SSI_SRX1:
	case CCSR_SSI_SISR:
	case CCSR_SSI_SACADD:
	case CCSR_SSI_SACDAT:
	case CCSR_SSI_SATAG:
		return true;
	default:
		return false;
	}
}

static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case CCSR_SSI_SRX0:
	case CCSR_SSI_SRX1:
	case CCSR_SSI_SACCST:
		return false;
	default:
		return true;
	}
}

static const struct regmap_config fsl_ssi_regconfig = {
	.max_register = CCSR_SSI_SACCDIS,
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.val_format_endian = REGMAP_ENDIAN_NATIVE,
	.num_reg_defaults_raw = CCSR_SSI_SACCDIS / sizeof(uint32_t) + 1,
	.readable_reg = fsl_ssi_readable_reg,
	.volatile_reg = fsl_ssi_volatile_reg,
	.precious_reg = fsl_ssi_precious_reg,
	.writeable_reg = fsl_ssi_writeable_reg,
	.cache_type = REGCACHE_FLAT,
};

struct fsl_ssi_soc_data {
	bool imx;
	bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
	bool offline_config;
	u32 sisr_write_mask;
};

/**
 * fsl_ssi_private: per-SSI private data
 *
 * @reg: Pointer to the regmap registers
 * @irq: IRQ of this SSI
 * @cpu_dai_drv: CPU DAI driver for this device
 *
 * @dai_fmt: DAI configuration this device is currently used with
 * @i2s_mode: i2s and network mode configuration of the device. Is used to
 * switch between normal and i2s/network mode
 * mode depending on the number of channels
 * @use_dma: DMA is used or FIQ with stream filter
 * @use_dual_fifo: DMA with support for both FIFOs used
 * @fifo_deph: Depth of the SSI FIFOs
 * @rxtx_reg_val: Specific register settings for receive/transmit configuration
 *
 * @clk: SSI clock
 * @baudclk: SSI baud clock for master mode
 * @baudclk_streams: Active streams that are using baudclk
 * @bitclk_freq: bitclock frequency set by .set_dai_sysclk
 *
 * @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
 *
 * @pdev: Pointer to pdev used for deprecated fsl-ssi sound card
 *
 * @dbg_stats: Debugging statistics
 *
 * @soc: SoC specific data
 *
 * @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.
 */
struct fsl_ssi_private {
	struct regmap *regs;
	int irq;
	struct snd_soc_dai_driver cpu_dai_drv;

	unsigned int dai_fmt;
	u8 i2s_mode;
	bool use_dma;
	bool use_dual_fifo;
	bool use_dyna_fifo;
	bool has_ipg_clk_name;
	unsigned int fifo_depth;
	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;

	struct clk *clk;
	struct clk *baudclk;
	unsigned int baudclk_streams;
	unsigned int bitclk_freq;

	/* regcache for volatile regs */
	u32 regcache_sfcsr;
	u32 regcache_sacnt;

	/* DMA params */
	struct snd_dmaengine_dai_dma_data dma_params_tx;
	struct snd_dmaengine_dai_dma_data dma_params_rx;
	dma_addr_t ssi_phys;

	/* params for non-dma FIQ stream filtered mode */
	struct imx_pcm_fiq_params fiq_params;

	/* Used when using fsl-ssi as sound-card. This is only used by ppc and
	 * should be replaced with simple-sound-card. */
	struct platform_device *pdev;

	struct fsl_ssi_dbg dbg_stats;

	const struct fsl_ssi_soc_data *soc;
	struct device *dev;

	u32 fifo_watermark;
	u32 dma_maxburst;
};

/*
 * imx51 and later SoCs have a slightly different IP that allows the
 * SSI configuration while the SSI unit is running.
 *
 * More important, it is necessary on those SoCs to configure the
 * sperate TX/RX DMA bits just before starting the stream
 * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi
 * sends any DMA requests to the SDMA unit, otherwise it is not defined
 * how the SDMA unit handles the DMA request.
 *
 * SDMA units are present on devices starting at imx35 but the imx35
 * reference manual states that the DMA bits should not be changed
 * while the SSI unit is running (SSIEN). So we support the necessary
 * online configuration of fsl-ssi starting at imx51.
 */

static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
	.imx = false,
	.offline_config = true,
	.sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
			CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
			CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
};

static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
	.imx = true,
	.imx21regs = true,
	.offline_config = true,
	.sisr_write_mask = 0,
};

static struct fsl_ssi_soc_data fsl_ssi_imx35 = {
	.imx = true,
	.offline_config = true,
	.sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
			CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
			CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
};

static struct fsl_ssi_soc_data fsl_ssi_imx51 = {
	.imx = true,
	.offline_config = false,
	.sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
		CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
};

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

static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
{
	return (ssi_private->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
		SND_SOC_DAIFMT_AC97;
}

static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private)
{
	return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
		SND_SOC_DAIFMT_CBS_CFS;
}

static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi_private *ssi_private)
{
	return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
		SND_SOC_DAIFMT_CBM_CFS;
}
/**
 * fsl_ssi_isr: SSI interrupt handler
 *
 * Although it's possible to use the interrupt handler to send and receive
 * data to/from the SSI, we use the DMA instead.  Programming is more
 * complicated, but the performance is much better.
 *
 * This interrupt handler is used only to gather statistics.
 *
 * @irq: IRQ of the SSI device
 * @dev_id: pointer to the ssi_private structure for this SSI device
 */
static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
{
	struct fsl_ssi_private *ssi_private = dev_id;
	struct regmap *regs = ssi_private->regs;
	__be32 sisr;
	__be32 sisr2;

	/* We got an interrupt, so read the status register to see what we
	   were interrupted for.  We mask it with the Interrupt Enable register
	   so that we only check for events that we're interested in.
	 */
	regmap_read(regs, CCSR_SSI_SISR, &sisr);

	sisr2 = sisr & ssi_private->soc->sisr_write_mask;
	/* Clear the bits that we set */
	if (sisr2)
		regmap_write(regs, CCSR_SSI_SISR, sisr2);

	fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr);

	return IRQ_HANDLED;
}

/*
 * Enable/Disable all rx/tx config flags at once.
 */
static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
		bool enable)
{
	struct regmap *regs = ssi_private->regs;
	struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val;

	if (enable) {
		regmap_update_bits(regs, CCSR_SSI_SIER,
				vals->rx.sier | vals->tx.sier,
				vals->rx.sier | vals->tx.sier);
		regmap_update_bits(regs, CCSR_SSI_SRCR,
				vals->rx.srcr | vals->tx.srcr,
				vals->rx.srcr | vals->tx.srcr);
		regmap_update_bits(regs, CCSR_SSI_STCR,
				vals->rx.stcr | vals->tx.stcr,
				vals->rx.stcr | vals->tx.stcr);
	} else {
		regmap_update_bits(regs, CCSR_SSI_SRCR,
				vals->rx.srcr | vals->tx.srcr, 0);
		regmap_update_bits(regs, CCSR_SSI_STCR,
				vals->rx.stcr | vals->tx.stcr, 0);
		regmap_update_bits(regs, CCSR_SSI_SIER,
				vals->rx.sier | vals->tx.sier, 0);
	}
}

/*
 * Clear RX or TX FIFO to remove samples from the previous
 * stream session which may be still present in the FIFO and
 * may introduce bad samples and/or channel slipping.
 *
 * Note: The SOR is not documented in recent IMX datasheet, but
 * is described in IMX51 reference manual at section 56.3.3.15.
 */
static void fsl_ssi_fifo_clear(struct fsl_ssi_private *ssi_private,
		bool is_rx)
{
	if (is_rx) {
		regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR,
			CCSR_SSI_SOR_RX_CLR, CCSR_SSI_SOR_RX_CLR);
	} else {
		regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR,
			CCSR_SSI_SOR_TX_CLR, CCSR_SSI_SOR_TX_CLR);
	}
}

/*
 * Calculate the bits that have to be disabled for the current stream that is
 * getting disabled. This keeps the bits enabled that are necessary for the
 * second stream to work if 'stream_active' is true.
 *
 * Detailed calculation:
 * These are the values that need to be active after disabling. For non-active
 * second stream, this is 0:
 *	vals_stream * !!stream_active
 *
 * The following computes the overall differences between the setup for the
 * to-disable stream and the active stream, a simple XOR:
 *	vals_disable ^ (vals_stream * !!(stream_active))
 *
 * The full expression adds a mask on all values we care about
 */
#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \
	((vals_disable) & \
	 ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active))))

/*
 * Enable/Disable a ssi configuration. You have to pass either
 * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
 */
static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
		struct fsl_ssi_reg_val *vals)
{
	struct regmap *regs = ssi_private->regs;
	struct fsl_ssi_reg_val *avals;
	int nr_active_streams;
	u32 scr_val;
	int keep_active;

	regmap_read(regs, CCSR_SSI_SCR, &scr_val);

	nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
				!!(scr_val & CCSR_SSI_SCR_RE);

	if (nr_active_streams - 1 > 0)
		keep_active = 1;
	else
		keep_active = 0;

	/* Find the other direction values rx or tx which we do not want to
	 * modify */
	if (&ssi_private->rxtx_reg_val.rx == vals)
		avals = &ssi_private->rxtx_reg_val.tx;
	else
		avals = &ssi_private->rxtx_reg_val.rx;

	/* If vals should be disabled, start with disabling the unit */
	if (!enable) {
		u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr,
				keep_active);
		regmap_update_bits(regs, CCSR_SSI_SCR, scr, 0);
	}

	/*
	 * We are running on a SoC which does not support online SSI
	 * reconfiguration, so we have to enable all necessary flags at once
	 * even if we do not use them later (capture and playback configuration)
	 */
	if (ssi_private->soc->offline_config) {
		if ((enable && !nr_active_streams) ||
				(!enable && !keep_active))
			fsl_ssi_rxtx_config(ssi_private, enable);

		goto config_done;
	}

	/*
	 * Configure single direction units while the SSI unit is running
	 * (online configuration)
	 */
	if (enable) {
		fsl_ssi_fifo_clear(ssi_private, vals->scr & CCSR_SSI_SCR_RE);

		regmap_update_bits(regs, CCSR_SSI_SRCR, vals->srcr, vals->srcr);
		regmap_update_bits(regs, CCSR_SSI_STCR, vals->stcr, vals->stcr);
		regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier);
	} else {
		u32 sier;
		u32 srcr;
		u32 stcr;

		/*
		 * Disabling the necessary flags for one of rx/tx while the
		 * other stream is active is a little bit more difficult. We
		 * have to disable only those flags that differ between both
		 * streams (rx XOR tx) and that are set in the stream that is
		 * disabled now. Otherwise we could alter flags of the other
		 * stream
		 */

		/* These assignments are simply vals without bits set in avals*/
		sier = fsl_ssi_disable_val(vals->sier, avals->sier,
				keep_active);
		srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr,
				keep_active);
		stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr,
				keep_active);

		regmap_update_bits(regs, CCSR_SSI_SRCR, srcr, 0);
		regmap_update_bits(regs, CCSR_SSI_STCR, stcr, 0);
		regmap_update_bits(regs, CCSR_SSI_SIER, sier, 0);
	}

config_done:
	/* Enabling of subunits is done after configuration */
	if (enable) {
		if (ssi_private->use_dma && (vals->scr & CCSR_SSI_SCR_TE)) {
			/*
			 * Be sure the Tx FIFO is filled when TE is set.
			 * Otherwise, there are some chances to start the
			 * playback with some void samples inserted first,
			 * generating a channel slip.
			 *
			 * First, SSIEN must be set, to let the FIFO be filled.
			 *
			 * Notes:
			 * - Limit this fix to the DMA case until FIQ cases can
			 *   be tested.
			 * - Limit the length of the busy loop to not lock the
			 *   system too long, even if 1-2 loops are sufficient
			 *   in general.
			 */
			int i;
			int max_loop = 100;
			regmap_update_bits(regs, CCSR_SSI_SCR,
					CCSR_SSI_SCR_SSIEN, CCSR_SSI_SCR_SSIEN);
			for (i = 0; i < max_loop; i++) {
				u32 sfcsr;
				regmap_read(regs, CCSR_SSI_SFCSR, &sfcsr);
				if (CCSR_SSI_SFCSR_TFCNT0(sfcsr))
					break;
			}
			if (i == max_loop) {
				dev_err(ssi_private->dev,
					"Timeout waiting TX FIFO filling\n");
			}
		}
		regmap_update_bits(regs, CCSR_SSI_SCR, vals->scr, vals->scr);
	}
}


static void fsl_ssi_rx_config(struct fsl_ssi_private *ssi_private, bool enable)
{
	fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.rx);
}

static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable)
{
	fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx);
}

/*
 * Setup rx/tx register values used to enable/disable the streams. These will
 * be used later in fsl_ssi_config to setup the streams without the need to
 * check for all different SSI modes.
 */
static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
{
	struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;

	reg->rx.sier = CCSR_SSI_SIER_RFF0_EN;
	reg->rx.srcr = CCSR_SSI_SRCR_RFEN0;
	reg->rx.scr = 0;
	reg->tx.sier = CCSR_SSI_SIER_TFE0_EN;
	reg->tx.stcr = CCSR_SSI_STCR_TFEN0;
	reg->tx.scr = 0;

	if (!fsl_ssi_is_ac97(ssi_private)) {
		reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE;
		reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN;
		reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE;
		reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN;
	}

	if (ssi_private->use_dma) {
		reg->rx.sier |= CCSR_SSI_SIER_RDMAE;
		reg->tx.sier |= CCSR_SSI_SIER_TDMAE;
	} else {
		reg->rx.sier |= CCSR_SSI_SIER_RIE;
		reg->tx.sier |= CCSR_SSI_SIER_TIE;
	}

	reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS;
	reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS;
}

static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
{
	struct regmap *regs = ssi_private->regs;

	/*
	 * Setup the clock control register
	 */
	regmap_write(regs, CCSR_SSI_STCCR,
			CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13));
	regmap_write(regs, CCSR_SSI_SRCCR,
			CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13));

	/*
	 * Enable AC97 mode and startup the SSI
	 */
	regmap_write(regs, CCSR_SSI_SACNT,
			CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV);

	/* no SACC{ST,EN,DIS} regs on imx21-class SSI */
	if (!ssi_private->soc->imx21regs) {
		regmap_write(regs, CCSR_SSI_SACCDIS, 0xff);
		regmap_write(regs, CCSR_SSI_SACCEN, 0x300);
	}

	/*
	 * Enable SSI, Transmit and Receive. AC97 has to communicate with the
	 * codec before a stream is started.
	 */
	regmap_update_bits(regs, CCSR_SSI_SCR,
			CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE,
			CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);

	regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_WAIT(3));
}

/**
 * fsl_ssi_startup: create a new substream
 *
 * This is the first function called when a stream is opened.
 *
 * If this is the first stream open, then grab the IRQ and program most of
 * the SSI registers.
 */
static int fsl_ssi_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct fsl_ssi_private *ssi_private =
		snd_soc_dai_get_drvdata(rtd->cpu_dai);
	int ret;

	ret = clk_prepare_enable(ssi_private->clk);
	if (ret)
		return ret;

	pm_runtime_get_sync(dai->dev);

	/* When using dual fifo mode, it is safer to ensure an even period
	 * 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.
	 */
	if (ssi_private->use_dual_fifo || ssi_private->use_dyna_fifo)
		snd_pcm_hw_constraint_step(substream->runtime, 0,
				SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);

	return 0;
}

/**
 * fsl_ssi_shutdown: shutdown the SSI
 *
 */
static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct fsl_ssi_private *ssi_private =
		snd_soc_dai_get_drvdata(rtd->cpu_dai);

	pm_runtime_put_sync(dai->dev);

	clk_disable_unprepare(ssi_private->clk);

}

/**
 * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock
 *
 * Note: This function can be only called when using SSI as DAI master
 *
 * Quick instruction for parameters:
 * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels
 * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK.
 */
static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
		struct snd_soc_dai *cpu_dai,
		struct snd_pcm_hw_params *hw_params)
{
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
	struct regmap *regs = ssi_private->regs;
	int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret;
	u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
	unsigned long clkrate, baudrate, tmprate;
	u64 sub, savesub = 100000;
	unsigned int freq;
	bool baudclk_is_used;

	/* Prefer the explicitly set bitclock frequency */
	if (ssi_private->bitclk_freq)
		freq = ssi_private->bitclk_freq;
	else {
		if (params_channels(hw_params) == 1)
			freq = 2 * params_width(hw_params) *
					params_rate(hw_params);
		else
			freq = params_channels(hw_params) * 32 *
					params_rate(hw_params);
	}

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

	/*
	 * Hardware limitation: The bclk rate must be
	 * never greater than 1/5 IPG clock rate
	 */
	if (freq * 5 > clk_get_rate(ssi_private->clk)) {
		dev_err(cpu_dai->dev, "bitclk > ipgclk/5\n");
		return -EINVAL;
	}

	baudclk_is_used = ssi_private->baudclk_streams & ~(BIT(substream->stream));

	/* 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++) {
		tmprate = freq * factor * (i + 1);

		if (baudclk_is_used)
			clkrate = clk_get_rate(ssi_private->baudclk);
		else
			clkrate = clk_round_rate(ssi_private->baudclk, tmprate);

		clkrate /= factor;
		afreq = clkrate / (i + 1);

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

		if (sub < savesub && !(i == 0 && psr == 0 && div2 == 0)) {
			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) {
		dev_err(cpu_dai->dev, "failed to handle the required sysclk\n");
		return -EINVAL;
	}

	stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) |
		(psr ? CCSR_SSI_SxCCR_PSR : 0);
	mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 |
		CCSR_SSI_SxCCR_PSR;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous)
		regmap_update_bits(regs, CCSR_SSI_STCCR, mask, stccr);
	else
		regmap_update_bits(regs, CCSR_SSI_SRCCR, mask, stccr);

	if (!baudclk_is_used) {
		ret = clk_set_rate(ssi_private->baudclk, baudrate);
		if (ret) {
			dev_err(cpu_dai->dev, "failed to set baudclk rate\n");
			return -EINVAL;
		}
	}

	return 0;
}

static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
		int clk_id, unsigned int freq, int dir)
{
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);

	ssi_private->bitclk_freq = freq;

	return 0;
}

/**
 * fsl_ssi_hw_params - program the sample size
 *
 * Most of the SSI registers have been programmed in the startup function,
 * but the word length must be programmed here.  Unfortunately, programming
 * the SxCCR.WL bits requires the SSI to be temporarily disabled.  This can
 * cause a problem with supporting simultaneous playback and capture.  If
 * the SSI is already playing a stream, then that stream may be temporarily
 * stopped when you start capture.
 *
 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
 * clock master.
 */
static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
{
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
	struct regmap *regs = ssi_private->regs;
	unsigned int channels = params_channels(hw_params);
	unsigned int sample_size = params_width(hw_params);
	u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
	int ret;
	u32 scr_val;
	int enabled;
	u8 i2smode = ssi_private->i2s_mode;
	struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;

	if (fsl_ssi_is_i2s_master(ssi_private)) {
		ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params);
		if (ret)
			return ret;

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

			ssi_private->baudclk_streams |= BIT(substream->stream);
		}
	}

	regmap_read(regs, CCSR_SSI_SCR, &scr_val);
	enabled = scr_val & CCSR_SSI_SCR_SSIEN;

	/*
	 * If we're in synchronous mode, and the SSI is already enabled,
	 * then STCCR is already set properly.
	 */
	if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
		return 0;

	if (!fsl_ssi_is_ac97(ssi_private)) {
		/*
		 * Switch to normal net mode in order to have a frame sync
		 * signal every 32 bits instead of 16 bits
		 */
		if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16)
			i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL |
				CCSR_SSI_SCR_NET;
		if (channels == 1)
			i2smode = 0;
	}

	regmap_update_bits(regs, CCSR_SSI_SCR,
			   CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
			   i2smode);

	/*
	 * FIXME: The documentation says that SxCCR[WL] should not be
	 * modified while the SSI is enabled.  The only time this can
	 * happen is if we're trying to do simultaneous playback and
	 * capture in asynchronous mode.  Unfortunately, I have been enable
	 * to get that to work at all on the P1022DS.  Therefore, we don't
	 * bother to disable/enable the SSI when setting SxCCR[WL], because
	 * the SSI will stop anyway.  Maybe one day, this will get fixed.
	 */

	/* In synchronous mode, the SSI uses STCCR for capture */
	if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
	    ssi_private->cpu_dai_drv.symmetric_rates)
		regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_WL_MASK,
				wl);
	else
		regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK,
				wl);

	if (ssi_private->use_dyna_fifo) {
		if (channels == 1) {
			ssi_private->dma_params_tx.fifo_num  = 1;
			ssi_private->dma_params_rx.fifo_num  = 1;
			reg->rx.srcr &= ~CCSR_SSI_SRCR_RFEN1;
			reg->tx.stcr &= ~CCSR_SSI_STCR_TFEN1;
			reg->rx.scr  &= ~CCSR_SSI_SCR_TCH_EN;
			reg->tx.scr  &= ~CCSR_SSI_SCR_TCH_EN;
		} else {
			ssi_private->dma_params_tx.fifo_num  = 2;
			ssi_private->dma_params_rx.fifo_num  = 2;
			reg->rx.srcr |= CCSR_SSI_SRCR_RFEN1;
			reg->tx.stcr |= CCSR_SSI_STCR_TFEN1;
			reg->rx.scr  |= CCSR_SSI_SCR_TCH_EN;
			reg->tx.scr  |= CCSR_SSI_SCR_TCH_EN;
		}
	}

	return 0;
}

static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
		struct snd_soc_dai *cpu_dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct fsl_ssi_private *ssi_private =
		snd_soc_dai_get_drvdata(rtd->cpu_dai);

	if (fsl_ssi_is_i2s_master(ssi_private) &&
			ssi_private->baudclk_streams & BIT(substream->stream)) {
		clk_disable_unprepare(ssi_private->baudclk);
		ssi_private->baudclk_streams &= ~BIT(substream->stream);
	}

	return 0;
}

static int _fsl_ssi_set_dai_fmt(struct device *dev,
				struct fsl_ssi_private *ssi_private,
				unsigned int fmt)
{
	struct regmap *regs = ssi_private->regs;
	u32 strcr = 0, stcr, srcr, scr, mask;
	u8 wm;

	ssi_private->dai_fmt = fmt;

	if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk)) {
		dev_err(dev, "baudclk is missing which is necessary for master mode\n");
		return -EINVAL;
	}

	fsl_ssi_setup_reg_vals(ssi_private);

	regmap_read(regs, CCSR_SSI_SCR, &scr);
	scr &= ~CCSR_SSI_SCR_SYN;
	scr |= CCSR_SSI_SCR_SYNC_TX_FS;

	mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
		CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL |
		CCSR_SSI_STCR_TEFS;
	regmap_read(regs, CCSR_SSI_STCR, &stcr);
	regmap_read(regs, CCSR_SSI_SRCR, &srcr);
	stcr &= ~mask;
	srcr &= ~mask;

	ssi_private->i2s_mode = CCSR_SSI_SCR_NET;
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		regmap_update_bits(regs, CCSR_SSI_STCCR,
				   CCSR_SSI_SxCCR_DC_MASK,
				   CCSR_SSI_SxCCR_DC(2));
		regmap_update_bits(regs, CCSR_SSI_SRCCR,
				   CCSR_SSI_SxCCR_DC_MASK,
				   CCSR_SSI_SxCCR_DC(2));
		switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
		case SND_SOC_DAIFMT_CBM_CFS:
		case SND_SOC_DAIFMT_CBS_CFS:
			ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER;
			break;
		case SND_SOC_DAIFMT_CBM_CFM:
			ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE;
			break;
		default:
			return -EINVAL;
		}

		/* Data on rising edge of bclk, frame low, 1clk before data */
		strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP |
			CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		/* Data on rising edge of bclk, frame high */
		strcr |= CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TSCKP;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		/* Data on rising edge of bclk, frame high, 1clk before data */
		strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
			CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		/* Data on rising edge of bclk, frame high */
		strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
			CCSR_SSI_STCR_TXBIT0;
		break;
	case SND_SOC_DAIFMT_AC97:
		ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL;
		break;
	default:
		return -EINVAL;
	}

	/* 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 */
		strcr ^= CCSR_SSI_STCR_TSCKP;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		/* Invert frame clock */
		strcr ^= CCSR_SSI_STCR_TFSI;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		/* Invert both clocks */
		strcr ^= CCSR_SSI_STCR_TSCKP;
		strcr ^= CCSR_SSI_STCR_TFSI;
		break;
	default:
		return -EINVAL;
	}

	/* DAI clock master masks */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		strcr |= CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR;
		scr |= CCSR_SSI_SCR_SYS_CLK_EN;
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
		scr &= ~CCSR_SSI_SCR_SYS_CLK_EN;
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		strcr &= ~CCSR_SSI_STCR_TXDIR;
		strcr |= CCSR_SSI_STCR_TFDIR;
		scr &= ~CCSR_SSI_SCR_SYS_CLK_EN;
		break;
	default:
		if (!fsl_ssi_is_ac97(ssi_private))
			return -EINVAL;
	}

	stcr |= strcr;
	srcr |= strcr;

	if (ssi_private->cpu_dai_drv.symmetric_rates
			|| fsl_ssi_is_ac97(ssi_private)) {
		/* Need to clear RXDIR when using SYNC or AC97 mode */
		srcr &= ~CCSR_SSI_SRCR_RXDIR;
		scr |= CCSR_SSI_SCR_SYN;
	}

	regmap_write(regs, CCSR_SSI_STCR, stcr);
	regmap_write(regs, CCSR_SSI_SRCR, srcr);
	regmap_write(regs, CCSR_SSI_SCR, scr);

	wm = ssi_private->fifo_watermark;

	regmap_write(regs, CCSR_SSI_SFCSR,
			CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
			CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm));

	if (ssi_private->use_dual_fifo) {
		regmap_update_bits(regs, CCSR_SSI_SRCR, CCSR_SSI_SRCR_RFEN1,
				CCSR_SSI_SRCR_RFEN1);
		regmap_update_bits(regs, CCSR_SSI_STCR, CCSR_SSI_STCR_TFEN1,
				CCSR_SSI_STCR_TFEN1);
		regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_TCH_EN,
				CCSR_SSI_SCR_TCH_EN);
	}

	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
		fsl_ssi_setup_ac97(ssi_private);

	return 0;

}

/**
 * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format.
 */
static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);

	return _fsl_ssi_set_dai_fmt(cpu_dai->dev, ssi_private, fmt);
}

/**
 * fsl_ssi_set_dai_tdm_slot - set TDM slot number
 *
 * Note: This function can be only called when using SSI as DAI master
 */
static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
				u32 rx_mask, int slots, int slot_width)
{
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
	struct regmap *regs = ssi_private->regs;
	u32 val;

	/* The slot number should be >= 2 if using Network mode or I2S mode */
	regmap_read(regs, CCSR_SSI_SCR, &val);
	val &= CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET;
	if (val && slots < 2) {
		dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n");
		return -EINVAL;
	}

	regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_DC_MASK,
			CCSR_SSI_SxCCR_DC(slots));
	regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_DC_MASK,
			CCSR_SSI_SxCCR_DC(slots));

	/* The register SxMSKs needs SSI to provide essential clock due to
	 * hardware design. So we here temporarily enable SSI to set them.
	 */
	regmap_read(regs, CCSR_SSI_SCR, &val);
	val &= CCSR_SSI_SCR_SSIEN;
	regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN,
			CCSR_SSI_SCR_SSIEN);

	regmap_write(regs, CCSR_SSI_STMSK, ~tx_mask);
	regmap_write(regs, CCSR_SSI_SRMSK, ~rx_mask);

	regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val);

	return 0;
}

/**
 * fsl_ssi_trigger: start and stop the DMA transfer.
 *
 * This function is called by ALSA to start, stop, pause, and resume the DMA
 * transfer of data.
 *
 * The DMA channel is in external master start and pause mode, which
 * means the SSI completely controls the flow of data.
 */
static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
			   struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
	struct regmap *regs = ssi_private->regs;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			fsl_ssi_tx_config(ssi_private, true);
		else
			fsl_ssi_rx_config(ssi_private, true);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			fsl_ssi_tx_config(ssi_private, false);
		else
			fsl_ssi_rx_config(ssi_private, false);
		break;

	default:
		return -EINVAL;
	}

	if (fsl_ssi_is_ac97(ssi_private)) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_TX_CLR);
		else
			regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_RX_CLR);
	}

	return 0;
}

static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
{
	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);

	if (ssi_private->soc->imx && ssi_private->use_dma) {
		dai->playback_dma_data = &ssi_private->dma_params_tx;
		dai->capture_dma_data = &ssi_private->dma_params_rx;
	}

	return 0;
}

static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
	.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_sysclk	= fsl_ssi_set_dai_sysclk,
	.set_tdm_slot	= fsl_ssi_set_dai_tdm_slot,
	.trigger	= fsl_ssi_trigger,
};

/* Template for the CPU dai driver structure */
static struct snd_soc_dai_driver fsl_ssi_dai_template = {
	.probe = fsl_ssi_dai_probe,
	.playback = {
		.stream_name = "CPU-Playback",
		.channels_min = 1,
		.channels_max = 32,
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
		.formats = FSLSSI_I2S_FORMATS,
	},
	.capture = {
		.stream_name = "CPU-Capture",
		.channels_min = 1,
		.channels_max = 32,
		.rates = SNDRV_PCM_RATE_CONTINUOUS,
		.formats = FSLSSI_I2S_FORMATS,
	},
	.ops = &fsl_ssi_dai_ops,
};

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

static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
	.bus_control = true,
	.probe = fsl_ssi_dai_probe,
	.playback = {
		.stream_name = "AC97 Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,
	},
	.capture = {
		.stream_name = "AC97 Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,
	},
	.ops = &fsl_ssi_dai_ops,
};


static struct fsl_ssi_private *fsl_ac97_data;

static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
		unsigned short val)
{
	struct regmap *regs = fsl_ac97_data->regs;
	unsigned int lreg;
	unsigned int lval;
	int ret;

	if (reg > 0x7f)
		return;

	ret = clk_prepare_enable(fsl_ac97_data->clk);
	if (ret) {
		pr_err("ac97 write clk_prepare_enable failed: %d\n",
			ret);
		return;
	}

	lreg = reg <<  12;
	regmap_write(regs, CCSR_SSI_SACADD, lreg);

	lval = val << 4;
	regmap_write(regs, CCSR_SSI_SACDAT, lval);

	regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK,
			CCSR_SSI_SACNT_WR);
	udelay(100);

	clk_disable_unprepare(fsl_ac97_data->clk);
}

static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
		unsigned short reg)
{
	struct regmap *regs = fsl_ac97_data->regs;

	unsigned short val = -1;
	u32 reg_val;
	unsigned int lreg;
	int ret;

	ret = clk_prepare_enable(fsl_ac97_data->clk);
	if (ret) {
		pr_err("ac97 read clk_prepare_enable failed: %d\n",
			ret);
		return -1;
	}

	lreg = (reg & 0x7f) <<  12;
	regmap_write(regs, CCSR_SSI_SACADD, lreg);
	regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK,
			CCSR_SSI_SACNT_RD);

	udelay(100);

	regmap_read(regs, CCSR_SSI_SACDAT, &reg_val);
	val = (reg_val >> 4) & 0xffff;

	clk_disable_unprepare(fsl_ac97_data->clk);

	return val;
}

static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
	.read		= fsl_ssi_ac97_read,
	.write		= fsl_ssi_ac97_write,
};

/**
 * Make every character in a string lower-case
 */
static void make_lowercase(char *s)
{
	if (!s)
		return;
	for (; *s; s++)
		*s = tolower(*s);
}

static int fsl_ssi_imx_probe(struct platform_device *pdev,
		struct fsl_ssi_private *ssi_private, void __iomem *iomem)
{
	struct device_node *np = pdev->dev.of_node;
	u32 dmas[4];
	int ret;
	u32 buffer_size;

	if (ssi_private->has_ipg_clk_name)
		ssi_private->clk = devm_clk_get(&pdev->dev, "ipg");
	else
		ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(ssi_private->clk)) {
		ret = PTR_ERR(ssi_private->clk);
		dev_err(&pdev->dev, "could not get clock: %d\n", ret);
		return ret;
	}

	if (!ssi_private->has_ipg_clk_name) {
		ret = clk_prepare_enable(ssi_private->clk);
		if (ret) {
			dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
			return ret;
		}
	}

	/* For those SLAVE implementations, we ignore non-baudclk cases
	 * and, instead, abandon MASTER mode that needs baud clock.
	 */
	ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
	if (IS_ERR(ssi_private->baudclk))
		dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
			 PTR_ERR(ssi_private->baudclk));

	ssi_private->dma_params_rx.chan_name = "rx";
	ssi_private->dma_params_tx.chan_name = "tx";
	ssi_private->dma_params_tx.maxburst = ssi_private->dma_maxburst;
	ssi_private->dma_params_rx.maxburst = ssi_private->dma_maxburst;
	ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
	ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0;

	ret = of_property_read_u32_array(np, "dmas", dmas, 4);
	if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
		ssi_private->use_dual_fifo = true;
		/* When using dual fifo mode, we need to keep watermark
		 * as even numbers due to dma script limitation.
		 */
		ssi_private->dma_params_tx.maxburst &= ~0x1;
		ssi_private->dma_params_rx.maxburst &= ~0x1;
	}

	if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)
		ssi_private->use_dyna_fifo = true;

	if (of_property_read_u32(np, "fsl,dma-buffer-size", &buffer_size))
		buffer_size = IMX_SSI_DMABUF_SIZE;

	if (!ssi_private->use_dma) {

		/*
		 * Some boards use an incompatible codec. To get it
		 * working, we are using imx-fiq-pcm-audio, that
		 * can handle those codecs. DMA is not possible in this
		 * situation.
		 */

		ssi_private->fiq_params.irq = ssi_private->irq;
		ssi_private->fiq_params.base = iomem;
		ssi_private->fiq_params.dma_params_rx =
			&ssi_private->dma_params_rx;
		ssi_private->fiq_params.dma_params_tx =
			&ssi_private->dma_params_tx;

		ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
		if (ret)
			goto error_pcm;
	} else {
		ret = imx_pcm_platform_register(&pdev->dev);
		if (ret)
			goto error_pcm;
	}

	return 0;

error_pcm:

	if (!ssi_private->has_ipg_clk_name)
		clk_disable_unprepare(ssi_private->clk);
	return ret;
}

static void fsl_ssi_imx_clean(struct platform_device *pdev,
		struct fsl_ssi_private *ssi_private)
{
	if (!ssi_private->use_dma)
		imx_pcm_fiq_exit(pdev);
	if (!ssi_private->has_ipg_clk_name)
		clk_disable_unprepare(ssi_private->clk);
}

static int fsl_ssi_probe(struct platform_device *pdev)
{
	struct fsl_ssi_private *ssi_private;
	int ret = 0;
	struct device_node *np = pdev->dev.of_node;
	const struct of_device_id *of_id;
	const char *p, *sprop;
	const uint32_t *iprop;
	struct resource *res;
	void __iomem *iomem;
	char name[64];
	struct regmap_config regconfig = fsl_ssi_regconfig;

	of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
	if (!of_id || !of_id->data)
		return -EINVAL;

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

	ssi_private->soc = of_id->data;
	ssi_private->dev = &pdev->dev;

	sprop = of_get_property(np, "fsl,mode", NULL);
	if (sprop) {
		if (!strcmp(sprop, "ac97-slave"))
			ssi_private->dai_fmt = SND_SOC_DAIFMT_AC97;
	}

	ssi_private->use_dma = !of_property_read_bool(np,
			"fsl,fiq-stream-filter");

	if (fsl_ssi_is_ac97(ssi_private)) {
		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
				sizeof(fsl_ssi_ac97_dai));

		fsl_ac97_data = ssi_private;
	} else {
		/* Initialize this copy of the CPU DAI driver structure */
		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
		       sizeof(fsl_ssi_dai_template));
	}
	ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	iomem = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(iomem))
		return PTR_ERR(iomem);
	ssi_private->ssi_phys = res->start;

	if (ssi_private->soc->imx21regs) {
		/*
		 * According to datasheet imx21-class SSI
		 * don't have SACC{ST,EN,DIS} regs.
		 */
		regconfig.max_register = CCSR_SSI_SRMSK;
		regconfig.num_reg_defaults_raw =
			CCSR_SSI_SRMSK / sizeof(uint32_t) + 1;
	}

	ret = of_property_match_string(np, "clock-names", "ipg");
	if (ret < 0) {
		ssi_private->has_ipg_clk_name = false;
		ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
			&regconfig);
	} else {
		ssi_private->has_ipg_clk_name = true;
		ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev,
			"ipg", iomem, &regconfig);
	}
	if (IS_ERR(ssi_private->regs)) {
		dev_err(&pdev->dev, "Failed to init register map\n");
		return PTR_ERR(ssi_private->regs);
	}

	ssi_private->irq = platform_get_irq(pdev, 0);
	if (ssi_private->irq < 0) {
		dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
		return ssi_private->irq;
	}

	/* Are the RX and the TX clocks locked? */
	if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
		if (!fsl_ssi_is_ac97(ssi_private))
			ssi_private->cpu_dai_drv.symmetric_rates = 1;

		ssi_private->cpu_dai_drv.symmetric_channels = 1;
		ssi_private->cpu_dai_drv.symmetric_samplebits = 1;
	}

	/* Determine the FIFO depth. */
	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
	if (iprop)
		ssi_private->fifo_depth = be32_to_cpup(iprop);
	else
                /* Older 8610 DTs didn't have the fifo-depth property */
		ssi_private->fifo_depth = 8;

	/*
	 * Set the watermark for transmit FIFO 0 and receive FIFO 0. We don't
	 * use FIFO 1 but set the watermark appropriately nontheless.
	 * We program the transmit water to signal a DMA transfer
	 * if there are N elements left in the FIFO. For chips with 15-deep
	 * FIFOs, set watermark to 8.  This allows the SSI to operate at a
	 * high data rate without channel slipping. Behavior is unchanged
	 * for the older chips with a fifo depth of only 8.  A value of 4
	 * might be appropriate for the older chips, but is left at
	 * fifo_depth-2 until sombody has a chance to test.
	 *
	 * We set the watermark on the same level as the DMA burstsize.  For
	 * fiq it is probably better to use the biggest possible watermark
	 * size.
	 */
	switch (ssi_private->fifo_depth) {
	case 15:
		/*
		 * 2 samples is not enough when running at high data
		 * rates (like 48kHz @ 16 bits/channel, 16 channels)
		 * 8 seems to split things evenly and leave enough time
		 * for the DMA to fill the FIFO before it's over/under
		 * run.
		 */
		ssi_private->fifo_watermark = 8;
		ssi_private->dma_maxburst = 8;
		break;
	case 8:
	default:
		/*
		 * maintain old behavior for older chips.
		 * Keeping it the same because I don't have an older
		 * board to test with.
		 * I suspect this could be changed to be something to
		 * leave some more space in the fifo.
		 */
		ssi_private->fifo_watermark = ssi_private->fifo_depth - 2;
		ssi_private->dma_maxburst = ssi_private->fifo_depth - 2;
		break;
	}

	pm_runtime_enable(&pdev->dev);

	dev_set_drvdata(&pdev->dev, ssi_private);

	if (ssi_private->soc->imx) {
		ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem);
		if (ret)
			return ret;
	}

	if (fsl_ssi_is_ac97(ssi_private)) {
		ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
		if (ret) {
			dev_err(&pdev->dev, "could not set AC'97 ops\n");
			goto error_ac97_ops;
		}
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
					      &ssi_private->cpu_dai_drv, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
		goto error_asoc_register;
	}

	if (ssi_private->use_dma) {
		ret = devm_request_irq(&pdev->dev, ssi_private->irq,
					fsl_ssi_isr, 0, dev_name(&pdev->dev),
					ssi_private);
		if (ret < 0) {
			dev_err(&pdev->dev, "could not claim irq %u\n",
					ssi_private->irq);
			goto error_asoc_register;
		}
	}

	ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev);
	if (ret)
		goto error_asoc_register;

	/*
	 * If codec-handle property is missing from SSI node, we assume
	 * that the machine driver uses new binding which does not require
	 * SSI driver to trigger machine driver's probe.
	 */
	if (!of_get_property(np, "codec-handle", NULL))
		goto done;

	/* Trigger the machine driver's probe function.  The platform driver
	 * name of the machine driver is taken from /compatible property of the
	 * device tree.  We also pass the address of the CPU DAI driver
	 * structure.
	 */
	sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
	/* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
	p = strrchr(sprop, ',');
	if (p)
		sprop = p + 1;
	snprintf(name, sizeof(name), "snd-soc-%s", sprop);
	make_lowercase(name);

	ssi_private->pdev =
		platform_device_register_data(&pdev->dev, name, 0, NULL, 0);
	if (IS_ERR(ssi_private->pdev)) {
		ret = PTR_ERR(ssi_private->pdev);
		dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
		goto error_sound_card;
	}

done:
	if (ssi_private->dai_fmt)
		_fsl_ssi_set_dai_fmt(&pdev->dev, ssi_private,
				     ssi_private->dai_fmt);

	if (fsl_ssi_is_ac97(ssi_private)) {
		u32 ssi_idx;

		ret = of_property_read_u32(np, "cell-index", &ssi_idx);
		if (ret) {
			dev_err(&pdev->dev, "cannot get SSI index property\n");
			goto error_sound_card;
		}

		ssi_private->pdev =
			platform_device_register_data(NULL,
					"ac97-codec", ssi_idx, NULL, 0);
		if (IS_ERR(ssi_private->pdev)) {
			ret = PTR_ERR(ssi_private->pdev);
			dev_err(&pdev->dev,
				"failed to register AC97 codec platform: %d\n",
				ret);
			goto error_sound_card;
		}
	}

	return 0;

error_sound_card:
	fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);

error_asoc_register:
	if (fsl_ssi_is_ac97(ssi_private))
		snd_soc_set_ac97_ops(NULL);

error_ac97_ops:
	if (ssi_private->soc->imx)
		fsl_ssi_imx_clean(pdev, ssi_private);

	return ret;
}

static int fsl_ssi_remove(struct platform_device *pdev)
{
	struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);

	fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);

	if (ssi_private->pdev)
		platform_device_unregister(ssi_private->pdev);

	if (ssi_private->soc->imx)
		fsl_ssi_imx_clean(pdev, ssi_private);

	if (fsl_ssi_is_ac97(ssi_private))
		snd_soc_set_ac97_ops(NULL);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int fsl_ssi_suspend(struct device *dev)
{
	struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev);
	struct regmap *regs = ssi_private->regs;

	regmap_read(regs, CCSR_SSI_SFCSR,
			&ssi_private->regcache_sfcsr);
	regmap_read(regs, CCSR_SSI_SACNT,
			&ssi_private->regcache_sacnt);

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

	return 0;
}

static int fsl_ssi_resume(struct device *dev)
{
	struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev);
	struct regmap *regs = ssi_private->regs;

	regcache_cache_only(regs, false);

	regmap_update_bits(regs, CCSR_SSI_SFCSR,
			CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK |
			CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK,
			ssi_private->regcache_sfcsr);
	regmap_write(regs, CCSR_SSI_SACNT,
			ssi_private->regcache_sacnt);

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

#ifdef CONFIG_PM
static int fsl_ssi_runtime_resume(struct device *dev)
{
	request_bus_freq(BUS_FREQ_AUDIO);
	return 0;
}

static int fsl_ssi_runtime_suspend(struct device *dev)
{
	release_bus_freq(BUS_FREQ_AUDIO);
	return 0;
}
#endif

static const struct dev_pm_ops fsl_ssi_pm = {
	SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume)
	SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend, fsl_ssi_runtime_resume,
			   NULL)
};

static struct platform_driver fsl_ssi_driver = {
	.driver = {
		.name = "fsl-ssi-dai",
		.of_match_table = fsl_ssi_ids,
		.pm = &fsl_ssi_pm,
	},
	.probe = fsl_ssi_probe,
	.remove = fsl_ssi_remove,
};

module_platform_driver(fsl_ssi_driver);

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