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

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

ASoC: rsnd: tidyup data align position



Sound L/R order of SSI is different from Linux sound data order.
So current rsnd driver is using DALIGN (= data align) to exchange data
align on SSIU. OTOH, CMD/SRC/SSIU have DALIGN register. Now inverted
sound volume will be exchanged if user used volume control on DVC.
Because SSIU which exchanges data align is located after DVC.

	MEM -> SRC -> DVC -> SSI

This patch exchanges data align SRC if possible

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: default avatarKeita Kobayashi <keita.kobayashi.ym@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent bfe1360d
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -249,6 +249,42 @@ u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)

	return chan;
}

/*
 *	DALIGN function
 */
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
{
	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *target = src ? src : ssi;
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	u32 val = 0x76543210;
	u32 mask = ~0;

	mask <<= runtime->channels * 4;
	val = val & mask;

	switch (runtime->sample_bits) {
	case 16:
		val |= 0x67452301 & ~mask;
		break;
	case 32:
		val |= 0x76543210 & ~mask;
		break;
	}

	/*
	 * exchange channeles on SRC if possible,
	 * otherwise, R/L volume settings on DVC
	 * changes inverted channels
	 */
	if (mod == target)
		return val;
	else
		return 0x76543210;
}

/*
 *	rsnd_dai functions
 */
+1 −0
Original line number Diff line number Diff line
@@ -222,6 +222,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
	};
	struct rsnd_regmap_field_conf conf_scu[] = {
		RSND_GEN_M_REG(SRC_BUSIF_MODE,	0x0,	0x20),
		RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8,	0x20),
		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),
+3 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ enum rsnd_reg {
	RSND_REG_SHARE26,
	RSND_REG_SHARE27,
	RSND_REG_SHARE28,
	RSND_REG_SHARE29,

	RSND_REG_MAX,
};
@@ -143,6 +144,7 @@ enum rsnd_reg {
#define RSND_REG_SCU_SYS_STATUS1	RSND_REG_SHARE26
#define RSND_REG_SCU_SYS_INT_EN1	RSND_REG_SHARE27
#define RSND_REG_SRC_INT_ENABLE0	RSND_REG_SHARE28
#define RSND_REG_SRC_BUSIF_DALIGN	RSND_REG_SHARE29

struct rsnd_of_data;
struct rsnd_priv;
@@ -171,6 +173,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_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
void rsnd_path_parse(struct rsnd_priv *priv,
		     struct rsnd_dai_stream *io);

+5 −15
Original line number Diff line number Diff line
@@ -148,7 +148,6 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
			int use_busif)
{
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	int ssi_id = rsnd_mod_id(ssi_mod);

	/*
@@ -185,27 +184,14 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
	 * DMA settings for SSIU
	 */
	if (use_busif) {
		u32 val = 0x76543210;
		u32 mask = ~0;
		u32 val = rsnd_get_dalign(ssi_mod, io);

		rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
			       rsnd_get_adinr_bit(ssi_mod, io));
		rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE,  1);
		rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);

		mask <<= runtime->channels * 4;
		val = val & mask;

		switch (runtime->sample_bits) {
		case 16:
			val |= 0x67452301 & ~mask;
			break;
		case 32:
			val |= 0x76543210 & ~mask;
			break;
		}
		rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);

	}

	return 0;
@@ -678,6 +664,10 @@ static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	u32 val;

	val = rsnd_get_dalign(mod, io);

	rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val);

	/*
	 * WORKAROUND
	 *