[v6,13/13] ASoC: simple-card: Handle additional devices

Message ID 20230623085830.749991-14-herve.codina@bootlin.com
State New
Headers
Series Add support for IIO devices in ASoC |

Commit Message

Herve Codina June 23, 2023, 8:58 a.m. UTC
  An additional-devs subnode can be present in the simple-card top node.
This subnode is used to declared some "virtual" additional devices.

Create related devices from this subnode and avoid this subnode presence
to interfere with the already supported subnodes analysis.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 sound/soc/generic/simple-card.c | 46 +++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)
  

Comments

Christophe Leroy June 27, 2023, 10:02 a.m. UTC | #1
Le 23/06/2023 à 10:58, Herve Codina a écrit :
> An additional-devs subnode can be present in the simple-card top node.
> This subnode is used to declared some "virtual" additional devices.
> 
> Create related devices from this subnode and avoid this subnode presence
> to interfere with the already supported subnodes analysis.
> 
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
>   sound/soc/generic/simple-card.c | 46 +++++++++++++++++++++++++++++++--
>   1 file changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
> index 6f044cc8357e..ae4a47018278 100644
> --- a/sound/soc/generic/simple-card.c
> +++ b/sound/soc/generic/simple-card.c
> @@ -348,6 +348,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
>   	struct device *dev = simple_priv_to_dev(priv);
>   	struct device_node *top = dev->of_node;
>   	struct device_node *node;
> +	struct device_node *add_devs;
>   	uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev);
>   	bool is_top = 0;
>   	int ret = 0;
> @@ -359,6 +360,8 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
>   		is_top = 1;
>   	}
>   
> +	add_devs = of_get_child_by_name(top, PREFIX "additional-devs");
> +
>   	/* loop for all dai-link */
>   	do {
>   		struct asoc_simple_data adata;
> @@ -367,6 +370,12 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
>   		struct device_node *np;
>   		int num = of_get_child_count(node);
>   
> +		/* Skip additional-devs node */
> +		if (node == add_devs) {
> +			node = of_get_next_child(top, node);
> +			continue;
> +		}
> +
>   		/* get codec */
>   		codec = of_get_child_by_name(node, is_top ?
>   					     PREFIX "codec" : "codec");
> @@ -380,12 +389,15 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
>   
>   		/* get convert-xxx property */
>   		memset(&adata, 0, sizeof(adata));
> -		for_each_child_of_node(node, np)
> +		for_each_child_of_node(node, np) {
> +			if (np == add_devs)
> +				continue;
>   			simple_parse_convert(dev, np, &adata);
> +		}
>   
>   		/* loop for all CPU/Codec node */
>   		for_each_child_of_node(node, np) {
> -			if (plat == np)
> +			if (plat == np || add_devs == np)
>   				continue;
>   			/*
>   			 * It is DPCM
> @@ -427,6 +439,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
>   	} while (!is_top && node);
>   
>    error:
> +	of_node_put(add_devs);
>   	of_node_put(node);
>   	return ret;
>   }
> @@ -464,6 +477,31 @@ static int simple_for_each_link(struct asoc_simple_priv *priv,
>   	return ret;
>   }
>   
> +static void simple_depopulate_aux(void *data)
> +{
> +	struct asoc_simple_priv *priv = data;
> +
> +	of_platform_depopulate(simple_priv_to_dev(priv));
> +}
> +
> +static int simple_populate_aux(struct asoc_simple_priv *priv)
> +{
> +	struct device *dev = simple_priv_to_dev(priv);
> +	struct device_node *node;
> +	int ret;
> +
> +	node = of_get_child_by_name(dev->of_node, PREFIX "additional-devs");
> +	if (!node)
> +		return 0;
> +
> +	ret = of_platform_populate(node, NULL, NULL, dev);
> +	of_node_put(node);
> +	if (ret)
> +		return ret;
> +
> +	return devm_add_action_or_reset(dev, simple_depopulate_aux, priv);
> +}
> +
>   static int simple_parse_of(struct asoc_simple_priv *priv, struct link_info *li)
>   {
>   	struct snd_soc_card *card = simple_priv_to_card(priv);
> @@ -493,6 +531,10 @@ static int simple_parse_of(struct asoc_simple_priv *priv, struct link_info *li)
>   	if (ret < 0)
>   		return ret;
>   
> +	ret = simple_populate_aux(priv);
> +	if (ret < 0)
> +		return ret;
> +
>   	ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs");
>   
>   	return ret;
  

Patch

diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 6f044cc8357e..ae4a47018278 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -348,6 +348,7 @@  static int __simple_for_each_link(struct asoc_simple_priv *priv,
 	struct device *dev = simple_priv_to_dev(priv);
 	struct device_node *top = dev->of_node;
 	struct device_node *node;
+	struct device_node *add_devs;
 	uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev);
 	bool is_top = 0;
 	int ret = 0;
@@ -359,6 +360,8 @@  static int __simple_for_each_link(struct asoc_simple_priv *priv,
 		is_top = 1;
 	}
 
+	add_devs = of_get_child_by_name(top, PREFIX "additional-devs");
+
 	/* loop for all dai-link */
 	do {
 		struct asoc_simple_data adata;
@@ -367,6 +370,12 @@  static int __simple_for_each_link(struct asoc_simple_priv *priv,
 		struct device_node *np;
 		int num = of_get_child_count(node);
 
+		/* Skip additional-devs node */
+		if (node == add_devs) {
+			node = of_get_next_child(top, node);
+			continue;
+		}
+
 		/* get codec */
 		codec = of_get_child_by_name(node, is_top ?
 					     PREFIX "codec" : "codec");
@@ -380,12 +389,15 @@  static int __simple_for_each_link(struct asoc_simple_priv *priv,
 
 		/* get convert-xxx property */
 		memset(&adata, 0, sizeof(adata));
-		for_each_child_of_node(node, np)
+		for_each_child_of_node(node, np) {
+			if (np == add_devs)
+				continue;
 			simple_parse_convert(dev, np, &adata);
+		}
 
 		/* loop for all CPU/Codec node */
 		for_each_child_of_node(node, np) {
-			if (plat == np)
+			if (plat == np || add_devs == np)
 				continue;
 			/*
 			 * It is DPCM
@@ -427,6 +439,7 @@  static int __simple_for_each_link(struct asoc_simple_priv *priv,
 	} while (!is_top && node);
 
  error:
+	of_node_put(add_devs);
 	of_node_put(node);
 	return ret;
 }
@@ -464,6 +477,31 @@  static int simple_for_each_link(struct asoc_simple_priv *priv,
 	return ret;
 }
 
+static void simple_depopulate_aux(void *data)
+{
+	struct asoc_simple_priv *priv = data;
+
+	of_platform_depopulate(simple_priv_to_dev(priv));
+}
+
+static int simple_populate_aux(struct asoc_simple_priv *priv)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device_node *node;
+	int ret;
+
+	node = of_get_child_by_name(dev->of_node, PREFIX "additional-devs");
+	if (!node)
+		return 0;
+
+	ret = of_platform_populate(node, NULL, NULL, dev);
+	of_node_put(node);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, simple_depopulate_aux, priv);
+}
+
 static int simple_parse_of(struct asoc_simple_priv *priv, struct link_info *li)
 {
 	struct snd_soc_card *card = simple_priv_to_card(priv);
@@ -493,6 +531,10 @@  static int simple_parse_of(struct asoc_simple_priv *priv, struct link_info *li)
 	if (ret < 0)
 		return ret;
 
+	ret = simple_populate_aux(priv);
+	if (ret < 0)
+		return ret;
+
 	ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs");
 
 	return ret;