diff mbox series

[4/4] ASoC: rsnd: adjust disabled module

Message ID 875yyzk017.wl-kuninori.morimoto.gx@renesas.com (mailing list archive)
State Accepted
Commit c413983eb66a0f6de37c13f7da3dd5fa488e5967
Headers show
Series ASoC: rsnd: adjust disabled module for R-Car D3 | expand

Commit Message

Kuninori Morimoto May 31, 2021, 4:19 a.m. UTC
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

In general Renesas SoC's SSI/SRC are all enabled, but some SoC is not.

	H2	E2

	SRC0	      <=
	SRC1	SRC1
	SRC2	SRC2
	...	...

Renesas Sound driver is assuming that *all* modules are
enabled, and thus it is using *data array* to access each modules.
Because of it, we have been using "status = disabled" at DT,
and using *full size* array but avoiding disabled module.

ex)
	rcar_sound,src {
		src-0 {
=>			status = "disabled";
		};
		src1: src-1 {
			...
		};
		...

But R-Car D3 have many disabled modules (It has SSI3/SSI4, SRC5/SRC6),
and Renesas SoC maintainer don't want above style on DT.

ex)
	rcar_sound,src {
=>		src0: src-0 { status = "disabled"; };
=>		src1: src-1 { status = "disabled"; };
=>		src2: src-2 { status = "disabled"; };
=>		src3: src-3 { status = "disabled"; };
=>		src4: src-4 { status = "disabled"; };
		src5: src-5 {
			...
		};
		src6: src-6 {
			...
		};
	};

	rcar_sound,ssi {
=>		ssi0: ssi-0 { status = "disabled"; };
=>		ssi1: ssi-1 { status = "disabled"; };
=>		ssi2: ssi-2 { status = "disabled"; };
		ssi3: ssi-3 {
			...
		};
		ssi4: ssi-4 {
			...
		};
	};

To adjust it, it needs to care about related for_each_child_of_node()
loop on rsnd driver, and it is used from...

	> grep -l for_each_child_of_node sound/soc/sh/rcar/*
	sound/soc/sh/rcar/core.c
	sound/soc/sh/rcar/ctu.c
	sound/soc/sh/rcar/dma.c
	sound/soc/sh/rcar/dvc.c
	sound/soc/sh/rcar/mix.c
	sound/soc/sh/rcar/src.c
	sound/soc/sh/rcar/ssi.c
	sound/soc/sh/rcar/ssiu.c

This patch adjust to this situation.
By this patch, we can avoid disabled modules on DT

	rcar_sound,src {
		src5: src-5 {
			...
		};
		src6: src-6 {
			...
		};
	};

	rcar_sound,ssi {
		ssi3: ssi-3 {
			...
		};
		ssi4: ssi-4 {
			...
		};
	};

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/sh/rcar/core.c | 52 ++++++++++++++++++++++++++++++++++++++++
 sound/soc/sh/rcar/dma.c  |  2 ++
 sound/soc/sh/rcar/rsnd.h |  2 ++
 sound/soc/sh/rcar/src.c  |  4 +++-
 sound/soc/sh/rcar/ssi.c  |  6 ++++-
 sound/soc/sh/rcar/ssiu.c |  4 +++-
 6 files changed, 67 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index b50812c188ed..a4ed9d8f022a 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1142,6 +1142,8 @@  void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name,
 	for_each_child_of_node(node, np) {
 		struct rsnd_mod *mod;
 
+		i = rsnd_node_fixed_index(np, name, i);
+
 		mod = mod_get(priv, i);
 
 		if (np == playback)
@@ -1154,6 +1156,56 @@  void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name,
 	of_node_put(node);
 }
 
+int rsnd_node_fixed_index(struct device_node *node, char *name, int idx)
+{
+	char node_name[16];
+
+	/*
+	 * rsnd is assuming each device nodes are sequential numbering,
+	 * but some of them are not.
+	 * This function adjusts index for it.
+	 *
+	 * ex)
+	 * Normal case,		special case
+	 *	ssi-0
+	 *	ssi-1
+	 *	ssi-2
+	 *	ssi-3		ssi-3
+	 *	ssi-4		ssi-4
+	 *	...
+	 *
+	 * assume Max 64 node
+	 */
+	for (; idx < 64; idx++) {
+		snprintf(node_name, sizeof(node_name), "%s-%d", name, idx);
+
+		if (strncmp(node_name, of_node_full_name(node), sizeof(node_name)) == 0)
+			return idx;
+	}
+
+	return -EINVAL;
+}
+
+int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name)
+{
+	struct device *dev = rsnd_priv_to_dev(priv);
+	struct device_node *np;
+	int i;
+
+	i = 0;
+	for_each_child_of_node(node, np) {
+		i = rsnd_node_fixed_index(np, name, i);
+		if (i < 0) {
+			dev_err(dev, "strange node numbering (%s)",
+				of_node_full_name(node));
+			return 0;
+		}
+		i++;
+	}
+
+	return i;
+}
+
 static struct device_node *rsnd_dai_of_node(struct rsnd_priv *priv,
 					    int *is_graph)
 {
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index d581f1424185..82d16e037d9a 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -245,6 +245,8 @@  struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *nam
 	int i = 0;
 
 	for_each_child_of_node(of_node, np) {
+		i = rsnd_node_fixed_index(np, name, i);
+
 		if (i == rsnd_mod_id_raw(mod) && (!chan))
 			chan = of_dma_request_slave_channel(np, x);
 		i++;
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 256a11b67eed..b2fbe3bbaabd 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -465,6 +465,8 @@  void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name,
 		struct device_node *node,
 		struct device_node *playback,
 		struct device_node *capture);
+int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name);
+int rsnd_node_fixed_index(struct device_node *node, char *name, int idx);
 
 int rsnd_channel_normalization(int chan);
 #define rsnd_runtime_channel_original(io) \
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 9ccc959c9150..42a100c6303d 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -656,7 +656,7 @@  int rsnd_src_probe(struct rsnd_priv *priv)
 	if (!node)
 		return 0; /* not used is not error */
 
-	nr = of_get_child_count(node);
+	nr = rsnd_node_count(priv, node, SRC_NAME);
 	if (!nr) {
 		ret = -EINVAL;
 		goto rsnd_src_probe_done;
@@ -676,6 +676,8 @@  int rsnd_src_probe(struct rsnd_priv *priv)
 		if (!of_device_is_available(np))
 			goto skip;
 
+		i = rsnd_node_fixed_index(np, SRC_NAME, i);
+
 		src = rsnd_src_get(priv, i);
 
 		snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 4c91091518e3..27f34ca6059d 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -1117,6 +1117,8 @@  void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
 	for_each_child_of_node(node, np) {
 		struct rsnd_mod *mod;
 
+		i = rsnd_node_fixed_index(np, SSI_NAME, i);
+
 		mod = rsnd_ssi_mod_get(priv, i);
 
 		if (np == playback)
@@ -1160,7 +1162,7 @@  int rsnd_ssi_probe(struct rsnd_priv *priv)
 	if (!node)
 		return -EINVAL;
 
-	nr = of_get_child_count(node);
+	nr = rsnd_node_count(priv, node, SSI_NAME);
 	if (!nr) {
 		ret = -EINVAL;
 		goto rsnd_ssi_probe_done;
@@ -1180,6 +1182,8 @@  int rsnd_ssi_probe(struct rsnd_priv *priv)
 		if (!of_device_is_available(np))
 			goto skip;
 
+		i = rsnd_node_fixed_index(np, SSI_NAME, i);
+
 		ssi = rsnd_ssi_get(priv, i);
 
 		snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 819739e18465..5682c74bb7ff 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -472,6 +472,8 @@  void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
 		for_each_child_of_node(node, np) {
 			struct rsnd_mod *mod;
 
+			i = rsnd_node_fixed_index(np, SSIU_NAME, i);
+
 			mod = rsnd_ssiu_mod_get(priv, i);
 
 			if (np == playback)
@@ -509,7 +511,7 @@  int rsnd_ssiu_probe(struct rsnd_priv *priv)
 	 */
 	node = rsnd_ssiu_of_node(priv);
 	if (node)
-		nr = of_get_child_count(node);
+		nr = rsnd_node_count(priv, node, SSIU_NAME);
 	else
 		nr = priv->ssi_nr;