// SPDX-License-Identifier: GPL-2.0
//
// Renesas R-Car SSIU/SSI support
//
// Copyright (C) 2013 Renesas Solutions Corp.
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
//
// Based on fsi.c
// Kuninori Morimoto <morimoto.kuninori@renesas.com>

/*
 * you can enable below define if you don't need
 * SSI interrupt status debug message when debugging
 * see rsnd_dbg_irq_status()
 *
 * #define RSND_DEBUG_NO_IRQ_STATUS 1
 */

#include <sound/simple_card_utils.h>
#include <linux/delay.h>
#include "rsnd.h"
#define RSND_SSI_NAME_SIZE 16

/*
 * SSICR
 */
#define	FORCE		(1 << 31)	/* Fixed */
#define	DMEN		(1 << 28)	/* DMA Enable */
#define	UIEN		(1 << 27)	/* Underflow Interrupt Enable */
#define	OIEN		(1 << 26)	/* Overflow Interrupt Enable */
#define	IIEN		(1 << 25)	/* Idle Mode Interrupt Enable */
#define	DIEN		(1 << 24)	/* Data Interrupt Enable */
#define	CHNL_4		(1 << 22)	/* Channels */
#define	CHNL_6		(2 << 22)	/* Channels */
#define	CHNL_8		(3 << 22)	/* Channels */
#define DWL_MASK	(7 << 19)	/* Data Word Length mask */
#define	DWL_8		(0 << 19)	/* Data Word Length */
#define	DWL_16		(1 << 19)	/* Data Word Length */
#define	DWL_18		(2 << 19)	/* Data Word Length */
#define	DWL_20		(3 << 19)	/* Data Word Length */
#define	DWL_22		(4 << 19)	/* Data Word Length */
#define	DWL_24		(5 << 19)	/* Data Word Length */
#define	DWL_32		(6 << 19)	/* Data Word Length */

/*
 * System word length
 */
#define	SWL_16		(1 << 16)	/* R/W System Word Length */
#define	SWL_24		(2 << 16)	/* R/W System Word Length */
#define	SWL_32		(3 << 16)	/* R/W System Word Length */

#define	SCKD		(1 << 15)	/* Serial Bit Clock Direction */
#define	SWSD		(1 << 14)	/* Serial WS Direction */
#define	SCKP		(1 << 13)	/* Serial Bit Clock Polarity */
#define	SWSP		(1 << 12)	/* Serial WS Polarity */
#define	SDTA		(1 << 10)	/* Serial Data Alignment */
#define	PDTA		(1 <<  9)	/* Parallel Data Alignment */
#define	DEL		(1 <<  8)	/* Serial Data Delay */
#define	CKDV(v)		(v <<  4)	/* Serial Clock Division Ratio */
#define	TRMD		(1 <<  1)	/* Transmit/Receive Mode Select */
#define	EN		(1 <<  0)	/* SSI Module Enable */

/*
 * SSISR
 */
#define	UIRQ		(1 << 27)	/* Underflow Error Interrupt Status */
#define	OIRQ		(1 << 26)	/* Overflow Error Interrupt Status */
#define	IIRQ		(1 << 25)	/* Idle Mode Interrupt Status */
#define	DIRQ		(1 << 24)	/* Data Interrupt Status Flag */

/*
 * SSIWSR
 */
#define CONT		(1 << 8)	/* WS Continue Function */
#define WS_MODE		(1 << 0)	/* WS Mode */

#define SSI_NAME "ssi"

struct rsnd_ssi {
	struct rsnd_mod mod;

	u32 flags;
	u32 cr_own;
	u32 cr_clk;
	u32 cr_mode;
	u32 cr_en;
	u32 wsr;
	int chan;
	int rate;
	int irq;
	unsigned int usrcnt;

	/* for PIO */
	int byte_pos;
	int byte_per_period;
	int next_period_byte;
};

/* flags */
#define RSND_SSI_CLK_PIN_SHARE		(1 << 0)
#define RSND_SSI_NO_BUSIF		(1 << 1) /* SSI+DMA without BUSIF */
#define RSND_SSI_PROBED			(1 << 2)

#define for_each_rsnd_ssi(pos, priv, i)					\
	for (i = 0;							\
	     (i < rsnd_ssi_nr(priv)) &&					\
		((pos) = ((struct rsnd_ssi *)(priv)->ssi + i));		\
	     i++)

#define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id)
#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
#define rsnd_ssi_is_multi_secondary(mod, io)				\
	(rsnd_ssi_multi_secondaries(io) & (1 << rsnd_mod_id(mod)))
#define rsnd_ssi_is_run_mods(mod, io) \
	(rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod)))
#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod))

static int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);

int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
{
	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	int use_busif = 0;

	if (!rsnd_ssi_is_dma_mode(mod))
		return 0;

	if (!(rsnd_flags_has(ssi, RSND_SSI_NO_BUSIF)))
		use_busif = 1;
	if (rsnd_io_to_mod_src(io))
		use_busif = 1;

	return use_busif;
}

static void rsnd_ssi_status_clear(struct rsnd_mod *mod)
{
	rsnd_mod_write(mod, SSISR, 0);
}

static u32 rsnd_ssi_status_get(struct rsnd_mod *mod)
{
	return rsnd_mod_read(mod, SSISR);
}

static void rsnd_ssi_status_check(struct rsnd_mod *mod,
				  u32 bit)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	u32 status;
	int i;

	for (i = 0; i < 1024; i++) {
		status = rsnd_ssi_status_get(mod);
		if (status & bit)
			return;

		udelay(5);
	}

	dev_warn(dev, "%s status check failed\n", rsnd_mod_name(mod));
}

static u32 rsnd_ssi_multi_secondaries(struct rsnd_dai_stream *io)
{
	struct rsnd_mod *mod;
	enum rsnd_mod_type types[] = {
		RSND_MOD_SSIM1,
		RSND_MOD_SSIM2,
		RSND_MOD_SSIM3,
	};
	int i, mask;

	mask = 0;
	for (i = 0; i < ARRAY_SIZE(types); i++) {
		mod = rsnd_io_to_mod(io, types[i]);
		if (!mod)
			continue;

		mask |= 1 << rsnd_mod_id(mod);
	}

	return mask;
}

static u32 rsnd_ssi_run_mods(struct rsnd_dai_stream *io)
{
	struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
	u32 mods;

	mods = rsnd_ssi_multi_secondaries_runtime(io) |
		1 << rsnd_mod_id(ssi_mod);

	if (ssi_parent_mod)
		mods |= 1 << rsnd_mod_id(ssi_parent_mod);

	return mods;
}

u32 rsnd_ssi_multi_secondaries_runtime(struct rsnd_dai_stream *io)
{
	if (rsnd_runtime_is_multi_ssi(io))
		return rsnd_ssi_multi_secondaries(io);

	return 0;
}

static u32 rsnd_rdai_width_to_swl(struct rsnd_dai *rdai)
{
	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
	struct device *dev = rsnd_priv_to_dev(priv);
	int width = rsnd_rdai_width_get(rdai);

	switch (width) {
	case 32: return SWL_32;
	case 24: return SWL_24;
	case 16: return SWL_16;
	}

	dev_err(dev, "unsupported slot width value: %d\n", width);
	return 0;
}

unsigned int rsnd_ssi_clk_query(struct rsnd_dai *rdai,
		       int param1, int param2, int *idx)
{
	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
	int ssi_clk_mul_table[] = {
		1, 2, 4, 8, 16, 6, 12,
	};
	int j, ret;
	unsigned int main_rate;
	int width = rsnd_rdai_width_get(rdai);

	for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {

		/*
		 * It will set SSIWSR.CONT here, but SSICR.CKDV = 000
		 * with it is not allowed. (SSIWSR.WS_MODE with
		 * SSICR.CKDV = 000 is not allowed either).
		 * Skip it. See SSICR.CKDV
		 */
		if (j == 0)
			continue;

		main_rate = width * param1 * param2 * ssi_clk_mul_table[j];

		ret = rsnd_adg_clk_query(priv, main_rate);
		if (ret < 0)
			continue;

		if (idx)
			*idx = j;

		return main_rate;
	}

	return 0;
}

static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
				     struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_io_to_priv(io);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	int chan = rsnd_runtime_channel_for_ssi(io);
	int idx, ret;
	unsigned int main_rate;
	unsigned int rate = rsnd_io_is_play(io) ?
		rsnd_src_get_out_rate(priv, io) :
		rsnd_src_get_in_rate(priv, io);

	if (!rsnd_rdai_is_clk_master(rdai))
		return 0;

	if (!rsnd_ssi_can_output_clk(mod))
		return 0;

	if (rsnd_ssi_is_multi_secondary(mod, io))
		return 0;

	if (rsnd_runtime_is_tdm_split(io))
		chan = rsnd_io_converted_chan(io);

	chan = rsnd_channel_normalization(chan);

	if (ssi->usrcnt > 0) {
		if (ssi->rate != rate) {
			dev_err(dev, "SSI parent/child should use same rate\n");
			return -EINVAL;
		}

		if (ssi->chan != chan) {
			dev_err(dev, "SSI parent/child should use same chan\n");
			return -EINVAL;
		}

		return 0;
	}

	main_rate = rsnd_ssi_clk_query(rdai, rate, chan, &idx);
	if (!main_rate) {
		dev_err(dev, "unsupported clock rate\n");
		return -EIO;
	}

	ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
	if (ret < 0)
		return ret;

	/*
	 * SSI clock will be output contiguously
	 * by below settings.
	 * This means, rsnd_ssi_master_clk_start()
	 * and rsnd_ssi_register_setup() are necessary
	 * for SSI parent
	 *
	 * SSICR  : FORCE, SCKD, SWSD
	 * SSIWSR : CONT
	 */
	ssi->cr_clk = FORCE | rsnd_rdai_width_to_swl(rdai) |
			SCKD | SWSD | CKDV(idx);
	ssi->wsr = CONT;
	ssi->rate = rate;
	ssi->chan = chan;

	dev_dbg(dev, "%s outputs %d chan %u Hz\n",
		rsnd_mod_name(mod), chan, rate);

	return 0;
}

static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod,
				     struct rsnd_dai_stream *io)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	if (!rsnd_rdai_is_clk_master(rdai))
		return;

	if (!rsnd_ssi_can_output_clk(mod))
		return;

	if (ssi->usrcnt > 1)
		return;

	ssi->cr_clk	= 0;
	ssi->rate	= 0;
	ssi->chan	= 0;

	rsnd_adg_ssi_clk_stop(mod);
}

static void rsnd_ssi_config_init(struct rsnd_mod *mod,
				struct rsnd_dai_stream *io)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	u32 cr_own	= ssi->cr_own;
	u32 cr_mode	= ssi->cr_mode;
	u32 wsr		= ssi->wsr;
	int width;
	int is_tdm, is_tdm_split;
	int id = rsnd_mod_id(mod);
	int i;
	u32 sys_int_enable = 0;

	is_tdm		= rsnd_runtime_is_tdm(io);
	is_tdm_split	= rsnd_runtime_is_tdm_split(io);

	if (is_tdm)
		dev_dbg(dev, "TDM mode\n");
	if (is_tdm_split)
		dev_dbg(dev, "TDM Split mode\n");

	cr_own |= FORCE | rsnd_rdai_width_to_swl(rdai);

	if (rdai->bit_clk_inv)
		cr_own |= SCKP;
	if (rdai->frm_clk_inv && !is_tdm)
		cr_own |= SWSP;
	if (rdai->data_alignment)
		cr_own |= SDTA;
	if (rdai->sys_delay)
		cr_own |= DEL;

	/*
	 * TDM Mode
	 * see
	 *	rsnd_ssiu_init_gen2()
	 */
	wsr = ssi->wsr;
	if (is_tdm || is_tdm_split) {
		wsr	|= WS_MODE;
		cr_own	|= CHNL_8;
	}

	/*
	 * We shouldn't exchange SWSP after running.
	 * This means, parent needs to care it.
	 */
	if (rsnd_ssi_is_parent(mod, io))
		goto init_end;

	if (rsnd_io_is_play(io))
		cr_own |= TRMD;

	cr_own &= ~DWL_MASK;
	width = snd_pcm_format_width(runtime->format);
	if (is_tdm_split) {
		/*
		 * The SWL and DWL bits in SSICR should be fixed at 32-bit
		 * setting when TDM split mode.
		 * see datasheet
		 *	Operation :: TDM Format Split Function (TDM Split Mode)
		 */
		width = 32;
	}

	switch (width) {
	case 8:
		cr_own |= DWL_8;
		break;
	case 16:
		cr_own |= DWL_16;
		break;
	case 24:
		cr_own |= DWL_24;
		break;
	case 32:
		cr_own |= DWL_32;
		break;
	}

	if (rsnd_ssi_is_dma_mode(mod)) {
		cr_mode = UIEN | OIEN |	/* over/under run */
			  DMEN;		/* DMA : enable DMA */
	} else {
		cr_mode = DIEN;		/* PIO : enable Data interrupt */
	}

	/* enable busif buffer over/under run interrupt. */
	if (is_tdm || is_tdm_split) {
		switch (id) {
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
			for (i = 0; i < 4; i++) {
				sys_int_enable = rsnd_mod_read(mod,
					SSI_SYS_INT_ENABLE(i * 2));
				sys_int_enable |= 0xf << (id * 4);
				rsnd_mod_write(mod,
					       SSI_SYS_INT_ENABLE(i * 2),
					       sys_int_enable);
			}

			break;
		case 9:
			for (i = 0; i < 4; i++) {
				sys_int_enable = rsnd_mod_read(mod,
					SSI_SYS_INT_ENABLE((i * 2) + 1));
				sys_int_enable |= 0xf << 4;
				rsnd_mod_write(mod,
					       SSI_SYS_INT_ENABLE((i * 2) + 1),
					       sys_int_enable);
			}

			break;
		}
	}

init_end:
	ssi->cr_own	= cr_own;
	ssi->cr_mode	= cr_mode;
	ssi->wsr	= wsr;
}

static void rsnd_ssi_register_setup(struct rsnd_mod *mod)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	rsnd_mod_write(mod, SSIWSR,	ssi->wsr);
	rsnd_mod_write(mod, SSICR,	ssi->cr_own	|
					ssi->cr_clk	|
					ssi->cr_mode	|
					ssi->cr_en);
}

/*
 *	SSI mod common functions
 */
static int rsnd_ssi_init(struct rsnd_mod *mod,
			 struct rsnd_dai_stream *io,
			 struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	if (!rsnd_ssi_is_run_mods(mod, io))
		return 0;

	ssi->usrcnt++;

	rsnd_mod_power_on(mod);

	rsnd_ssi_config_init(mod, io);

	rsnd_ssi_register_setup(mod);

	/* clear error status */
	rsnd_ssi_status_clear(mod);

	return 0;
}

static int rsnd_ssi_quit(struct rsnd_mod *mod,
			 struct rsnd_dai_stream *io,
			 struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	int is_tdm, is_tdm_split;
	int id = rsnd_mod_id(mod);
	int i;
	u32 sys_int_enable = 0;

	is_tdm		= rsnd_runtime_is_tdm(io);
	is_tdm_split	= rsnd_runtime_is_tdm_split(io);

	if (!rsnd_ssi_is_run_mods(mod, io))
		return 0;

	if (!ssi->usrcnt) {
		dev_err(dev, "%s usrcnt error\n", rsnd_mod_name(mod));
		return -EIO;
	}

	rsnd_ssi_master_clk_stop(mod, io);

	rsnd_mod_power_off(mod);

	ssi->usrcnt--;

	if (!ssi->usrcnt) {
		ssi->cr_own	= 0;
		ssi->cr_mode	= 0;
		ssi->wsr	= 0;
	}

	/* disable busif buffer over/under run interrupt. */
	if (is_tdm || is_tdm_split) {
		switch (id) {
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
			for (i = 0; i < 4; i++) {
				sys_int_enable = rsnd_mod_read(mod,
						SSI_SYS_INT_ENABLE(i * 2));
				sys_int_enable &= ~(0xf << (id * 4));
				rsnd_mod_write(mod,
					       SSI_SYS_INT_ENABLE(i * 2),
					       sys_int_enable);
			}

			break;
		case 9:
			for (i = 0; i < 4; i++) {
				sys_int_enable = rsnd_mod_read(mod,
					SSI_SYS_INT_ENABLE((i * 2) + 1));
				sys_int_enable &= ~(0xf << 4);
				rsnd_mod_write(mod,
					       SSI_SYS_INT_ENABLE((i * 2) + 1),
					       sys_int_enable);
			}

			break;
		}
	}

	return 0;
}

static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
			      struct rsnd_dai_stream *io,
			      struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	unsigned int fmt_width = snd_pcm_format_width(params_format(params));

	if (fmt_width > rdai->chan_width) {
		struct rsnd_priv *priv = rsnd_io_to_priv(io);
		struct device *dev = rsnd_priv_to_dev(priv);

		dev_err(dev, "invalid combination of slot-width and format-data-width\n");
		return -EINVAL;
	}

	return 0;
}

static int rsnd_ssi_start(struct rsnd_mod *mod,
			  struct rsnd_dai_stream *io,
			  struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	if (!rsnd_ssi_is_run_mods(mod, io))
		return 0;

	/*
	 * EN will be set via SSIU :: SSI_CONTROL
	 * if Multi channel mode
	 */
	if (rsnd_ssi_multi_secondaries_runtime(io))
		return 0;

	/*
	 * EN is for data output.
	 * SSI parent EN is not needed.
	 */
	if (rsnd_ssi_is_parent(mod, io))
		return 0;

	ssi->cr_en = EN;

	rsnd_mod_write(mod, SSICR,	ssi->cr_own	|
					ssi->cr_clk	|
					ssi->cr_mode	|
					ssi->cr_en);

	return 0;
}

static int rsnd_ssi_stop(struct rsnd_mod *mod,
			 struct rsnd_dai_stream *io,
			 struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	u32 cr;

	if (!rsnd_ssi_is_run_mods(mod, io))
		return 0;

	if (rsnd_ssi_is_parent(mod, io))
		return 0;

	cr  =	ssi->cr_own	|
		ssi->cr_clk;

	/*
	 * disable all IRQ,
	 * Playback: Wait all data was sent
	 * Capture:  It might not receave data. Do nothing
	 */
	if (rsnd_io_is_play(io)) {
		rsnd_mod_write(mod, SSICR, cr | ssi->cr_en);
		rsnd_ssi_status_check(mod, DIRQ);
	}

	/* In multi-SSI mode, stop is performed by setting ssi0129 in
	 * SSI_CONTROL to 0 (in rsnd_ssio_stop_gen2). Do nothing here.
	 */
	if (rsnd_ssi_multi_secondaries_runtime(io))
		return 0;

	/*
	 * disable SSI,
	 * and, wait idle state
	 */
	rsnd_mod_write(mod, SSICR, cr);	/* disabled all */
	rsnd_ssi_status_check(mod, IIRQ);

	ssi->cr_en = 0;

	return 0;
}

static int rsnd_ssi_irq(struct rsnd_mod *mod,
			struct rsnd_dai_stream *io,
			struct rsnd_priv *priv,
			int enable)
{
	u32 val = 0;
	int is_tdm, is_tdm_split;
	int id = rsnd_mod_id(mod);

	is_tdm		= rsnd_runtime_is_tdm(io);
	is_tdm_split	= rsnd_runtime_is_tdm_split(io);

	if (rsnd_is_gen1(priv))
		return 0;

	if (rsnd_ssi_is_parent(mod, io))
		return 0;

	if (!rsnd_ssi_is_run_mods(mod, io))
		return 0;

	if (enable)
		val = rsnd_ssi_is_dma_mode(mod) ? 0x0e000000 : 0x0f000000;

	if (is_tdm || is_tdm_split) {
		switch (id) {
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 9:
			val |= 0x0000ff00;
			break;
		}
	}

	rsnd_mod_write(mod, SSI_INT_ENABLE, val);

	return 0;
}

static bool rsnd_ssi_pio_interrupt(struct rsnd_mod *mod,
				   struct rsnd_dai_stream *io);
static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
				 struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	int is_dma = rsnd_ssi_is_dma_mode(mod);
	u32 status;
	bool elapsed = false;
	bool stop = false;
	int id = rsnd_mod_id(mod);
	int i;
	int is_tdm, is_tdm_split;

	is_tdm		= rsnd_runtime_is_tdm(io);
	is_tdm_split	= rsnd_runtime_is_tdm_split(io);

	spin_lock(&priv->lock);

	/* ignore all cases if not working */
	if (!rsnd_io_is_working(io))
		goto rsnd_ssi_interrupt_out;

	status = rsnd_ssi_status_get(mod);

	/* PIO only */
	if (!is_dma && (status & DIRQ))
		elapsed = rsnd_ssi_pio_interrupt(mod, io);

	/* DMA only */
	if (is_dma && (status & (UIRQ | OIRQ))) {
		rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
			rsnd_mod_name(mod), status);

		stop = true;
	}

	status = 0;

	if (is_tdm || is_tdm_split) {
		switch (id) {
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
			for (i = 0; i < 4; i++) {
				status = rsnd_mod_read(mod,
						       SSI_SYS_STATUS(i * 2));
				status &= 0xf << (id * 4);

				if (status) {
					rsnd_dbg_irq_status(dev,
						"%s err status : 0x%08x\n",
						rsnd_mod_name(mod), status);
					rsnd_mod_write(mod,
						       SSI_SYS_STATUS(i * 2),
						       0xf << (id * 4));
					stop = true;
					break;
				}
			}
			break;
		case 9:
			for (i = 0; i < 4; i++) {
				status = rsnd_mod_read(mod,
						SSI_SYS_STATUS((i * 2) + 1));
				status &= 0xf << 4;

				if (status) {
					rsnd_dbg_irq_status(dev,
						"%s err status : 0x%08x\n",
						rsnd_mod_name(mod), status);
					rsnd_mod_write(mod,
						SSI_SYS_STATUS((i * 2) + 1),
						0xf << 4);
					stop = true;
					break;
				}
			}
			break;
		}
	}

	rsnd_ssi_status_clear(mod);
rsnd_ssi_interrupt_out:
	spin_unlock(&priv->lock);

	if (elapsed)
		rsnd_dai_period_elapsed(io);

	if (stop)
		snd_pcm_stop_xrun(io->substream);

}

static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
{
	struct rsnd_mod *mod = data;

	rsnd_mod_interrupt(mod, __rsnd_ssi_interrupt);

	return IRQ_HANDLED;
}

static u32 *rsnd_ssi_get_status(struct rsnd_mod *mod,
				struct rsnd_dai_stream *io,
				enum rsnd_mod_type type)
{
	/*
	 * SSIP (= SSI parent) needs to be special, otherwise,
	 * 2nd SSI might doesn't start. see also rsnd_mod_call()
	 *
	 * We can't include parent SSI status on SSI, because we don't know
	 * how many SSI requests parent SSI. Thus, it is localed on "io" now.
	 * ex) trouble case
	 *	Playback: SSI0
	 *	Capture : SSI1 (needs SSI0)
	 *
	 * 1) start Capture  ->	SSI0/SSI1 are started.
	 * 2) start Playback ->	SSI0 doesn't work, because it is already
	 *			marked as "started" on 1)
	 *
	 * OTOH, using each mod's status is good for MUX case.
	 * It doesn't need to start in 2nd start
	 * ex)
	 *	IO-0: SRC0 -> CTU1 -+-> MUX -> DVC -> SSIU -> SSI0
	 *			    |
	 *	IO-1: SRC1 -> CTU2 -+
	 *
	 * 1) start IO-0 ->	start SSI0
	 * 2) start IO-1 ->	SSI0 doesn't need to start, because it is
	 *			already started on 1)
	 */
	if (type == RSND_MOD_SSIP)
		return &io->parent_ssi_status;

	return rsnd_mod_get_status(mod, io, type);
}

/*
 *		SSI PIO
 */
static void rsnd_ssi_parent_attach(struct rsnd_mod *mod,
				   struct rsnd_dai_stream *io)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);

	if (!__rsnd_ssi_is_pin_sharing(mod))
		return;

	if (!rsnd_rdai_is_clk_master(rdai))
		return;

	if (rsnd_ssi_is_multi_secondary(mod, io))
		return;

	switch (rsnd_mod_id(mod)) {
	case 1:
	case 2:
	case 9:
		rsnd_dai_connect(rsnd_ssi_mod_get(priv, 0), io, RSND_MOD_SSIP);
		break;
	case 4:
		rsnd_dai_connect(rsnd_ssi_mod_get(priv, 3), io, RSND_MOD_SSIP);
		break;
	case 8:
		rsnd_dai_connect(rsnd_ssi_mod_get(priv, 7), io, RSND_MOD_SSIP);
		break;
	}
}

static int rsnd_ssi_pcm_new(struct rsnd_mod *mod,
			    struct rsnd_dai_stream *io,
			    struct snd_soc_pcm_runtime *rtd)
{
	/*
	 * rsnd_rdai_is_clk_master() will be enabled after set_fmt,
	 * and, pcm_new will be called after it.
	 * This function reuse pcm_new at this point.
	 */
	rsnd_ssi_parent_attach(mod, io);

	return 0;
}

static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
				 struct rsnd_dai_stream *io,
				 struct rsnd_priv *priv)
{
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	int ret = 0;

	/*
	 * SSIP/SSIU/IRQ are not needed on
	 * SSI Multi secondaries
	 */
	if (rsnd_ssi_is_multi_secondary(mod, io))
		return 0;

	/*
	 * It can't judge ssi parent at this point
	 * see rsnd_ssi_pcm_new()
	 */

	/*
	 * SSI might be called again as PIO fallback
	 * It is easy to manual handling for IRQ request/free
	 *
	 * OTOH, this function might be called many times if platform is
	 * using MIX. It needs xxx_attach() many times on xxx_probe().
	 * Because of it, we can't control .probe/.remove calling count by
	 * mod->status.
	 * But it don't need to call request_irq() many times.
	 * Let's control it by RSND_SSI_PROBED flag.
	 */
	if (!rsnd_flags_has(ssi, RSND_SSI_PROBED)) {
		ret = request_irq(ssi->irq,
				  rsnd_ssi_interrupt,
				  IRQF_SHARED,
				  dev_name(dev), mod);

		rsnd_flags_set(ssi, RSND_SSI_PROBED);
	}

	return ret;
}

static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
				  struct rsnd_dai_stream *io,
				  struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io);

	/* Do nothing if non SSI (= SSI parent, multi SSI) mod */
	if (pure_ssi_mod != mod)
		return 0;

	/* PIO will request IRQ again */
	if (rsnd_flags_has(ssi, RSND_SSI_PROBED)) {
		free_irq(ssi->irq, mod);

		rsnd_flags_del(ssi, RSND_SSI_PROBED);
	}

	return 0;
}

/*
 *	SSI PIO functions
 */
static bool rsnd_ssi_pio_interrupt(struct rsnd_mod *mod,
				   struct rsnd_dai_stream *io)
{
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	u32 *buf = (u32 *)(runtime->dma_area + ssi->byte_pos);
	int shift = 0;
	int byte_pos;
	bool elapsed = false;

	if (snd_pcm_format_width(runtime->format) == 24)
		shift = 8;

	/*
	 * 8/16/32 data can be assesse to TDR/RDR register
	 * directly as 32bit data
	 * see rsnd_ssi_init()
	 */
	if (rsnd_io_is_play(io))
		rsnd_mod_write(mod, SSITDR, (*buf) << shift);
	else
		*buf = (rsnd_mod_read(mod, SSIRDR) >> shift);

	byte_pos = ssi->byte_pos + sizeof(*buf);

	if (byte_pos >= ssi->next_period_byte) {
		int period_pos = byte_pos / ssi->byte_per_period;

		if (period_pos >= runtime->periods) {
			byte_pos = 0;
			period_pos = 0;
		}

		ssi->next_period_byte = (period_pos + 1) * ssi->byte_per_period;

		elapsed = true;
	}

	WRITE_ONCE(ssi->byte_pos, byte_pos);

	return elapsed;
}

static int rsnd_ssi_pio_init(struct rsnd_mod *mod,
			     struct rsnd_dai_stream *io,
			     struct rsnd_priv *priv)
{
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	if (!rsnd_ssi_is_parent(mod, io)) {
		ssi->byte_pos		= 0;
		ssi->byte_per_period	= runtime->period_size *
					  runtime->channels *
					  samples_to_bytes(runtime, 1);
		ssi->next_period_byte	= ssi->byte_per_period;
	}

	return rsnd_ssi_init(mod, io, priv);
}

static int rsnd_ssi_pio_pointer(struct rsnd_mod *mod,
			    struct rsnd_dai_stream *io,
			    snd_pcm_uframes_t *pointer)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);

	*pointer = bytes_to_frames(runtime, READ_ONCE(ssi->byte_pos));

	return 0;
}

static int rsnd_ssi_prepare(struct rsnd_mod *mod,
			    struct rsnd_dai_stream *io,
			    struct rsnd_priv *priv)
{
	return rsnd_ssi_master_clk_start(mod, io);
}

static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
	.name		= SSI_NAME,
	.probe		= rsnd_ssi_common_probe,
	.remove		= rsnd_ssi_common_remove,
	.init		= rsnd_ssi_pio_init,
	.quit		= rsnd_ssi_quit,
	.start		= rsnd_ssi_start,
	.stop		= rsnd_ssi_stop,
	.irq		= rsnd_ssi_irq,
	.pointer	= rsnd_ssi_pio_pointer,
	.pcm_new	= rsnd_ssi_pcm_new,
	.hw_params	= rsnd_ssi_hw_params,
	.prepare	= rsnd_ssi_prepare,
	.get_status	= rsnd_ssi_get_status,
};

static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
			      struct rsnd_dai_stream *io,
			      struct rsnd_priv *priv)
{
	int ret;

	/*
	 * SSIP/SSIU/IRQ/DMA are not needed on
	 * SSI Multi secondaries
	 */
	if (rsnd_ssi_is_multi_secondary(mod, io))
		return 0;

	ret = rsnd_ssi_common_probe(mod, io, priv);
	if (ret)
		return ret;

	/* SSI probe might be called many times in MUX multi path */
	ret = rsnd_dma_attach(io, mod, &io->dma);

	return ret;
}

static int rsnd_ssi_fallback(struct rsnd_mod *mod,
			     struct rsnd_dai_stream *io,
			     struct rsnd_priv *priv)
{
	struct device *dev = rsnd_priv_to_dev(priv);

	/*
	 * fallback to PIO
	 *
	 * SSI .probe might be called again.
	 * see
	 *	rsnd_rdai_continuance_probe()
	 */
	mod->ops = &rsnd_ssi_pio_ops;

	dev_info(dev, "%s fallback to PIO mode\n", rsnd_mod_name(mod));

	return 0;
}

static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
					 struct rsnd_mod *mod)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	int is_play = rsnd_io_is_play(io);
	char *name;

	/*
	 * It should use "rcar_sound,ssiu" on DT.
	 * But, we need to keep compatibility for old version.
	 *
	 * If it has "rcar_sound.ssiu", it will be used.
	 * If not, "rcar_sound.ssi" will be used.
	 * see
	 *	rsnd_ssiu_dma_req()
	 *	rsnd_dma_of_path()
	 */

	if (rsnd_ssi_use_busif(io))
		name = is_play ? "rxu" : "txu";
	else
		name = is_play ? "rx" : "tx";

	return rsnd_dma_request_channel(rsnd_ssi_of_node(priv),
					mod, name);
}

static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
	.name		= SSI_NAME,
	.dma_req	= rsnd_ssi_dma_req,
	.probe		= rsnd_ssi_dma_probe,
	.remove		= rsnd_ssi_common_remove,
	.init		= rsnd_ssi_init,
	.quit		= rsnd_ssi_quit,
	.start		= rsnd_ssi_start,
	.stop		= rsnd_ssi_stop,
	.irq		= rsnd_ssi_irq,
	.pcm_new	= rsnd_ssi_pcm_new,
	.fallback	= rsnd_ssi_fallback,
	.hw_params	= rsnd_ssi_hw_params,
	.prepare	= rsnd_ssi_prepare,
	.get_status	= rsnd_ssi_get_status,
};

static int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
{
	return mod->ops == &rsnd_ssi_dma_ops;
}

/*
 *		ssi mod function
 */
static void rsnd_ssi_connect(struct rsnd_mod *mod,
			     struct rsnd_dai_stream *io)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	enum rsnd_mod_type types[] = {
		RSND_MOD_SSI,
		RSND_MOD_SSIM1,
		RSND_MOD_SSIM2,
		RSND_MOD_SSIM3,
	};
	enum rsnd_mod_type type;
	int i;

	/* try SSI -> SSIM1 -> SSIM2 -> SSIM3 */
	for (i = 0; i < ARRAY_SIZE(types); i++) {
		type = types[i];
		if (!rsnd_io_to_mod(io, type)) {
			rsnd_dai_connect(mod, io, type);
			rsnd_rdai_channels_set(rdai, (i + 1) * 2);
			rsnd_rdai_ssi_lane_set(rdai, (i + 1));
			return;
		}
	}
}

void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
			    struct device_node *playback,
			    struct device_node *capture)
{
	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
	struct device_node *node;
	struct device_node *np;
	struct rsnd_mod *mod;
	int i;

	node = rsnd_ssi_of_node(priv);
	if (!node)
		return;

	i = 0;
	for_each_child_of_node(node, np) {
		mod = rsnd_ssi_mod_get(priv, i);
		if (np == playback)
			rsnd_ssi_connect(mod, &rdai->playback);
		if (np == capture)
			rsnd_ssi_connect(mod, &rdai->capture);
		i++;
	}

	of_node_put(node);
}

struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
{
	if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
		id = 0;

	return rsnd_mod_get(rsnd_ssi_get(priv, id));
}

int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
{
	if (!mod)
		return 0;

	return !!(rsnd_flags_has(rsnd_mod_to_ssi(mod), RSND_SSI_CLK_PIN_SHARE));
}

int rsnd_ssi_probe(struct rsnd_priv *priv)
{
	struct device_node *node;
	struct device_node *np;
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mod_ops *ops;
	struct clk *clk;
	struct rsnd_ssi *ssi;
	char name[RSND_SSI_NAME_SIZE];
	int i, nr, ret;

	node = rsnd_ssi_of_node(priv);
	if (!node)
		return -EINVAL;

	nr = of_get_child_count(node);
	if (!nr) {
		ret = -EINVAL;
		goto rsnd_ssi_probe_done;
	}

	ssi	= devm_kcalloc(dev, nr, sizeof(*ssi), GFP_KERNEL);
	if (!ssi) {
		ret = -ENOMEM;
		goto rsnd_ssi_probe_done;
	}

	priv->ssi	= ssi;
	priv->ssi_nr	= nr;

	i = 0;
	for_each_child_of_node(node, np) {
		if (!of_device_is_available(np))
			goto skip;

		ssi = rsnd_ssi_get(priv, i);

		snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
			 SSI_NAME, i);

		clk = devm_clk_get(dev, name);
		if (IS_ERR(clk)) {
			ret = PTR_ERR(clk);
			of_node_put(np);
			goto rsnd_ssi_probe_done;
		}

		if (of_get_property(np, "shared-pin", NULL))
			rsnd_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE);

		if (of_get_property(np, "no-busif", NULL))
			rsnd_flags_set(ssi, RSND_SSI_NO_BUSIF);

		ssi->irq = irq_of_parse_and_map(np, 0);
		if (!ssi->irq) {
			ret = -EINVAL;
			of_node_put(np);
			goto rsnd_ssi_probe_done;
		}

		if (of_property_read_bool(np, "pio-transfer"))
			ops = &rsnd_ssi_pio_ops;
		else
			ops = &rsnd_ssi_dma_ops;

		ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
				    RSND_MOD_SSI, i);
		if (ret) {
			of_node_put(np);
			goto rsnd_ssi_probe_done;
		}
skip:
		i++;
	}

	ret = 0;

rsnd_ssi_probe_done:
	of_node_put(node);

	return ret;
}

void rsnd_ssi_remove(struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi;
	int i;

	for_each_rsnd_ssi(ssi, priv, i) {
		rsnd_mod_quit(rsnd_mod_get(ssi));
	}
}
