// SPDX-License-Identifier: GPL-2.0
//
// Renesas R-Car SSIU support
//
// Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

#include "rsnd.h"

#define SSIU_NAME "ssiu"

struct rsnd_ssiu {
	struct rsnd_mod mod;
	u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */
	unsigned int usrcnt;
	int id;
	int id_sub;
};

/* SSI_MODE */
#define TDM_EXT		(1 << 0)
#define TDM_SPLIT	(1 << 8)

#define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
#define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod)
#define for_each_rsnd_ssiu(pos, priv, i)				\
	for (i = 0;							\
	     (i < rsnd_ssiu_nr(priv)) &&				\
		     ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i));	\
	     i++)

/*
 *	SSI	Gen2		Gen3
 *	0	BUSIF0-3	BUSIF0-7
 *	1	BUSIF0-3	BUSIF0-7
 *	2	BUSIF0-3	BUSIF0-7
 *	3	BUSIF0		BUSIF0-7
 *	4	BUSIF0		BUSIF0-7
 *	5	BUSIF0		BUSIF0
 *	6	BUSIF0		BUSIF0
 *	7	BUSIF0		BUSIF0
 *	8	BUSIF0		BUSIF0
 *	9	BUSIF0-3	BUSIF0-7
 *	total	22		52
 */
static const int gen2_id[] = { 0, 4,  8, 12, 13, 14, 15, 16, 17, 18 };
static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };

static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
				 struct rsnd_dai_stream *io,
				 enum rsnd_mod_type type)
{
	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
	int busif = rsnd_mod_id_sub(mod);

	return &ssiu->busif_status[busif];
}

static int rsnd_ssiu_init(struct rsnd_mod *mod,
			  struct rsnd_dai_stream *io,
			  struct rsnd_priv *priv)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	u32 multi_ssi_slaves = rsnd_ssi_multi_slaves_runtime(io);
	int use_busif = rsnd_ssi_use_busif(io);
	int id = rsnd_mod_id(mod);
	u32 mask1, val1;
	u32 mask2, val2;
	int i;

	/* clear status */
	switch (id) {
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
		for (i = 0; i < 4; i++)
			rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
		break;
	case 9:
		for (i = 0; i < 4; i++)
			rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << 4);
		break;
	}

	/*
	 * SSI_MODE0
	 */
	rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);

	/*
	 * SSI_MODE1
	 */
	mask1 = (1 << 4) | (1 << 20);	/* mask sync bit */
	mask2 = (1 << 4);		/* mask sync bit */
	val1  = val2  = 0;
	if (id == 8) {
		/*
		 * SSI8 pin is sharing with SSI7, nothing to do.
		 */
	} else if (rsnd_ssi_is_pin_sharing(io)) {
		int shift = -1;

		switch (id) {
		case 1:
			shift = 0;
			break;
		case 2:
			shift = 2;
			break;
		case 4:
			shift = 16;
			break;
		default:
			return -EINVAL;
		}

		mask1 |= 0x3 << shift;
		val1 = rsnd_rdai_is_clk_master(rdai) ?
			0x2 << shift : 0x1 << shift;

	} else if (multi_ssi_slaves) {

		mask2 |= 0x00000007;
		mask1 |= 0x0000000f;

		switch (multi_ssi_slaves) {
		case 0x0206: /* SSI0/1/2/9 */
			val2 = (1 << 4) | /* SSI0129 sync */
				(rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1);
			/* fall through */
		case 0x0006: /* SSI0/1/2 */
			val1 = rsnd_rdai_is_clk_master(rdai) ?
				0xa : 0x5;

			if (!val2)  /* SSI012 sync */
				val1 |= (1 << 4);
		}
	}

	rsnd_mod_bset(mod, SSI_MODE1, mask1, val1);
	rsnd_mod_bset(mod, SSI_MODE2, mask2, val2);

	return 0;
}

static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
	.name		= SSIU_NAME,
	.init		= rsnd_ssiu_init,
	.get_status	= rsnd_ssiu_get_status,
};

static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
			       struct rsnd_dai_stream *io,
			       struct rsnd_priv *priv)
{
	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
	u32 has_hdmi0 = rsnd_flags_has(io, RSND_STREAM_HDMI0);
	u32 has_hdmi1 = rsnd_flags_has(io, RSND_STREAM_HDMI1);
	int ret;
	u32 mode = 0;

	ret = rsnd_ssiu_init(mod, io, priv);
	if (ret < 0)
		return ret;

	ssiu->usrcnt++;

	/*
	 * TDM Extend/Split Mode
	 * see
	 *	rsnd_ssi_config_init()
	 */
	if (rsnd_runtime_is_tdm(io))
		mode = TDM_EXT;
	else if (rsnd_runtime_is_tdm_split(io))
		mode = TDM_SPLIT;

	rsnd_mod_write(mod, SSI_MODE, mode);

	if (rsnd_ssi_use_busif(io)) {
		int id = rsnd_mod_id(mod);
		int busif = rsnd_mod_id_sub(mod);

		/*
		 * FIXME
		 *
		 * We can't support SSI9-4/5/6/7, because its address is
		 * out of calculation rule
		 */
		if ((id == 9) && (busif >= 4)) {
			struct device *dev = rsnd_priv_to_dev(priv);

			dev_err(dev, "This driver doesn't support SSI%d-%d, so far",
				id, busif);
		}

		rsnd_mod_write(mod, SSI_BUSIF_ADINR(busif),
			       rsnd_get_adinr_bit(mod, io) |
			       (rsnd_io_is_play(io) ?
				rsnd_runtime_channel_after_ctu(io) :
				rsnd_runtime_channel_original(io)));
		rsnd_mod_write(mod, SSI_BUSIF_MODE(busif),
			       rsnd_get_busif_shift(io, mod) | 1);
		rsnd_mod_write(mod, SSI_BUSIF_DALIGN(busif),
			       rsnd_get_dalign(mod, io));
	}

	if (has_hdmi0 || has_hdmi1) {
		enum rsnd_mod_type rsnd_ssi_array[] = {
			RSND_MOD_SSIM1,
			RSND_MOD_SSIM2,
			RSND_MOD_SSIM3,
		};
		struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
		struct rsnd_mod *pos;
		u32 val;
		int i, shift;

		i = rsnd_mod_id(ssi_mod);

		/* output all same SSI as default */
		val =	i << 16 |
			i << 20 |
			i << 24 |
			i << 28 |
			i;

		for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
			shift	= (i * 4) + 16;
			val	= (val & ~(0xF << shift)) |
				rsnd_mod_id(pos) << shift;
		}

		if (has_hdmi0)
			rsnd_mod_write(mod, HDMI0_SEL, val);
		if (has_hdmi1)
			rsnd_mod_write(mod, HDMI1_SEL, val);
	}

	return 0;
}

static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
				struct rsnd_dai_stream *io,
				struct rsnd_priv *priv)
{
	int busif = rsnd_mod_id_sub(mod);

	if (!rsnd_ssi_use_busif(io))
		return 0;

	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 1 << (busif * 4));

	if (rsnd_ssi_multi_slaves_runtime(io))
		rsnd_mod_write(mod, SSI_CONTROL, 0x1);

	return 0;
}

static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
			       struct rsnd_dai_stream *io,
			       struct rsnd_priv *priv)
{
	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
	int busif = rsnd_mod_id_sub(mod);

	if (!rsnd_ssi_use_busif(io))
		return 0;

	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 0);

	if (--ssiu->usrcnt)
		return 0;

	if (rsnd_ssi_multi_slaves_runtime(io))
		rsnd_mod_write(mod, SSI_CONTROL, 0);

	return 0;
}

static int rsnd_ssiu_id(struct rsnd_mod *mod)
{
	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);

	/* see rsnd_ssiu_probe() */
	return ssiu->id;
}

static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
{
	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);

	/* see rsnd_ssiu_probe() */
	return ssiu->id_sub;
}

static struct dma_chan *rsnd_ssiu_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_ssi_dma_req()
	 *	rsnd_dma_of_path()
	 */

	name = is_play ? "rx" : "tx";

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

static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
	.name		= SSIU_NAME,
	.dma_req	= rsnd_ssiu_dma_req,
	.init		= rsnd_ssiu_init_gen2,
	.start		= rsnd_ssiu_start_gen2,
	.stop		= rsnd_ssiu_stop_gen2,
	.get_status	= rsnd_ssiu_get_status,
};

static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
{
	if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
		id = 0;

	return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
}

static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
					       struct rsnd_dai_stream *io)
{
	struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *mod;
	struct rsnd_ssiu *ssiu;
	int i;

	if (!ssi_mod)
		return;

	/* select BUSIF0 */
	for_each_rsnd_ssiu(ssiu, priv, i) {
		mod = rsnd_mod_get(ssiu);

		if ((rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
		    (rsnd_mod_id_sub(mod) == 0)) {
			rsnd_dai_connect(mod, io, mod->type);
			return;
		}
	}
}

void rsnd_parse_connect_ssiu(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 = rsnd_ssiu_of_node(priv);
	struct device_node *np;
	struct rsnd_mod *mod;
	struct rsnd_dai_stream *io_p = &rdai->playback;
	struct rsnd_dai_stream *io_c = &rdai->capture;
	int i;

	/* use rcar_sound,ssiu if exist */
	if (node) {
		i = 0;
		for_each_child_of_node(node, np) {
			mod = rsnd_ssiu_mod_get(priv, i);
			if (np == playback)
				rsnd_dai_connect(mod, io_p, mod->type);
			if (np == capture)
				rsnd_dai_connect(mod, io_c, mod->type);
			i++;
		}

		of_node_put(node);
	}

	/* Keep DT compatibility */
	if (!rsnd_io_to_mod_ssiu(io_p))
		rsnd_parse_connect_ssiu_compatible(priv, io_p);
	if (!rsnd_io_to_mod_ssiu(io_c))
		rsnd_parse_connect_ssiu_compatible(priv, io_c);
}

int rsnd_ssiu_probe(struct rsnd_priv *priv)
{
	struct device *dev = rsnd_priv_to_dev(priv);
	struct device_node *node;
	struct rsnd_ssiu *ssiu;
	struct rsnd_mod_ops *ops;
	const int *list = NULL;
	int i, nr, ret;

	/*
	 * Keep DT compatibility.
	 * if it has "rcar_sound,ssiu", use it.
	 * if not, use "rcar_sound,ssi"
	 * see
	 *	rsnd_ssiu_bufsif_to_id()
	 */
	node = rsnd_ssiu_of_node(priv);
	if (node)
		nr = of_get_child_count(node);
	else
		nr = priv->ssi_nr;

	ssiu	= devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
	if (!ssiu)
		return -ENOMEM;

	priv->ssiu	= ssiu;
	priv->ssiu_nr	= nr;

	if (rsnd_is_gen1(priv))
		ops = &rsnd_ssiu_ops_gen1;
	else
		ops = &rsnd_ssiu_ops_gen2;

	/* Keep compatibility */
	nr = 0;
	if ((node) &&
	    (ops == &rsnd_ssiu_ops_gen2)) {
		ops->id		= rsnd_ssiu_id;
		ops->id_sub	= rsnd_ssiu_id_sub;

		if (rsnd_is_gen2(priv)) {
			list	= gen2_id;
			nr	= ARRAY_SIZE(gen2_id);
		} else if (rsnd_is_gen3(priv)) {
			list	= gen3_id;
			nr	= ARRAY_SIZE(gen3_id);
		} else {
			dev_err(dev, "unknown SSIU\n");
			return -ENODEV;
		}
	}

	for_each_rsnd_ssiu(ssiu, priv, i) {
		if (node) {
			int j;

			/*
			 * see
			 *	rsnd_ssiu_get_id()
			 *	rsnd_ssiu_get_id_sub()
			 */
			for (j = 0; j < nr; j++) {
				if (list[j] > i)
					break;
				ssiu->id	= j;
				ssiu->id_sub	= i - list[ssiu->id];
			}
		} else {
			ssiu->id = i;
		}

		ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
				    ops, NULL, RSND_MOD_SSIU, i);
		if (ret)
			return ret;
	}

	return 0;
}

void rsnd_ssiu_remove(struct rsnd_priv *priv)
{
	struct rsnd_ssiu *ssiu;
	int i;

	for_each_rsnd_ssiu(ssiu, priv, i) {
		rsnd_mod_quit(rsnd_mod_get(ssiu));
	}
}
