alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes
  2014-03-11 10:27 [PATCH v2 0/4] ASoC: simple-card: DT fix and multi DAI links extension Jean-Francois Moine
@ 2014-03-11  9:03 ` Jean-Francois Moine
  2014-03-14 19:57   ` Mark Brown
  2014-03-11  9:21 ` [PATCH v2 2/4] ASoC: simple-card: dynamically allocate the DAI link array Jean-Francois Moine
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-11  9:03 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Kuninori Morimoto, linux-kernel, Xiubo Li

The reference count of some device nodes is not correctly reset
at end of card probe.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 sound/soc/generic/simple-card.c | 50 ++++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 5dd4769..dcf37fb 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -105,12 +105,12 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
 	/* get dai->name */
 	ret = snd_soc_of_get_dai_name(np, name);
 	if (ret < 0)
-		goto parse_error;
+		return ret;
 
 	/* parse TDM slot */
 	ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
 	if (ret)
-		goto parse_error;
+		return ret;
 
 	/*
 	 * bitclock-inversion, frame-inversion
@@ -130,7 +130,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
 		clk = of_clk_get(np, 0);
 		if (IS_ERR(clk)) {
 			ret = PTR_ERR(clk);
-			goto parse_error;
+			return ret;
 		}
 
 		dai->sysclk = clk_get_rate(clk);
@@ -144,12 +144,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
 			dai->sysclk = clk_get_rate(clk);
 	}
 
-	ret = 0;
-
-parse_error:
-	of_node_put(node);
-
-	return ret;
+	return 0;
 }
 
 static int asoc_simple_card_parse_of(struct device_node *node,
@@ -187,22 +182,26 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 	/* CPU sub-node */
 	ret = -EINVAL;
 	np = of_get_child_by_name(node, "simple-audio-card,cpu");
-	if (np)
+	if (np) {
 		ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
 						  &priv->cpu_dai,
 						  &dai_link->cpu_of_node,
 						  &dai_link->cpu_dai_name);
+		of_node_put(np);
+	}
 	if (ret < 0)
 		return ret;
 
 	/* CODEC sub-node */
 	ret = -EINVAL;
 	np = of_get_child_by_name(node, "simple-audio-card,codec");
-	if (np)
+	if (np) {
 		ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
 						  &priv->codec_dai,
 						  &dai_link->codec_of_node,
 						  &dai_link->codec_dai_name);
+		of_node_put(np);
+	}
 	if (ret < 0)
 		return ret;
 
@@ -248,6 +247,27 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 	return 0;
 }
 
+/* update the reference count of the devices nodes at end of probe */
+static int asoc_simple_card_unref(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct snd_soc_dai_link *dai_link;
+	struct device_node *np;
+	int num_links;
+
+	for (num_links = 0, dai_link = card->dai_link;
+	     num_links < card->num_links;
+	     num_links++, dai_link++) {
+		np = (struct device_node *) dai_link->cpu_of_node;
+		if (np)
+			of_node_put(np);
+		np = (struct device_node *) dai_link->codec_of_node;
+		if (np)
+			of_node_put(np);
+	}
+	return 0;
+}
+
 static int asoc_simple_card_probe(struct platform_device *pdev)
 {
 	struct simple_card_data *priv;
@@ -275,7 +295,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 		if (ret < 0) {
 			if (ret != -EPROBE_DEFER)
 				dev_err(dev, "parse error %d\n", ret);
-			return ret;
+			goto err;
 		}
 	} else {
 		struct asoc_simple_card_info *cinfo;
@@ -318,7 +338,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 
 	snd_soc_card_set_drvdata(&priv->snd_card, priv);
 
-	return devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
+	ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
+
+err:
+	asoc_simple_card_unref(pdev);
+	return ret;
 }
 
 static const struct of_device_id asoc_simple_of_match[] = {
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/4] ASoC: simple-card: dynamically allocate the DAI link array
  2014-03-11 10:27 [PATCH v2 0/4] ASoC: simple-card: DT fix and multi DAI links extension Jean-Francois Moine
  2014-03-11  9:03 ` [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes Jean-Francois Moine
@ 2014-03-11  9:21 ` Jean-Francois Moine
  2014-03-11  9:36 ` [PATCH v2 3/4] ASoC: simple-card: accept many DAI links Jean-Francois Moine
  2014-03-11  9:58 ` [PATCH v2 4/4] ASoC: simple-card: Add DT documentation for multi-DAI links Jean-Francois Moine
  3 siblings, 0 replies; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-11  9:21 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Kuninori Morimoto, linux-kernel, Xiubo Li

The DAI link array is hard-coded as a single CPU / CODEC link.

This patch allocates this array with the card definition and facilitates
handling more DAI links.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 sound/soc/generic/simple-card.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index dcf37fb..2710b52 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -23,7 +23,7 @@ struct simple_card_data {
 	unsigned int daifmt;
 	struct asoc_simple_dai cpu_dai;
 	struct asoc_simple_dai codec_dai;
-	struct snd_soc_dai_link snd_link;
+	struct snd_soc_dai_link dai_link[];	/* dynamically allocated */
 };
 
 static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
@@ -276,7 +276,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev,
+			sizeof(*priv) + sizeof(*dai_link),
+			GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
@@ -285,7 +287,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 	 */
 	priv->snd_card.owner = THIS_MODULE;
 	priv->snd_card.dev = dev;
-	dai_link = &priv->snd_link;
+	dai_link = priv->dai_link;
 	priv->snd_card.dai_link = dai_link;
 	priv->snd_card.num_links = 1;
 
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-11 10:27 [PATCH v2 0/4] ASoC: simple-card: DT fix and multi DAI links extension Jean-Francois Moine
  2014-03-11  9:03 ` [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes Jean-Francois Moine
  2014-03-11  9:21 ` [PATCH v2 2/4] ASoC: simple-card: dynamically allocate the DAI link array Jean-Francois Moine
@ 2014-03-11  9:36 ` Jean-Francois Moine
  2014-03-12  5:20   ` Li.Xiubo
  2014-03-14 11:16   ` Jyri Sarha
  2014-03-11  9:58 ` [PATCH v2 4/4] ASoC: simple-card: Add DT documentation for multi-DAI links Jean-Francois Moine
  3 siblings, 2 replies; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-11  9:36 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Kuninori Morimoto, linux-kernel, Xiubo Li

Some simple audio cards may have many DAI links.
This patch extends the simple-card driver for handling such cards.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 sound/soc/generic/simple-card.c | 132 ++++++++++++++++++++++++++--------------
 1 file changed, 85 insertions(+), 47 deletions(-)

diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 2710b52..8188c34 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -107,6 +107,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
 	if (ret < 0)
 		return ret;
 
+	if (!dai)
+		return 0;
+
 	/* parse TDM slot */
 	ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
 	if (ret)
@@ -154,7 +157,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 	struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
 	struct device_node *np;
 	char *name;
-	int ret;
+	int first_link, ret;
 
 	/* parsing the card name from DT */
 	snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
@@ -179,50 +182,67 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 			return ret;
 	}
 
-	/* CPU sub-node */
-	ret = -EINVAL;
-	np = of_get_child_by_name(node, "simple-audio-card,cpu");
-	if (np) {
+	/* loop on the DAI links */
+	np = NULL;
+	first_link = 1;
+	for (;;) {
+		np = of_get_next_child(node, np);
+		if (!np)
+			break;
+
+		/* CPU sub-node */
+		if (strcmp(np->name, "simple-audio-card,cpu") != 0) {
+			dev_err(dev, "Bad CPU DAI\n");
+			ret = -EINVAL;
+			goto err;
+		}
 		ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
-						  &priv->cpu_dai,
+					first_link ? &priv->cpu_dai : NULL,
 						  &dai_link->cpu_of_node,
 						  &dai_link->cpu_dai_name);
-		of_node_put(np);
-	}
-	if (ret < 0)
-		return ret;
+		if (ret < 0)
+			goto err;
 
-	/* CODEC sub-node */
-	ret = -EINVAL;
-	np = of_get_child_by_name(node, "simple-audio-card,codec");
-	if (np) {
+		/* CODEC sub-node */
+		np = of_get_next_child(node, np);
+		if (strcmp(np->name, "simple-audio-card,codec") != 0) {
+			dev_err(dev, "Bad CODEC DAI\n");
+			ret = -EINVAL;
+			goto err;
+		}
 		ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
-						  &priv->codec_dai,
+					first_link ? &priv->codec_dai : NULL,
 						  &dai_link->codec_of_node,
 						  &dai_link->codec_dai_name);
-		of_node_put(np);
-	}
-	if (ret < 0)
-		return ret;
+		if (ret < 0)
+			goto err;
+
+		if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
+			ret = -EINVAL;
+			goto err;
+		}
 
-	if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name)
-		return -EINVAL;
+		/* simple-card assumes platform == cpu */
+		dai_link->platform_of_node = dai_link->cpu_of_node;
+
+		name = devm_kzalloc(dev,
+				    strlen(dai_link->cpu_dai_name)   +
+				    strlen(dai_link->codec_dai_name) + 2,
+				    GFP_KERNEL);
+		sprintf(name, "%s-%s", dai_link->cpu_dai_name,
+					dai_link->codec_dai_name);
+		dai_link->name = dai_link->stream_name = name;
+
+		dai_link++;
+		first_link = 0;
+	}
 
 	/* card name is created from CPU/CODEC dai name */
-	name = devm_kzalloc(dev,
-			    strlen(dai_link->cpu_dai_name)   +
-			    strlen(dai_link->codec_dai_name) + 2,
-			    GFP_KERNEL);
-	sprintf(name, "%s-%s", dai_link->cpu_dai_name,
-				dai_link->codec_dai_name);
+	dai_link = priv->snd_card.dai_link;
 	if (!priv->snd_card.name)
-		priv->snd_card.name = name;
-	dai_link->name = dai_link->stream_name = name;
+		priv->snd_card.name = dai_link->name;
 
-	/* simple-card assumes platform == cpu */
-	dai_link->platform_of_node = dai_link->cpu_of_node;
-
-	dev_dbg(dev, "card-name : %s\n", name);
+	dev_dbg(dev, "card-name : %s\n", priv->snd_card.name);
 	dev_dbg(dev, "platform : %04x\n", priv->daifmt);
 	dev_dbg(dev, "cpu : %s / %04x / %d\n",
 		dai_link->cpu_dai_name,
@@ -233,18 +253,11 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 		priv->codec_dai.fmt,
 		priv->codec_dai.sysclk);
 
-	/*
-	 * soc_bind_dai_link() will check cpu name
-	 * after of_node matching if dai_link has cpu_dai_name.
-	 * but, it will never match if name was created by fmt_single_name()
-	 * remove cpu_dai_name to escape name matching.
-	 * see
-	 *	fmt_single_name()
-	 *	fmt_multiple_name()
-	 */
-	dai_link->cpu_dai_name = NULL;
-
 	return 0;
+
+err:
+	of_node_put(np);
+	return ret;
 }
 
 /* update the reference count of the devices nodes at end of probe */
@@ -274,10 +287,22 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 	struct snd_soc_dai_link *dai_link;
 	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
-	int ret;
+	int num_links, ret;
+
+	/* get the number of DAI links */
+	if (np) {
+		num_links = of_get_child_count(np);
+		if (num_links == 0 || (num_links & 1)) {
+			dev_err(&pdev->dev, "Bad number of DAI links\n");
+			return -EINVAL;
+		}
+		num_links /= 2;
+	} else {
+		num_links = 1;
+	}
 
 	priv = devm_kzalloc(dev,
-			sizeof(*priv) + sizeof(*dai_link),
+			sizeof(*priv) + sizeof(*dai_link) * num_links,
 			GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -289,7 +314,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 	priv->snd_card.dev = dev;
 	dai_link = priv->dai_link;
 	priv->snd_card.dai_link = dai_link;
-	priv->snd_card.num_links = 1;
+	priv->snd_card.num_links = num_links;
 
 	if (np && of_device_is_available(np)) {
 
@@ -299,6 +324,19 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
 				dev_err(dev, "parse error %d\n", ret);
 			goto err;
 		}
+
+		/*
+		 * soc_bind_dai_link() will check cpu name
+		 * after of_node matching if dai_link has cpu_dai_name.
+		 * but, it will never match if name was created by fmt_single_name()
+		 * remove cpu_dai_name to escape name matching.
+		 * see
+		 *	fmt_single_name()
+		 *	fmt_multiple_name()
+		 */
+		if (num_links == 1)
+			dai_link->cpu_dai_name = NULL;
+
 	} else {
 		struct asoc_simple_card_info *cinfo;
 
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 4/4] ASoC: simple-card: Add DT documentation for multi-DAI links
  2014-03-11 10:27 [PATCH v2 0/4] ASoC: simple-card: DT fix and multi DAI links extension Jean-Francois Moine
                   ` (2 preceding siblings ...)
  2014-03-11  9:36 ` [PATCH v2 3/4] ASoC: simple-card: accept many DAI links Jean-Francois Moine
@ 2014-03-11  9:58 ` Jean-Francois Moine
  3 siblings, 0 replies; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-11  9:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: alsa-devel, devicetree, Kuninori Morimoto, linux-kernel, Xiubo Li

There may be many couples of CPU/CODEC DAI links.
The example 2 is extracted from the Cubox DT.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 .../devicetree/bindings/sound/simple-card.txt      | 34 +++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index b30c222..a872e7b 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -26,6 +26,9 @@ Required subnodes:
 - simple-audio-card,cpu			: CPU   sub-node
 - simple-audio-card,codec		: CODEC sub-node
 
+  There may be one or many couples (simple-audio-card,cpu, simple-audio-card,codec)
+  (see example 2).
+
 Required CPU/CODEC subnodes properties:
 
 - sound-dai				: phandle and port of CPU/CODEC
@@ -43,7 +46,7 @@ Optional CPU/CODEC subnodes properties:
 					  clock node (= common clock), or "system-clock-frequency"
 					  (if system doens't support common clock)
 
-Example:
+Example 1:
 
 sound {
 	compatible = "simple-audio-card";
@@ -88,3 +91,32 @@ sh_fsi2: sh_fsi2@ec230000 {
 	interrupt-parent = <&gic>;
 	interrupts = <0 146 0x4>;
 };
+
+Example 2:
+
+sound {
+	compatible = "simple-audio-card";
+	simple-audio-card,name = "Cubox Audio";
+
+	simple-audio-card,cpu@0 {		/* I2S - HDMI */
+		sound-dai = <&audio1 0>;
+		format = "i2s";
+	};
+	simple-audio-card,codec@0 {
+		sound-dai = <&tda998x 0>;
+	};
+
+	simple-audio-card,cpu@1 {		/* S/PDIF - HDMI */
+		sound-dai = <&audio1 1>;
+	};
+	simple-audio-card,codec@1 {
+		sound-dai = <&tda998x 1>;
+	};
+
+	simple-audio-card,cpu@2 {		/* S/PDIF - S/PDIF */
+		sound-dai = <&audio1 1>;
+	};
+	simple-audio-card,codec@2 {
+		sound-dai = <&spdif_codec>;
+	};
+};
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 0/4] ASoC: simple-card: DT fix and multi DAI links extension
@ 2014-03-11 10:27 Jean-Francois Moine
  2014-03-11  9:03 ` [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes Jean-Francois Moine
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-11 10:27 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Xiubo Li, linux-kernel, Kuninori Morimoto

This patch series fixes a small problem about node device locks and also
extends the simple card driver to handle many DAI links as this exists
in the Cubox audio subsystem.

- v2
	- change subject/comment about device node reference count
		(Mark Brown)
	- use a null size array instead of an implicit area for the DAI links
		(Li Xiubo)
	- update the reference count of the device node at end of probe

Jean-Francois Moine (4):
  ASoC: simple-card: Fix the reference count of device nodes
  ASoC: simple-card: dynamically allocate the DAI link array
  ASoC: simple-card: accept many DAI links
  ASoC: simple-card: Add DT documentation for multi-DAI links

 .../devicetree/bindings/sound/simple-card.txt      |  34 +++-
 sound/soc/generic/simple-card.c                    | 174 ++++++++++++++-------
 2 files changed, 152 insertions(+), 56 deletions(-)

-- 
1.9.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-11  9:36 ` [PATCH v2 3/4] ASoC: simple-card: accept many DAI links Jean-Francois Moine
@ 2014-03-12  5:20   ` Li.Xiubo
  2014-03-14 18:58     ` [alsa-devel] " Jean-Francois Moine
  2014-03-14 11:16   ` Jyri Sarha
  1 sibling, 1 reply; 12+ messages in thread
From: Li.Xiubo @ 2014-03-12  5:20 UTC (permalink / raw)
  To: Jean-Francois Moine, Mark Brown
  Cc: alsa-devel, linux-kernel, Kuninori Morimoto

> Subject: [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
> 
> Some simple audio cards may have many DAI links.
> This patch extends the simple-card driver for handling such cards.
> 
> Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
> ---
>  sound/soc/generic/simple-card.c | 132 ++++++++++++++++++++++++++-------------
> -
>  1 file changed, 85 insertions(+), 47 deletions(-)
> 
> diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
> index 2710b52..8188c34 100644
> --- a/sound/soc/generic/simple-card.c
> +++ b/sound/soc/generic/simple-card.c
> @@ -107,6 +107,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
>  	if (ret < 0)
>  		return ret;
> 
> +	if (!dai)
> +		return 0;
> +
>  	/* parse TDM slot */
>  	ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
>  	if (ret)
> @@ -154,7 +157,7 @@ static int asoc_simple_card_parse_of(struct device_node
> *node,
>  	struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
>  	struct device_node *np;
>  	char *name;
> -	int ret;
> +	int first_link, ret;
> 
>  	/* parsing the card name from DT */
>  	snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
> @@ -179,50 +182,67 @@ static int asoc_simple_card_parse_of(struct device_node
> *node,
>  			return ret;
>  	}
> 
> -	/* CPU sub-node */
> -	ret = -EINVAL;
> -	np = of_get_child_by_name(node, "simple-audio-card,cpu");
> -	if (np) {
> +	/* loop on the DAI links */
> +	np = NULL;
> +	first_link = 1;
> +	for (;;) {
> +		np = of_get_next_child(node, np);
> +		if (!np)
> +			break;
> +
> +		/* CPU sub-node */
> +		if (strcmp(np->name, "simple-audio-card,cpu") != 0) {
> +			dev_err(dev, "Bad CPU DAI\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}
>  		ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
> -						  &priv->cpu_dai,
> +					first_link ? &priv->cpu_dai : NULL,

@Jean-Francois,

I'm not sure why only the first link needs parsing the DAIFMT ?

On my LS1 platform there are two CODECs and two CPU SAI deivces,
SGTL5000 <---> SAI
CS42888  <---> ESAI

Could the many dai links feature support this case? 

I my understanding is correct here, this patch will support the
Board, in which board there maybe only one CODEC supporting many
DAIs...


Thanks,

--
Best Regards,
Xiubo




>  						  &dai_link->cpu_of_node,
>  						  &dai_link->cpu_dai_name);
> -		of_node_put(np);
> -	}
> -	if (ret < 0)
> -		return ret;
> +		if (ret < 0)
> +			goto err;
> 
> -	/* CODEC sub-node */
> -	ret = -EINVAL;
> -	np = of_get_child_by_name(node, "simple-audio-card,codec");
> -	if (np) {
> +		/* CODEC sub-node */
> +		np = of_get_next_child(node, np);
> +		if (strcmp(np->name, "simple-audio-card,codec") != 0) {
> +			dev_err(dev, "Bad CODEC DAI\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}
>  		ret = asoc_simple_card_sub_parse_of(np, priv->daifmt,
> -						  &priv->codec_dai,
> +					first_link ? &priv->codec_dai : NULL,
>  						  &dai_link->codec_of_node,
>  						  &dai_link->codec_dai_name);
> -		of_node_put(np);
> -	}
> -	if (ret < 0)
> -		return ret;
> +		if (ret < 0)
> +			goto err;
> +
> +		if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
> +			ret = -EINVAL;
> +			goto err;
> +		}
> 
> -	if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name)
> -		return -EINVAL;
> +		/* simple-card assumes platform == cpu */
> +		dai_link->platform_of_node = dai_link->cpu_of_node;
> +
> +		name = devm_kzalloc(dev,
> +				    strlen(dai_link->cpu_dai_name)   +
> +				    strlen(dai_link->codec_dai_name) + 2,
> +				    GFP_KERNEL);
> +		sprintf(name, "%s-%s", dai_link->cpu_dai_name,
> +					dai_link->codec_dai_name);
> +		dai_link->name = dai_link->stream_name = name;
> +
> +		dai_link++;
> +		first_link = 0;
> +	}
> 
>  	/* card name is created from CPU/CODEC dai name */
> -	name = devm_kzalloc(dev,
> -			    strlen(dai_link->cpu_dai_name)   +
> -			    strlen(dai_link->codec_dai_name) + 2,
> -			    GFP_KERNEL);
> -	sprintf(name, "%s-%s", dai_link->cpu_dai_name,
> -				dai_link->codec_dai_name);
> +	dai_link = priv->snd_card.dai_link;
>  	if (!priv->snd_card.name)
> -		priv->snd_card.name = name;
> -	dai_link->name = dai_link->stream_name = name;
> +		priv->snd_card.name = dai_link->name;
> 
> -	/* simple-card assumes platform == cpu */
> -	dai_link->platform_of_node = dai_link->cpu_of_node;
> -
> -	dev_dbg(dev, "card-name : %s\n", name);
> +	dev_dbg(dev, "card-name : %s\n", priv->snd_card.name);
>  	dev_dbg(dev, "platform : %04x\n", priv->daifmt);
>  	dev_dbg(dev, "cpu : %s / %04x / %d\n",
>  		dai_link->cpu_dai_name,
> @@ -233,18 +253,11 @@ static int asoc_simple_card_parse_of(struct device_node
> *node,
>  		priv->codec_dai.fmt,
>  		priv->codec_dai.sysclk);
> 
> -	/*
> -	 * soc_bind_dai_link() will check cpu name
> -	 * after of_node matching if dai_link has cpu_dai_name.
> -	 * but, it will never match if name was created by fmt_single_name()
> -	 * remove cpu_dai_name to escape name matching.
> -	 * see
> -	 *	fmt_single_name()
> -	 *	fmt_multiple_name()
> -	 */
> -	dai_link->cpu_dai_name = NULL;
> -
>  	return 0;
> +
> +err:
> +	of_node_put(np);
> +	return ret;
>  }
> 
>  /* update the reference count of the devices nodes at end of probe */
> @@ -274,10 +287,22 @@ static int asoc_simple_card_probe(struct platform_device
> *pdev)
>  	struct snd_soc_dai_link *dai_link;
>  	struct device_node *np = pdev->dev.of_node;
>  	struct device *dev = &pdev->dev;
> -	int ret;
> +	int num_links, ret;
> +
> +	/* get the number of DAI links */
> +	if (np) {
> +		num_links = of_get_child_count(np);
> +		if (num_links == 0 || (num_links & 1)) {
> +			dev_err(&pdev->dev, "Bad number of DAI links\n");
> +			return -EINVAL;
> +		}
> +		num_links /= 2;
> +	} else {
> +		num_links = 1;
> +	}
> 
>  	priv = devm_kzalloc(dev,
> -			sizeof(*priv) + sizeof(*dai_link),
> +			sizeof(*priv) + sizeof(*dai_link) * num_links,
>  			GFP_KERNEL);
>  	if (!priv)
>  		return -ENOMEM;
> @@ -289,7 +314,7 @@ static int asoc_simple_card_probe(struct platform_device
> *pdev)
>  	priv->snd_card.dev = dev;
>  	dai_link = priv->dai_link;
>  	priv->snd_card.dai_link = dai_link;
> -	priv->snd_card.num_links = 1;
> +	priv->snd_card.num_links = num_links;
> 
>  	if (np && of_device_is_available(np)) {
> 
> @@ -299,6 +324,19 @@ static int asoc_simple_card_probe(struct platform_device
> *pdev)
>  				dev_err(dev, "parse error %d\n", ret);
>  			goto err;
>  		}
> +
> +		/*
> +		 * soc_bind_dai_link() will check cpu name
> +		 * after of_node matching if dai_link has cpu_dai_name.
> +		 * but, it will never match if name was created by
> fmt_single_name()
> +		 * remove cpu_dai_name to escape name matching.
> +		 * see
> +		 *	fmt_single_name()
> +		 *	fmt_multiple_name()
> +		 */
> +		if (num_links == 1)
> +			dai_link->cpu_dai_name = NULL;
> +
>  	} else {
>  		struct asoc_simple_card_info *cinfo;
> 
> --
> 1.9.0
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [alsa-devel] [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-11  9:36 ` [PATCH v2 3/4] ASoC: simple-card: accept many DAI links Jean-Francois Moine
  2014-03-12  5:20   ` Li.Xiubo
@ 2014-03-14 11:16   ` Jyri Sarha
  2014-03-14 18:40     ` Jean-Francois Moine
  1 sibling, 1 reply; 12+ messages in thread
From: Jyri Sarha @ 2014-03-14 11:16 UTC (permalink / raw)
  To: Jean-Francois Moine, Mark Brown
  Cc: alsa-devel, Xiubo Li, linux-kernel, Kuninori Morimoto

On 03/11/2014 11:36 AM, Jean-Francois Moine wrote:
> Some simple audio cards may have many DAI links.
> This patch extends the simple-card driver for handling such cards.
>
> Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
> ---
[...]

Why can't you just use two simple-card instances in your setup?

You need to update the DT-binding document too when you are changing the 
binding. That way it would also be easier to follow what you are trying 
to accomplish here.

The sysclk and tdm properties appear to only work in the dais of the 
first dai-link and __asoc_simple_card_dai_init() will not be called for 
other dais at all. The DT-binding of this implementation would look 
pretty hairy to me.

Best regards,
Jyri

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [alsa-devel] [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-14 11:16   ` Jyri Sarha
@ 2014-03-14 18:40     ` Jean-Francois Moine
  2014-03-15  9:14       ` Jyri Sarha
  0 siblings, 1 reply; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-14 18:40 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: Mark Brown, alsa-devel, Xiubo Li, linux-kernel, Kuninori Morimoto

On Fri, 14 Mar 2014 13:16:12 +0200
Jyri Sarha <jsarha@ti.com> wrote:

> On 03/11/2014 11:36 AM, Jean-Francois Moine wrote:
> > Some simple audio cards may have many DAI links.
> > This patch extends the simple-card driver for handling such cards.
> >
> > Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
> > ---
> [...]
> 
> Why can't you just use two simple-card instances in your setup?

My machine has only one audio device (kirkwood). This one has two
outputs. The first one (I2S) is connected to the HDMI transmitter, and
the other one (S/PDIF) is connected to both the HDMI transmitter and the
S/PDIF connector. There can be only one playback stream, either via
I2S, or S/PDIF, or both, with the final output either to HDMI or S/PDIF
or both:

           /--> I2S -----+-> HDMI
platform -+             /
           \-> S/PDIF -+
                        \--> S/PDIF

DPCM permits to activate both I2S and S/PDIF, but it does not handle
the format and rate constraints (both outputs are always activated with
the platform constraints).

So, the actual solution I use is 3 DAI links (= 3 PCMs):
- HDMI via I2S
- HDMI via S/PDIF (no S/PDIF output)
- S/PDIF via S/PDIF (no HDMI output)

> You need to update the DT-binding document too when you are changing the 
> binding. That way it would also be easier to follow what you are trying 
> to accomplish here.

Some people want to have 2 different patchs: one for the code and the
other one for the DT change. Some other people like you want only one
patch. Which is the right way?

> The sysclk and tdm properties appear to only work in the dais of the 
> first dai-link and __asoc_simple_card_dai_init() will not be called for 
> other dais at all. The DT-binding of this implementation would look 
> pretty hairy to me.

I will add an other dynamic structure for these properties.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [alsa-devel] [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-12  5:20   ` Li.Xiubo
@ 2014-03-14 18:58     ` Jean-Francois Moine
  0 siblings, 0 replies; 12+ messages in thread
From: Jean-Francois Moine @ 2014-03-14 18:58 UTC (permalink / raw)
  To: Li.Xiubo, Jyri Sarha
  Cc: Mark Brown, alsa-devel, linux-kernel, Kuninori Morimoto

On Wed, 12 Mar 2014 05:20:17 +0000
"Li.Xiubo@freescale.com" <Li.Xiubo@freescale.com> wrote:

> I'm not sure why only the first link needs parsing the DAIFMT ?

In my machine, there is only one audio device and the CODECs don't need
any format, sysclk or TDM slot.

But, as Jyri asked it too, I will add these properties.

> On my LS1 platform there are two CODECs and two CPU SAI deivces,
> SGTL5000 <---> SAI
> CS42888  <---> ESAI
> 
> Could the many dai links feature support this case? 

As Jyri said: why not two simple-cards?

> I my understanding is correct here, this patch will support the
> Board, in which board there maybe only one CODEC supporting many
> DAIs...

The audio (platform) device of my machine has two outputs (I2S and
S/PDIF = CPU DAIs) which are connected to different CODECs (HDMI
transmitter and S/PDIF connector).

There must be two different HDMI CODECs because the format and rate
constraints of the wires (I2S and S/PDIF) are different.

There is only one playback stream.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes
  2014-03-11  9:03 ` [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes Jean-Francois Moine
@ 2014-03-14 19:57   ` Mark Brown
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Brown @ 2014-03-14 19:57 UTC (permalink / raw)
  To: Jean-Francois Moine; +Cc: alsa-devel, Kuninori Morimoto, linux-kernel, Xiubo Li

[-- Attachment #1: Type: text/plain, Size: 177 bytes --]

On Tue, Mar 11, 2014 at 10:03:40AM +0100, Jean-Francois Moine wrote:
> The reference count of some device nodes is not correctly reset
> at end of card probe.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [alsa-devel] [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-14 18:40     ` Jean-Francois Moine
@ 2014-03-15  9:14       ` Jyri Sarha
  2014-03-17 16:19         ` Mark Brown
  0 siblings, 1 reply; 12+ messages in thread
From: Jyri Sarha @ 2014-03-15  9:14 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Xiubo Li, alsa-devel, Mark Brown, linux-kernel, Kuninori Morimoto

On 2014-03-14 20:40, Jean-Francois Moine wrote:
> On Fri, 14 Mar 2014 13:16:12 +0200
> Jyri Sarha <jsarha@ti.com> wrote:
> 
>> On 03/11/2014 11:36 AM, Jean-Francois Moine wrote:
>> > Some simple audio cards may have many DAI links.
>> > This patch extends the simple-card driver for handling such cards.
>> >
>> > Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
>> > ---
>> [...]
>> 
>> Why can't you just use two simple-card instances in your setup?
> 
> My machine has only one audio device (kirkwood). This one has two
> outputs. The first one (I2S) is connected to the HDMI transmitter, and
> the other one (S/PDIF) is connected to both the HDMI transmitter and 
> the
> S/PDIF connector. There can be only one playback stream, either via
> I2S, or S/PDIF, or both, with the final output either to HDMI or S/PDIF
> or both:
> 
>            /--> I2S -----+-> HDMI
> platform -+             /
>            \-> S/PDIF -+
>                         \--> S/PDIF
> 
> DPCM permits to activate both I2S and S/PDIF, but it does not handle
> the format and rate constraints (both outputs are always activated with
> the platform constraints).
> 
> So, the actual solution I use is 3 DAI links (= 3 PCMs):
> - HDMI via I2S
> - HDMI via S/PDIF (no S/PDIF output)
> - S/PDIF via S/PDIF (no HDMI output)
> 

Maybe a HW specific machine-driver would serve your case better. Of 
course it would be great to have a generic implementation that can 
handle this case too, but I am not sure if it should be called a 
simple-card anymore :).

>> You need to update the DT-binding document too when you are changing 
>> the
>> binding. That way it would also be easier to follow what you are 
>> trying
>> to accomplish here.
> 
> Some people want to have 2 different patchs: one for the code and the
> other one for the DT change. Some other people like you want only one
> patch. Which is the right way?
> 

I did not mean it should be in the same patch. Part of the same series 
is fine with me. It is up to maintainer to decide these things anyway. I 
would just like to compare the document with the implementation.

>> The sysclk and tdm properties appear to only work in the dais of the
>> first dai-link and __asoc_simple_card_dai_init() will not be called 
>> for
>> other dais at all. The DT-binding of this implementation would look
>> pretty hairy to me.
> 
> I will add an other dynamic structure for these properties.

Best regards,
Jyri

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [alsa-devel] [PATCH v2 3/4] ASoC: simple-card: accept many DAI links
  2014-03-15  9:14       ` Jyri Sarha
@ 2014-03-17 16:19         ` Mark Brown
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Brown @ 2014-03-17 16:19 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: Jean-Francois Moine, Xiubo Li, alsa-devel, linux-kernel,
	Kuninori Morimoto

[-- Attachment #1: Type: text/plain, Size: 1368 bytes --]

On Sat, Mar 15, 2014 at 11:14:13AM +0200, Jyri Sarha wrote:
> On 2014-03-14 20:40, Jean-Francois Moine wrote:

> >So, the actual solution I use is 3 DAI links (= 3 PCMs):
> >- HDMI via I2S
> >- HDMI via S/PDIF (no S/PDIF output)
> >- S/PDIF via S/PDIF (no HDMI output)

> Maybe a HW specific machine-driver would serve your case better. Of course
> it would be great to have a generic implementation that can handle this case
> too, but I am not sure if it should be called a simple-card anymore :).

I am a bit concerned about that I have to say.

> >>You need to update the DT-binding document too when you are changing the
> >>binding. That way it would also be easier to follow what you are trying
> >>to accomplish here.

> >Some people want to have 2 different patchs: one for the code and the
> >other one for the DT change. Some other people like you want only one
> >patch. Which is the right way?

> I did not mean it should be in the same patch. Part of the same series is
> fine with me. It is up to maintainer to decide these things anyway. I would
> just like to compare the document with the implementation.

If the binding is being changed in the code the documentation absolutely
must be updated as part of the same patch series if it's not already
been changed previously.  You can have documentation without code but
not code without documentation.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-03-17 16:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-11 10:27 [PATCH v2 0/4] ASoC: simple-card: DT fix and multi DAI links extension Jean-Francois Moine
2014-03-11  9:03 ` [PATCH v2 1/4] ASoC: simple-card: Fix the reference count of device nodes Jean-Francois Moine
2014-03-14 19:57   ` Mark Brown
2014-03-11  9:21 ` [PATCH v2 2/4] ASoC: simple-card: dynamically allocate the DAI link array Jean-Francois Moine
2014-03-11  9:36 ` [PATCH v2 3/4] ASoC: simple-card: accept many DAI links Jean-Francois Moine
2014-03-12  5:20   ` Li.Xiubo
2014-03-14 18:58     ` [alsa-devel] " Jean-Francois Moine
2014-03-14 11:16   ` Jyri Sarha
2014-03-14 18:40     ` Jean-Francois Moine
2014-03-15  9:14       ` Jyri Sarha
2014-03-17 16:19         ` Mark Brown
2014-03-11  9:58 ` [PATCH v2 4/4] ASoC: simple-card: Add DT documentation for multi-DAI links Jean-Francois Moine

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).