diff mbox

[LTSI-3.14,045/894] ASoC: rsnd: extracts Gen1/Gen2 common parts

Message ID 1409209620-24487-46-git-send-email-horms+renesas@verge.net.au (mailing list archive)
State New, archived
Headers show

Commit Message

Simon Horman Aug. 28, 2014, 6:52 a.m. UTC
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Renesas sound IP Gen1/Gen2 are similar, but different.
This patch extracts Gen1/Gen2 common and dependency parts,
and create Gen1/Gen2 ops to control it.

According to this structure, SSIU setup which
has been implemented on ssi.c can be moved to scu.c
(SRU/SSIU/SCU should be implemented on scu.c)

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
(cherry picked from commit 1b7b08efbe7419cc3e082f2b5ec8ae89f7af43d1)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 sound/soc/sh/rcar/rsnd.h |   2 +-
 sound/soc/sh/rcar/scu.c  | 336 ++++++++++++++++++++++++++++-------------------
 sound/soc/sh/rcar/ssi.c  |   5 -
 3 files changed, 205 insertions(+), 138 deletions(-)
diff mbox

Patch

diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index b1874eb..c397dc8 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -48,7 +48,7 @@  enum rsnd_reg {
 	RSND_REG_SRC_IFSCR,
 	RSND_REG_SRC_IFSVR,
 	RSND_REG_SRC_SRCCR,
-	RSND_REG_SRC_MNFSR,
+	RSND_REG_SRC_MNFSR,		/* for Gen1 */
 
 	/* ADG */
 	RSND_REG_BRRA,
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
index e2ffcc4..29d8990 100644
--- a/sound/soc/sh/rcar/scu.c
+++ b/sound/soc/sh/rcar/scu.c
@@ -110,6 +110,9 @@  struct rsnd_scu {
  *
  */
 
+/*
+ *		Gen1/Gen2 common functions
+ */
 static int rsnd_scu_ssi_mode_init(struct rsnd_mod *mod,
 				  struct rsnd_dai *rdai,
 				  struct rsnd_dai_stream *io)
@@ -151,11 +154,145 @@  static int rsnd_scu_ssi_mode_init(struct rsnd_mod *mod,
 	return 0;
 }
 
-/* Gen1 only */
-static int rsnd_src_set_route_if_gen1(
-			      struct rsnd_mod *mod,
-			      struct rsnd_dai *rdai,
-			      struct rsnd_dai_stream *io)
+unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
+				   struct rsnd_mod *ssi_mod,
+				   struct snd_pcm_runtime *runtime)
+{
+	struct rsnd_scu *scu;
+	unsigned int rate;
+
+	/* this function is assuming SSI id = SCU id here */
+	scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod)));
+
+	/*
+	 * return convert rate if SRC is used,
+	 * otherwise, return runtime->rate as usual
+	 */
+	rate = rsnd_scu_convert_rate(scu);
+	if (!rate)
+		rate = runtime->rate;
+
+	return rate;
+}
+
+static int rsnd_scu_set_convert_rate(struct rsnd_mod *mod,
+				     struct rsnd_dai *rdai,
+				     struct rsnd_dai_stream *io)
+{
+	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
+	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
+	u32 convert_rate = rsnd_scu_convert_rate(scu);
+	u32 adinr = runtime->channels;
+	u32 fsrate = 0;
+
+	if (convert_rate)
+		fsrate = 0x0400000 / convert_rate * runtime->rate;
+
+	/* set/clear soft reset */
+	rsnd_mod_write(mod, SRC_SWRSR, 0);
+	rsnd_mod_write(mod, SRC_SWRSR, 1);
+
+	/*
+	 * Initialize the operation of the SRC internal circuits
+	 * see rsnd_scu_start()
+	 */
+	rsnd_mod_write(mod, SRC_SRCIR, 1);
+
+	/* Set channel number and output bit length */
+	switch (runtime->sample_bits) {
+	case 16:
+		adinr |= OTBL_16;
+		break;
+	case 32:
+		adinr |= OTBL_24;
+		break;
+	default:
+		return -EIO;
+	}
+	rsnd_mod_write(mod, SRC_ADINR, adinr);
+
+	/* Enable the initial value of IFS */
+	if (fsrate) {
+		rsnd_mod_write(mod, SRC_IFSCR, 1);
+
+		/* Set initial value of IFS */
+		rsnd_mod_write(mod, SRC_IFSVR, fsrate);
+	}
+
+	/* use DMA transfer */
+	rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
+
+	return 0;
+}
+
+static int rsnd_scu_init(struct rsnd_mod *mod,
+			 struct rsnd_dai *rdai,
+			 struct rsnd_dai_stream *io)
+{
+	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
+	int ret;
+
+	clk_enable(scu->clk);
+
+	ret = rsnd_scu_ssi_mode_init(mod, rdai, io);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int rsnd_scu_quit(struct rsnd_mod *mod,
+			 struct rsnd_dai *rdai,
+			 struct rsnd_dai_stream *io)
+{
+	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
+
+	clk_disable(scu->clk);
+
+	return 0;
+}
+
+static int rsnd_scu_start(struct rsnd_mod *mod,
+			  struct rsnd_dai *rdai,
+			  struct rsnd_dai_stream *io)
+{
+	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
+
+	/*
+	 * Cancel the initialization and operate the SRC function
+	 * see rsnd_scu_set_convert_rate()
+	 */
+	rsnd_mod_write(mod, SRC_SRCIR, 0);
+
+	if (rsnd_scu_convert_rate(scu))
+		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
+
+	return 0;
+}
+
+
+static int rsnd_scu_stop(struct rsnd_mod *mod,
+			 struct rsnd_dai *rdai,
+			 struct rsnd_dai_stream *io)
+{
+	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
+
+	if (rsnd_scu_convert_rate(scu))
+		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
+
+	return 0;
+}
+
+static struct rsnd_mod_ops rsnd_scu_non_ops = {
+	.name	= "scu (non)",
+};
+
+/*
+ *		Gen1 functions
+ */
+static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
+				   struct rsnd_dai *rdai,
+				   struct rsnd_dai_stream *io)
 {
 	struct scu_route_config {
 		u32 mask;
@@ -171,17 +308,10 @@  static int rsnd_src_set_route_if_gen1(
 		{ 0x3, 28, }, /* 7 */
 		{ 0x3, 30, }, /* 8 */
 	};
-	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 	u32 mask;
 	u32 val;
 	int id;
 
-	/*
-	 * Gen1 only
-	 */
-	if (!rsnd_is_gen1(priv))
-		return 0;
-
 	id = rsnd_mod_id(mod);
 	if (id < 0 || id >= ARRAY_SIZE(routes))
 		return -EIO;
@@ -257,104 +387,43 @@  static int rsnd_scu_set_convert_timing_gen1(struct rsnd_mod *mod,
 	return 0;
 }
 
-unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
-				   struct rsnd_mod *ssi_mod,
-				   struct snd_pcm_runtime *runtime)
-{
-	struct rsnd_scu *scu;
-	unsigned int rate;
-
-	/* this function is assuming SSI id = SCU id here */
-	scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod)));
-
-	/*
-	 * return convert rate if SRC is used,
-	 * otherwise, return runtime->rate as usual
-	 */
-	rate = rsnd_scu_convert_rate(scu);
-	if (!rate)
-		rate = runtime->rate;
-
-	return rate;
-}
-
-static int rsnd_scu_set_convert_rate(struct rsnd_mod *mod,
-				     struct rsnd_dai *rdai,
-				     struct rsnd_dai_stream *io)
+static int rsnd_scu_set_convert_rate_gen1(struct rsnd_mod *mod,
+					  struct rsnd_dai *rdai,
+					  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 rsnd_scu *scu = rsnd_mod_to_scu(mod);
-	u32 convert_rate = rsnd_scu_convert_rate(scu);
-	u32 adinr = runtime->channels;
-
-	/* set/clear soft reset */
-	rsnd_mod_write(mod, SRC_SWRSR, 0);
-	rsnd_mod_write(mod, SRC_SWRSR, 1);
-
-	/* Initialize the operation of the SRC internal circuits */
-	rsnd_mod_write(mod, SRC_SRCIR, 1);
-
-	/* Set channel number and output bit length */
-	switch (runtime->sample_bits) {
-	case 16:
-		adinr |= OTBL_16;
-		break;
-	case 32:
-		adinr |= OTBL_24;
-		break;
-	default:
-		return -EIO;
-	}
-	rsnd_mod_write(mod, SRC_ADINR, adinr);
-
-	if (convert_rate) {
-		u32 fsrate = 0x0400000 / convert_rate * runtime->rate;
-
-		/* Enable the initial value of IFS */
-		rsnd_mod_write(mod, SRC_IFSCR, 1);
-
-		/* Set initial value of IFS */
-		rsnd_mod_write(mod, SRC_IFSVR, fsrate);
-
-		/* Select SRC mode (fixed value) */
-		rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
+	int ret;
 
-		/* Set the restriction value of the FS ratio (98%) */
-		rsnd_mod_write(mod, SRC_MNFSR, fsrate / 100 * 98);
+	ret = rsnd_scu_set_convert_rate(mod, rdai, io);
+	if (ret < 0)
+		return ret;
 
-		if (rsnd_is_gen1(priv)) {
-			/* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
-		}
-	}
+	/* Select SRC mode (fixed value) */
+	rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
 
-	/* Cancel the initialization and operate the SRC function */
-	rsnd_mod_write(mod, SRC_SRCIR, 0);
+	/* Set the restriction value of the FS ratio (98%) */
+	rsnd_mod_write(mod, SRC_MNFSR,
+		       rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
 
-	/* use DMA transfer */
-	rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
+	/* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
 
 	return 0;
 }
 
-static int rsnd_scu_init(struct rsnd_mod *mod,
-			  struct rsnd_dai *rdai,
-			  struct rsnd_dai_stream *io)
+static int rsnd_scu_init_gen1(struct rsnd_mod *mod,
+			      struct rsnd_dai *rdai,
+			      struct rsnd_dai_stream *io)
 {
-	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
 	int ret;
 
-	clk_enable(scu->clk);
-
-	ret = rsnd_scu_ssi_mode_init(mod, rdai, io);
+	ret = rsnd_scu_init(mod, rdai, io);
 	if (ret < 0)
 		return ret;
 
-	ret = rsnd_src_set_route_if_gen1(mod, rdai, io);
+	ret = rsnd_src_set_route_gen1(mod, rdai, io);
 	if (ret < 0)
 		return ret;
 
-	ret = rsnd_scu_set_convert_rate(mod, rdai, io);
+	ret = rsnd_scu_set_convert_rate_gen1(mod, rdai, io);
 	if (ret < 0)
 		return ret;
 
@@ -365,62 +434,58 @@  static int rsnd_scu_init(struct rsnd_mod *mod,
 	return 0;
 }
 
-static int rsnd_scu_quit(struct rsnd_mod *mod,
-			 struct rsnd_dai *rdai,
-			 struct rsnd_dai_stream *io)
+static int rsnd_scu_start_gen1(struct rsnd_mod *mod,
+			       struct rsnd_dai *rdai,
+			       struct rsnd_dai_stream *io)
 {
-	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
+	int id = rsnd_mod_id(mod);
 
-	clk_disable(scu->clk);
+	rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
 
-	return 0;
+	return rsnd_scu_start(mod, rdai, io);
 }
 
-static int rsnd_scu_start(struct rsnd_mod *mod,
-			  struct rsnd_dai *rdai,
-			  struct rsnd_dai_stream *io)
+static int rsnd_scu_stop_gen1(struct rsnd_mod *mod,
+			      struct rsnd_dai *rdai,
+			      struct rsnd_dai_stream *io)
 {
-	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
 	int id = rsnd_mod_id(mod);
 
-	if (rsnd_is_gen1(priv))
-		rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
-
-	if (rsnd_scu_convert_rate(scu))
-		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
+	rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
 
-	return 0;
+	return rsnd_scu_stop(mod, rdai, io);
 }
 
-static int rsnd_scu_stop(struct rsnd_mod *mod,
-			  struct rsnd_dai *rdai,
-			  struct rsnd_dai_stream *io)
-{
-	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-	struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
-	int id = rsnd_mod_id(mod);
+static struct rsnd_mod_ops rsnd_scu_gen1_ops = {
+	.name	= "sru (gen1)",
+	.init	= rsnd_scu_init_gen1,
+	.quit	= rsnd_scu_quit,
+	.start	= rsnd_scu_start_gen1,
+	.stop	= rsnd_scu_stop_gen1,
+};
 
-	if (rsnd_is_gen1(priv))
-		rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
+static struct rsnd_mod_ops rsnd_scu_non_gen1_ops = {
+	.name	= "non-sru (gen1)",
+	.init	= rsnd_scu_ssi_mode_init,
+};
 
-	if (rsnd_scu_convert_rate(scu))
-		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
+/*
+ *		Gen2 functions
+ */
+static int rsnd_scu_start_non_gen2(struct rsnd_mod *mod,
+				   struct rsnd_dai *rdai,
+				   struct rsnd_dai_stream *io)
+{
+	/* enable PIO interrupt */
+	rsnd_mod_write(mod, INT_ENABLE, 0x0f000000);
 
 	return 0;
 }
 
-static struct rsnd_mod_ops rsnd_scu_ops = {
-	.name	= "scu",
-	.init	= rsnd_scu_init,
-	.quit	= rsnd_scu_quit,
-	.start	= rsnd_scu_start,
-	.stop	= rsnd_scu_stop,
-};
-
-static struct rsnd_mod_ops rsnd_scu_non_ops = {
-	.name	= "scu (non)",
+static struct rsnd_mod_ops rsnd_scu_non_gen2_ops = {
+	.name	= "non-scu (gen2)",
 	.init	= rsnd_scu_ssi_mode_init,
+	.start	= rsnd_scu_start_non_gen2,
 };
 
 struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id)
@@ -466,8 +531,15 @@  int rsnd_scu_probe(struct platform_device *pdev,
 		scu->clk = clk;
 
 		ops = &rsnd_scu_non_ops;
-		if (rsnd_scu_hpbif_is_enable(scu))
-			ops = &rsnd_scu_ops;
+		if (rsnd_scu_hpbif_is_enable(scu)) {
+			if (rsnd_is_gen1(priv))
+				ops = &rsnd_scu_gen1_ops;
+		} else {
+			if (rsnd_is_gen1(priv))
+				ops = &rsnd_scu_non_gen1_ops;
+			if (rsnd_is_gen2(priv))
+				ops = &rsnd_scu_non_gen2_ops;
+		}
 
 		rsnd_mod_init(priv, &scu->mod, ops, i);
 
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index bae309c..b7f464e 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -363,16 +363,11 @@  static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
 			      struct rsnd_dai *rdai,
 			      struct rsnd_dai_stream *io)
 {
-	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
 
 	/* enable PIO IRQ */
 	ssi->cr_etc = UIEN | OIEN | DIEN;
 
-	/* enable PIO interrupt if gen2 */
-	if (rsnd_is_gen2(priv))
-		rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000);
-
 	rsnd_ssi_hw_start(ssi, rdai, io);
 
 	return 0;