Commit c413983e authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: rsnd: adjust disabled module

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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/875yyzk017.wl-kuninori.morimoto.gx@renesas.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 73919dbe
...@@ -1142,6 +1142,8 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, ...@@ -1142,6 +1142,8 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name,
for_each_child_of_node(node, np) { for_each_child_of_node(node, np) {
struct rsnd_mod *mod; struct rsnd_mod *mod;
i = rsnd_node_fixed_index(np, name, i);
mod = mod_get(priv, i); mod = mod_get(priv, i);
if (np == playback) if (np == playback)
...@@ -1154,6 +1156,56 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, ...@@ -1154,6 +1156,56 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name,
of_node_put(node); 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, static struct device_node *rsnd_dai_of_node(struct rsnd_priv *priv,
int *is_graph) int *is_graph)
{ {
......
...@@ -245,6 +245,8 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *nam ...@@ -245,6 +245,8 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *nam
int i = 0; int i = 0;
for_each_child_of_node(of_node, np) { for_each_child_of_node(of_node, np) {
i = rsnd_node_fixed_index(np, name, i);
if (i == rsnd_mod_id_raw(mod) && (!chan)) if (i == rsnd_mod_id_raw(mod) && (!chan))
chan = of_dma_request_slave_channel(np, x); chan = of_dma_request_slave_channel(np, x);
i++; i++;
......
...@@ -465,6 +465,8 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, ...@@ -465,6 +465,8 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name,
struct device_node *node, struct device_node *node,
struct device_node *playback, struct device_node *playback,
struct device_node *capture); 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); int rsnd_channel_normalization(int chan);
#define rsnd_runtime_channel_original(io) \ #define rsnd_runtime_channel_original(io) \
......
...@@ -656,7 +656,7 @@ int rsnd_src_probe(struct rsnd_priv *priv) ...@@ -656,7 +656,7 @@ int rsnd_src_probe(struct rsnd_priv *priv)
if (!node) if (!node)
return 0; /* not used is not error */ return 0; /* not used is not error */
nr = of_get_child_count(node); nr = rsnd_node_count(priv, node, SRC_NAME);
if (!nr) { if (!nr) {
ret = -EINVAL; ret = -EINVAL;
goto rsnd_src_probe_done; goto rsnd_src_probe_done;
...@@ -676,6 +676,8 @@ int rsnd_src_probe(struct rsnd_priv *priv) ...@@ -676,6 +676,8 @@ int rsnd_src_probe(struct rsnd_priv *priv)
if (!of_device_is_available(np)) if (!of_device_is_available(np))
goto skip; goto skip;
i = rsnd_node_fixed_index(np, SRC_NAME, i);
src = rsnd_src_get(priv, i); src = rsnd_src_get(priv, i);
snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
......
...@@ -1117,6 +1117,8 @@ void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, ...@@ -1117,6 +1117,8 @@ void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
for_each_child_of_node(node, np) { for_each_child_of_node(node, np) {
struct rsnd_mod *mod; struct rsnd_mod *mod;
i = rsnd_node_fixed_index(np, SSI_NAME, i);
mod = rsnd_ssi_mod_get(priv, i); mod = rsnd_ssi_mod_get(priv, i);
if (np == playback) if (np == playback)
...@@ -1160,7 +1162,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ...@@ -1160,7 +1162,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
if (!node) if (!node)
return -EINVAL; return -EINVAL;
nr = of_get_child_count(node); nr = rsnd_node_count(priv, node, SSI_NAME);
if (!nr) { if (!nr) {
ret = -EINVAL; ret = -EINVAL;
goto rsnd_ssi_probe_done; goto rsnd_ssi_probe_done;
...@@ -1180,6 +1182,8 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ...@@ -1180,6 +1182,8 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
if (!of_device_is_available(np)) if (!of_device_is_available(np))
goto skip; goto skip;
i = rsnd_node_fixed_index(np, SSI_NAME, i);
ssi = rsnd_ssi_get(priv, i); ssi = rsnd_ssi_get(priv, i);
snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d", snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
......
...@@ -472,6 +472,8 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai, ...@@ -472,6 +472,8 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
for_each_child_of_node(node, np) { for_each_child_of_node(node, np) {
struct rsnd_mod *mod; struct rsnd_mod *mod;
i = rsnd_node_fixed_index(np, SSIU_NAME, i);
mod = rsnd_ssiu_mod_get(priv, i); mod = rsnd_ssiu_mod_get(priv, i);
if (np == playback) if (np == playback)
...@@ -509,7 +511,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) ...@@ -509,7 +511,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
*/ */
node = rsnd_ssiu_of_node(priv); node = rsnd_ssiu_of_node(priv);
if (node) if (node)
nr = of_get_child_count(node); nr = rsnd_node_count(priv, node, SSIU_NAME);
else else
nr = priv->ssi_nr; nr = priv->ssi_nr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment