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

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

ASoC: add Renesas R-Car SSI feature



Renesas R-Car series sound circuit consists of SSI and its peripheral.
But this peripheral circuit is different between
R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2)
(Actually, there are many difference in Generation1 chips)

As 1st protype, this patch adds SSI feature on this driver.
But, it is PIO sound playback support only at this point.
The DMA transfer, and capture feature will be supported in the future

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent dfc9403b
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -16,11 +16,30 @@

#define RSND_GEN1_SRU	0
#define RSND_GEN1_ADG	1
#define RSND_GEN1_SSI	2

#define RSND_GEN2_SRU	0
#define RSND_GEN2_ADG	1
#define RSND_GEN2_SSIU	2
#define RSND_GEN2_SSI	3

#define RSND_BASE_MAX	2
#define RSND_BASE_MAX	4

/*
 * flags
 *
 * 0xA0000000
 *
 * A : clock sharing settings
 */
#define RSND_SSI_CLK_PIN_SHARE		(1 << 31)
#define RSND_SSI_CLK_FROM_ADG		(1 << 30) /* clock parent is master */
#define RSND_SSI_SYNC			(1 << 29) /* SSI34_sync etc */

struct rsnd_ssi_platform_info {
	int pio_irq;
	u32 flags;
};

struct rsnd_scu_platform_info {
	u32 flags;
@@ -43,6 +62,8 @@ struct rsnd_dai_platform_info {

struct rcar_snd_info {
	u32 flags;
	struct rsnd_ssi_platform_info *ssi_info;
	int ssi_info_nr;
	struct rsnd_scu_platform_info *scu_info;
	int scu_info_nr;
	struct rsnd_dai_platform_info *dai_info;
+1 −1
Original line number Diff line number Diff line
snd-soc-rcar-objs	:= core.o gen.o scu.o adg.o
snd-soc-rcar-objs	:= core.o gen.o scu.o adg.o ssi.o
obj-$(CONFIG_SND_SOC_RCAR)	+= snd-soc-rcar.o
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -639,6 +639,10 @@ static int rsnd_probe(struct platform_device *pdev)
	if (ret < 0)
		return ret;

	ret = rsnd_ssi_probe(pdev, info, priv);
	if (ret < 0)
		return ret;

	/*
	 *	asoc register
	 */
@@ -677,6 +681,7 @@ static int rsnd_remove(struct platform_device *pdev)
	/*
	 *	remove each module
	 */
	rsnd_ssi_remove(pdev, priv);
	rsnd_adg_remove(pdev, priv);
	rsnd_scu_remove(pdev, priv);
	rsnd_dai_remove(pdev, priv);
+22 −2
Original line number Diff line number Diff line
@@ -72,6 +72,12 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv,
	else
		id = info->ssi_id_capture;

	/* SSI */
	mod = rsnd_ssi_mod_get(priv, id);
	ret = rsnd_dai_connect(rdai, mod, io);
	if (ret < 0)
		return ret;

	/* SCU */
	mod = rsnd_scu_mod_get(priv, id);
	ret = rsnd_dai_connect(rdai, mod, io);
@@ -120,6 +126,12 @@ static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen)
	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL3,	0x0,	0x18);
	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL4,	0x0,	0x1c);
	RSND_GEN1_REG_MAP(gen, ADG,	AUDIO_CLK_SEL5,	0x0,	0x20);

	RSND_GEN1_REG_MAP(gen, SSI,	SSICR,		0x40,	0x00);
	RSND_GEN1_REG_MAP(gen, SSI,	SSISR,		0x40,	0x04);
	RSND_GEN1_REG_MAP(gen, SSI,	SSITDR,		0x40,	0x08);
	RSND_GEN1_REG_MAP(gen, SSI,	SSIRDR,		0x40,	0x0c);
	RSND_GEN1_REG_MAP(gen, SSI,	SSIWSR,		0x40,	0x20);
}

static int rsnd_gen1_probe(struct platform_device *pdev,
@@ -130,14 +142,17 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
	struct resource *sru_res;
	struct resource *adg_res;
	struct resource *ssi_res;

	/*
	 * map address
	 */
	sru_res	= platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU);
	adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG);
	ssi_res	= platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI);
	if (!sru_res ||
	    !adg_res) {
	    !adg_res ||
	    !ssi_res) {
		dev_err(dev, "Not enough SRU/SSI/ADG platform resources.\n");
		return -ENODEV;
	}
@@ -146,8 +161,10 @@ static int rsnd_gen1_probe(struct platform_device *pdev,

	gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res);
	gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res);
	gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res);
	if (!gen->base[RSND_GEN1_SRU] ||
	    !gen->base[RSND_GEN1_ADG]) {
	    !gen->base[RSND_GEN1_ADG] ||
	    !gen->base[RSND_GEN1_SSI]) {
		dev_err(dev, "SRU/SSI/ADG ioremap failed\n");
		return -ENODEV;
	}
@@ -159,8 +176,11 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
						gen->base[RSND_GEN1_SRU]);
	dev_dbg(dev, "ADG : %08x => %p\n",	adg_res->start,
						gen->base[RSND_GEN1_ADG]);
	dev_dbg(dev, "SSI : %08x => %p\n",	ssi_res->start,
						gen->base[RSND_GEN1_SSI]);

	return 0;

}

static void rsnd_gen1_remove(struct platform_device *pdev,
+23 −0
Original line number Diff line number Diff line
@@ -43,6 +43,13 @@ enum rsnd_reg {
	RSND_REG_AUDIO_CLK_SEL4,
	RSND_REG_AUDIO_CLK_SEL5,

	/* SSI */
	RSND_REG_SSICR,
	RSND_REG_SSISR,
	RSND_REG_SSITDR,
	RSND_REG_SSIRDR,
	RSND_REG_SSIWSR,

	RSND_REG_MAX,
};

@@ -151,6 +158,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod,
		     struct rsnd_dai_stream *io);
int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
#define rsnd_io_to_runtime(io) ((io)->substream->runtime)

void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
@@ -209,6 +217,11 @@ struct rsnd_priv {
	 */
	void *adg;

	/*
	 * below value will be filled on rsnd_ssi_probe()
	 */
	void *ssiu;

	/*
	 * below value will be filled on rsnd_dai_probe()
	 */
@@ -232,4 +245,14 @@ void rsnd_scu_remove(struct platform_device *pdev,
struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id);
#define rsnd_scu_nr(priv) ((priv)->scu_nr)

/*
 *	R-Car SSI
 */
int rsnd_ssi_probe(struct platform_device *pdev,
		   struct rcar_snd_info *info,
		   struct rsnd_priv *priv);
void rsnd_ssi_remove(struct platform_device *pdev,
		   struct rsnd_priv *priv);
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);

#endif
Loading