Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eed76bb8 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: rsnd: add rsnd_runtime_channel_xxx()



Current SSI is supporting Normal SSI/Multi mode SSI/TDM mode SSI
and its behavior is based on input channels.
This input channel might be converted by CTU,
and SSI needs to be Multi SSI mode / TDM SSI mode if 6ch input

EX) 6ch input, CTU for 2ch, playback

 6ch    6ch    2ch    2ch    2ch     2ch
 -> SRC -> CTU -> MIX -> DVC -> SSIU -> SSI

EX) 6ch input, no CTU, Multi SSI, playback

 6ch    6ch    6ch    6ch    6ch     2ch
 -> SRC -> CTU -> MIX -> DVC -> SSIU -> SSI0/SSI1/SSI2

Current driver is using rsnd_get_adinr_chan() / rsnd_get_slot_width()
for this purpose, but it is complicated enough without meaning.
This patch adds new rsnd_runtime_channel_xxx() which is caring
CTU/Multi SSI.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8a3a2211
Loading
Loading
Loading
Loading
+42 −27
Original line number Original line Diff line number Diff line
@@ -224,13 +224,36 @@ int rsnd_get_slot_num(struct rsnd_dai_stream *io)
	return rdai->slots_num;
	return rdai->slots_num;
}
}


int rsnd_get_slot_width(struct rsnd_dai_stream *io)
int rsnd_runtime_channel_original(struct rsnd_dai_stream *io)
{
{
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	int chan = runtime->channels;


	/* Multi channel Mode */
	return runtime->channels;
	if (rsnd_ssi_multi_slaves_runtime(io))
}

int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io)
{
	int chan = rsnd_runtime_channel_original(io);
	struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io);

	if (ctu_mod) {
		u32 converted_chan = rsnd_ctu_converted_channel(ctu_mod);

		if (converted_chan)
			return converted_chan;
	}

	return chan;
}

int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io)
{
	int chan = rsnd_io_is_play(io) ?
		rsnd_runtime_channel_after_ctu(io) :
		rsnd_runtime_channel_original(io);

	/* Use Multi SSI */
	if (rsnd_runtime_is_ssi_multi(io))
		chan /= rsnd_get_slot_num(io);
		chan /= rsnd_get_slot_num(io);


	/* TDM Extend Mode needs 8ch */
	/* TDM Extend Mode needs 8ch */
@@ -240,6 +263,21 @@ int rsnd_get_slot_width(struct rsnd_dai_stream *io)
	return chan;
	return chan;
}
}


int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io)
{
	int slots = rsnd_get_slot_num(io);
	int chan = rsnd_io_is_play(io) ?
		rsnd_runtime_channel_after_ctu(io) :
		rsnd_runtime_channel_original(io);

	return (chan >= 6) && (slots > 1);
}

int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io)
{
	return rsnd_runtime_channel_for_ssi(io) >= 6;
}

/*
/*
 *	ADINR function
 *	ADINR function
 */
 */
@@ -261,29 +299,6 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
	return 0;
	return 0;
}
}


u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct device *dev = rsnd_priv_to_dev(priv);
	u32 chan = runtime->channels;

	switch (chan) {
	case 1:
	case 2:
	case 4:
	case 6:
	case 8:
		break;
	default:
		dev_warn(dev, "not supported channel\n");
		chan = 0;
		break;
	}

	return chan;
}

/*
/*
 *	DALIGN function
 *	DALIGN function
 */
 */
+1 −1
Original line number Original line Diff line number Diff line
@@ -60,7 +60,7 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
{
{
	rsnd_mod_write(mod, CTU_CTUIR, 1);
	rsnd_mod_write(mod, CTU_CTUIR, 1);


	rsnd_mod_write(mod, CTU_ADINR, rsnd_get_adinr_chan(mod, io));
	rsnd_mod_write(mod, CTU_ADINR, rsnd_runtime_channel_original(io));


	rsnd_mod_write(mod, CTU_CPMDR, 0);
	rsnd_mod_write(mod, CTU_CPMDR, 0);
	rsnd_mod_write(mod, CTU_SCMDR, 0);
	rsnd_mod_write(mod, CTU_SCMDR, 0);
+1 −1
Original line number Original line Diff line number Diff line
@@ -116,7 +116,7 @@ static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
	u32 vrdbr = 0;
	u32 vrdbr = 0;


	adinr = rsnd_get_adinr_bit(mod, io) |
	adinr = rsnd_get_adinr_bit(mod, io) |
		rsnd_get_adinr_chan(mod, io);
		rsnd_runtime_channel_after_ctu(io);


	/* Enable Digital Volume, Zero Cross Mute Mode */
	/* Enable Digital Volume, Zero Cross Mute Mode */
	dvucr |= 0x101;
	dvucr |= 0x101;
+1 −1
Original line number Original line Diff line number Diff line
@@ -51,7 +51,7 @@ static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
	rsnd_mod_write(mod, MIX_MIXIR, 1);
	rsnd_mod_write(mod, MIX_MIXIR, 1);


	/* General Information */
	/* General Information */
	rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
	rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));


	/* volume step */
	/* volume step */
	rsnd_mod_write(mod, MIX_MIXMR, 0);
	rsnd_mod_write(mod, MIX_MIXMR, 0);
+6 −2
Original line number Original line Diff line number Diff line
@@ -193,7 +193,6 @@ void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
		    u32 mask, u32 data);
		    u32 mask, u32 data);
u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);


/*
/*
@@ -356,9 +355,14 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai,
void rsnd_set_slot(struct rsnd_dai *rdai,
void rsnd_set_slot(struct rsnd_dai *rdai,
		   int slots, int slots_total);
		   int slots, int slots_total);
int rsnd_get_slot(struct rsnd_dai_stream *io);
int rsnd_get_slot(struct rsnd_dai_stream *io);
int rsnd_get_slot_width(struct rsnd_dai_stream *io);
int rsnd_get_slot_num(struct rsnd_dai_stream *io);
int rsnd_get_slot_num(struct rsnd_dai_stream *io);


int rsnd_runtime_channel_original(struct rsnd_dai_stream *io);
int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io);
int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io);
int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io);
int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io);

/*
/*
 *	R-Car sound DAI
 *	R-Car sound DAI
 */
 */
Loading