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

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

ASoC: rsnd: SSI + DMA can select BUSIF



Sound data needs to be sent to R-Car sound SSI when playback.
But, there are 2 interfaces for it.
1st is SSITDR/SSIRDR which are mapped on SSI.
2nd is SSIn_BUSIF which are mapped on SSIU.

2nd SSIn_BUSIF is used when DMA transfer,
and it is always used if sound data came from via SRC.
But, we can use it when SSI+DMA case too.
(Current driver is assuming 1st SSITDR/SSIRDR for it)

2nd SSIn_BUSIF can be used as FIFO.
This is very helpful/useful for SSI+DMA.

But DMA address / DMA ID are not same between 1st/2nd cases.
This patch care about these settings.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 8457e0e9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ SSI subnode properties:
- interrupts			: Should contain SSI interrupt for PIO transfer
- shared-pin			: if shared clock pin
- pio-transfer			: use PIO transfer mode
- no-busif			: BUSIF is not ussed when [mem -> SSI] via DMA case

SRC subnode properties:
no properties at this point
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
 * B : SSI direction
 */
#define RSND_SSI_CLK_PIN_SHARE		(1 << 31)
#define RSND_SSI_NO_BUSIF		(1 << 30) /* SSI+DMA without BUSIF */

#define RSND_SSI(_dma_id, _pio_irq, _flags)		\
{ .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags }
+14 −8
Original line number Diff line number Diff line
@@ -138,6 +138,17 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
	return mod->ops->name;
}

char *rsnd_mod_dma_name(struct rsnd_mod *mod)
{
	if (!mod || !mod->ops)
		return "unknown";

	if (!mod->ops->dma_name)
		return mod->ops->name;

	return mod->ops->dma_name(mod);
}

void rsnd_mod_init(struct rsnd_priv *priv,
		   struct rsnd_mod *mod,
		   struct rsnd_mod_ops *ops,
@@ -261,7 +272,7 @@ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
{
	if (mod)
		return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
			 rsnd_mod_name(mod), rsnd_mod_id(mod));
			 rsnd_mod_dma_name(mod), rsnd_mod_id(mod));
	else
		return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");

@@ -343,11 +354,8 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	if (dev->of_node)
	rsnd_dma_of_name(dma, is_play, dma_name);
	else
		snprintf(dma_name, DMA_NAME_SIZE,
			 is_play ? "tx" : "rx");
	rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id);

	dev_dbg(dev, "dma name : %s\n", dma_name);

@@ -359,8 +367,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
		return -EIO;
	}

	rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id);

	ret = dmaengine_slave_config(dma->chan, &cfg);
	if (ret < 0)
		goto rsnd_dma_init_err;
+41 −23
Original line number Diff line number Diff line
@@ -165,15 +165,19 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
 *
 *	ex) R-Car H2 case
 *	      mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
 *	SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000
 *	SSI : 0xec541000 / 0xec241008 / 0xec24100c
 *	SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
 *	SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
 *	CMD : 0xec500000 / 0xec008000                             0xec308000
 */
#define RDMA_SSI_I_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
#define RDMA_SSI_O_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)

#define RDMA_SSI_I_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
#define RDMA_SSI_O_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
#define RDMA_SSIU_I_N(addr, i)	(addr ##_reg - 0x00441000 + (0x1000 * i))
#define RDMA_SSIU_O_N(addr, i)	(addr ##_reg - 0x00441000 + (0x1000 * i))

#define RDMA_SSIU_I_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
#define RDMA_SSIU_O_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))

#define RDMA_SRC_I_N(addr, i)	(addr ##_reg - 0x00500000 + (0x400 * i))
#define RDMA_SRC_O_N(addr, i)	(addr ##_reg - 0x004fc000 + (0x400 * i))
@@ -204,26 +208,36 @@ static void rsnd_gen2_dma_addr(struct rsnd_priv *priv,
	struct dma_addr {
		dma_addr_t src_addr;
		dma_addr_t dst_addr;
	} dma_addrs[2][2][3] = {
		{ /* SRC */
	} dma_addrs[3][2][3] = {
		/* SRC */
		{{{ 0,				0 },
		/* Capture */
			{{ 0,				0 },
		  { RDMA_SRC_O_N(src, id),	0 },
		  { RDMA_CMD_O_N(src, id),	0 } },
		 /* Playback */
		 {{ 0,				0, },
		  { 0,				RDMA_SRC_I_N(src, id) },
		  { 0,				RDMA_SRC_I_N(src, id) } }
		}, { /* SSI */
		},
		/* SSI */
		/* Capture */
			{{ RDMA_SSI_O_N(ssi, id),	0 },
			 { RDMA_SSI_O_P(ssi, id),	RDMA_SRC_I_P(src, id) },
			 { RDMA_SSI_O_P(ssi, id),	RDMA_SRC_I_P(src, id) }},
		{{{ RDMA_SSI_O_N(ssi, id),	0 },
		  { 0,				0 },
		  { 0,				0 } },
		 /* Playback */
		 {{ 0,				RDMA_SSI_I_N(ssi, id) },
			 { RDMA_SRC_O_P(src, id),	RDMA_SSI_I_P(ssi, id) },
			 { RDMA_CMD_O_P(src, id),	RDMA_SSI_I_P(ssi, id) }}
		}
		  { 0,				0 },
		  { 0,				0 } }
		},
		/* SSIU */
		/* Capture */
		{{{ RDMA_SSIU_O_N(ssi, id),	0 },
		  { RDMA_SSIU_O_P(ssi, id),	RDMA_SRC_I_P(src, id) },
		  { RDMA_SSIU_O_P(ssi, id),	RDMA_SRC_I_P(src, id) } },
		 /* Playback */
		 {{ 0,				RDMA_SSIU_I_N(ssi, id) },
		  { RDMA_SRC_O_P(src, id),	RDMA_SSIU_I_P(ssi, id) },
		  { RDMA_CMD_O_P(src, id),	RDMA_SSIU_I_P(ssi, id) } } },
	};

	/* it shouldn't happen */
@@ -232,6 +246,10 @@ static void rsnd_gen2_dma_addr(struct rsnd_priv *priv,
		return;
	}

	/* use SSIU or SSI ? */
	if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu")))
		is_ssi++;

	cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr;
	cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr;

+8 −2
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ enum rsnd_mod_type {

struct rsnd_mod_ops {
	char *name;
	char* (*dma_name)(struct rsnd_mod *mod);
	int (*probe)(struct rsnd_mod *mod,
		     struct rsnd_dai *rdai);
	int (*remove)(struct rsnd_mod *mod,
@@ -224,6 +225,7 @@ void rsnd_mod_init(struct rsnd_priv *priv,
		   enum rsnd_mod_type type,
		   int id);
char *rsnd_mod_name(struct rsnd_mod *mod);
char *rsnd_mod_dma_name(struct rsnd_mod *mod);

/*
 *	R-Car sound DAI
@@ -391,8 +393,12 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
				   struct rsnd_dai_stream *io,
				   struct snd_pcm_runtime *runtime);
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
			   struct rsnd_dai *rdai);
int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
			struct rsnd_dai *rdai,
			int use_busif);
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
		       struct rsnd_dai *rdai,
		       int use_busif);
int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
			    struct rsnd_dai *rdai);

Loading