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

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

ASoC: rsnd: add TDM Extend Mode support



Renesas R-Car can out TDM by
1) 6ch x 1 DAI as TDM Extend Mode
2) 2ch x 4 x 1 DAI as TDM split Mode
3) 2ch x 3 DAI or
   2ch x 4 DAI as TDM Multichannel Mode

This patch adds 1) TDM Extend Mode. Because of HW design,
this 6ch data will be outputed via 8ch data width.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 42ab9a79
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -247,9 +247,9 @@ 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)
{
	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;
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	u32 chan = rsnd_get_slot_rdai(rdai);

	switch (chan) {
	case 1:
@@ -569,9 +569,31 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
	return 0;
}

static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
				     u32 tx_mask, u32 rx_mask,
				     int slots, int slot_width)
{
	struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
	struct device *dev = rsnd_priv_to_dev(priv);

	switch (slots) {
	case 6:
		/* TDM Extend Mode */
		rdai->slots = slots;
		break;
	default:
		dev_err(dev, "unsupported TDM slots (%d)\n", slots);
		return -EINVAL;
	}

	return 0;
}

static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
	.trigger	= rsnd_soc_dai_trigger,
	.set_fmt	= rsnd_soc_dai_set_fmt,
	.set_tdm_slot	= rsnd_soc_set_dai_tdm_slot,
};

static int rsnd_dai_probe(struct rsnd_priv *priv)
@@ -626,7 +648,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
		drv->playback.rates		= RSND_RATES;
		drv->playback.formats		= RSND_FMTS;
		drv->playback.channels_min	= 2;
		drv->playback.channels_max	= 2;
		drv->playback.channels_max	= 6;
		drv->playback.stream_name	= rdai->playback.name;

		snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE,
@@ -634,7 +656,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
		drv->capture.rates		= RSND_RATES;
		drv->capture.formats		= RSND_FMTS;
		drv->capture.channels_min	= 2;
		drv->capture.channels_max	= 2;
		drv->capture.channels_max	= 6;
		drv->capture.stream_name	= rdai->capture.name;

		rdai->playback.rdai		= rdai;
+1 −0
Original line number Diff line number Diff line
@@ -230,6 +230,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
		RSND_GEN_M_REG(SSI_BUSIF_MODE,	0x0,	0x80),
		RSND_GEN_M_REG(SSI_BUSIF_ADINR,	0x4,	0x80),
		RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8,	0x80),
		RSND_GEN_M_REG(SSI_MODE,	0xc,	0x80),
		RSND_GEN_M_REG(SSI_CTRL,	0x10,	0x80),
		RSND_GEN_M_REG(SSI_INT_ENABLE,	0x18,	0x80),
	};
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
 */
enum rsnd_reg {
	/* SCU (SRC/SSIU/MIX/CTU/DVC) */
	RSND_REG_SSI_MODE,		/* Gen2 only */
	RSND_REG_SSI_MODE0,
	RSND_REG_SSI_MODE1,
	RSND_REG_SSI_CTRL,		/* Gen2 only */
+17 −1
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@
#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_8		(0 << 19)	/* Data Word Length */
#define	DWL_16		(1 << 19)	/* Data Word Length */
#define	DWL_18		(2 << 19)	/* Data Word Length */
@@ -57,6 +59,7 @@
 * SSIWSR
 */
#define CONT		(1 << 8)	/* WS Continue Function */
#define WS_MODE		(1 << 0)	/* WS Mode */

#define SSI_NAME "ssi"

@@ -261,6 +264,7 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi,
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	u32 cr_own;
	u32 cr_mode;
	u32 wsr;

	/*
	 * always use 32bit system word.
@@ -297,8 +301,20 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi,
		cr_mode = DIEN;		/* PIO : enable Data interrupt */
	}

	/*
	 * TDM Extend Mode
	 * see
	 *	rsnd_ssiu_init_gen2()
	 */
	wsr = ssi->wsr;
	if (rsnd_get_slot_runtime(io) >= 6) {
		wsr	|= WS_MODE;
		cr_own	|= CHNL_8;
	}

	ssi->cr_own	= cr_own;
	ssi->cr_mode	= cr_mode;
	ssi->wsr	= wsr;

	return 0;
}
+9 −0
Original line number Diff line number Diff line
@@ -78,6 +78,15 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
	if (ret < 0)
		return ret;

	if (rsnd_get_slot_runtime(io) >= 6) {
		/*
		 * TDM Extend Mode
		 * see
		 *	rsnd_ssi_config_init()
		 */
		rsnd_mod_write(mod, SSI_MODE, 0x1);
	}

	if (rsnd_ssi_use_busif(io)) {
		u32 val = rsnd_get_dalign(mod, io);