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

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

ASoC: rsnd: don't use PDTA bit for 24bit on SSI



Current SSI uses PDTA bit which indicates data that Input/Output
data are Right-Aligned. But, 24bit sound should be Left-Aligned
in this HW. Because Linux is using Right-Aligned data, and HW uses
Left-Aligned data, current 24bit data is missing lower 8bit.
To fix this issue, this patch removes PDTA bit, and shift 8bit
in necessary module

Reported-by: default avatarHiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: default avatarHiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2ea659a9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod,
	dev_dbg(dev, "ctu/mix path = 0x%08x", data);

	rsnd_mod_write(mod, CMD_ROUTE_SLCT, data);
	rsnd_mod_write(mod, CMD_BUSIF_MODE, rsnd_get_busif_shift(io, mod) | 1);
	rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io));

	rsnd_adg_set_cmd_timsel_gen2(mod, io);
+51 −0
Original line number Diff line number Diff line
@@ -343,6 +343,57 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
		return 0x76543210;
}

u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
{
	enum rsnd_mod_type playback_mods[] = {
		RSND_MOD_SRC,
		RSND_MOD_CMD,
		RSND_MOD_SSIU,
	};
	enum rsnd_mod_type capture_mods[] = {
		RSND_MOD_CMD,
		RSND_MOD_SRC,
		RSND_MOD_SSIU,
	};
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_mod *tmod = NULL;
	enum rsnd_mod_type *mods =
		rsnd_io_is_play(io) ?
		playback_mods : capture_mods;
	int i;

	/*
	 * This is needed for 24bit data
	 * We need to shift 8bit
	 *
	 * Linux 24bit data is located as 0x00******
	 * HW    24bit data is located as 0x******00
	 *
	 */
	switch (runtime->sample_bits) {
	case 16:
		return 0;
	case 32:
		break;
	}

	for (i = 0; i < ARRAY_SIZE(playback_mods); i++) {
		tmod = rsnd_io_to_mod(io, mods[i]);
		if (tmod)
			break;
	}

	if (tmod != mod)
		return 0;

	if (rsnd_io_is_play(io))
		return  (0 << 20) | /* shift to Left */
			(8 << 16);  /* 8bit */
	else
		return  (1 << 20) | /* shift to Right */
			(8 << 16);  /* 8bit */
}

/*
 *	rsnd_dai functions
 */
+1 −0
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
		RSND_GEN_M_REG(SRC_ROUTE_MODE0,	0xc,	0x20),
		RSND_GEN_M_REG(SRC_CTRL,	0x10,	0x20),
		RSND_GEN_M_REG(SRC_INT_ENABLE0,	0x18,	0x20),
		RSND_GEN_M_REG(CMD_BUSIF_MODE,	0x184,	0x20),
		RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188,	0x20),
		RSND_GEN_M_REG(CMD_ROUTE_SLCT,	0x18c,	0x20),
		RSND_GEN_M_REG(CMD_CTRL,	0x190,	0x20),
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ enum rsnd_reg {
	RSND_REG_SCU_SYS_INT_EN0,
	RSND_REG_SCU_SYS_INT_EN1,
	RSND_REG_CMD_CTRL,
	RSND_REG_CMD_BUSIF_MODE,
	RSND_REG_CMD_BUSIF_DALIGN,
	RSND_REG_CMD_ROUTE_SLCT,
	RSND_REG_CMDOUT_TIMSEL,
@@ -204,6 +205,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
		    u32 mask, u32 data);
u32 rsnd_get_adinr_bit(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_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);

/*
 *	R-Car DMA
+10 −2
Original line number Diff line number Diff line
@@ -190,11 +190,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	int is_play = rsnd_io_is_play(io);
	int use_src = 0;
	u32 fin, fout;
	u32 ifscr, fsrate, adinr;
	u32 cr, route;
	u32 bsdsr, bsisr;
	u32 i_busif, o_busif, tmp;
	uint ratio;

	if (!runtime)
@@ -270,6 +272,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
		break;
	}

	/* BUSIF_MODE */
	tmp = rsnd_get_busif_shift(io, mod);
	i_busif = ( is_play ? tmp : 0) | 1;
	o_busif = (!is_play ? tmp : 0) | 1;

	rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);

	rsnd_mod_write(mod, SRC_SRCIR, 1);	/* initialize */
@@ -281,8 +288,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
	rsnd_mod_write(mod, SRC_BSISR, bsisr);
	rsnd_mod_write(mod, SRC_SRCIR, 0);	/* cancel initialize */

	rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1);
	rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1);
	rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
	rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif);

	rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));

	rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
Loading