* [PATCH 2/5] ASoC: rsnd: cleanup rsnd_dai_of_node()
2023-07-24 0:20 [PATCH 0/5] ASoC: rsnd: add multi Component support Kuninori Morimoto
2023-07-24 0:21 ` [PATCH 1/5] ASoC: rsnd: use DAI driver ID instead of DAI ID Kuninori Morimoto
@ 2023-07-24 0:21 ` Kuninori Morimoto
2023-07-24 0:21 ` [PATCH 3/5] ASoC: rsnd: enable multi Component support for Audio Graph Card/Card2 Kuninori Morimoto
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2023-07-24 0:21 UTC (permalink / raw)
To: Mark Brown, Krzysztof Kozlowski, Rob Herring; +Cc: Linux-ALSA, devicetree
It calls rsnd_dai_of_node() to know it was called from Audio Graph
Card/Card2, or from Simple Audio Card. And after that, it gets
number of related DAIs.
To be more simple code, this patch merges these.
This is prepare for multi Component support.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/rcar/core.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index f3f17b784025..a87d7fa55f7b 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1261,7 +1261,7 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name
}
static struct device_node *rsnd_dai_of_node(struct rsnd_priv *priv,
- int *is_graph)
+ int *nr, int *is_graph)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *np = dev->of_node;
@@ -1274,22 +1274,30 @@ static struct device_node *rsnd_dai_of_node(struct rsnd_priv *priv,
* parse both previous dai (= rcar_sound,dai), and
* graph dai (= ports/port)
*/
+
+ /*
+ * Simple-Card
+ */
dai_node = of_get_child_by_name(np, RSND_NODE_DAI);
if (dai_node) {
+ *nr = of_get_child_count(dai_node);
ret = dai_node;
goto of_node_compatible;
}
- ret = np;
-
+ /*
+ * Audio-Graph-Card
+ */
dai_node = of_graph_get_next_endpoint(np, NULL);
- if (dai_node)
- goto of_node_graph;
+ if (dai_node) {
+ *nr = of_graph_get_endpoint_count(np);
+ *is_graph = 1;
+ ret = np;
+ goto of_node_compatible;
+ }
return NULL;
-of_node_graph:
- *is_graph = 1;
of_node_compatible:
of_node_put(dai_node);
@@ -1447,16 +1455,11 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
struct snd_soc_dai_driver *rdrv;
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_dai *rdai;
- int nr;
+ int nr = 0;
int is_graph;
int dai_i;
- dai_node = rsnd_dai_of_node(priv, &is_graph);
- if (is_graph)
- nr = of_graph_get_endpoint_count(dai_node);
- else
- nr = of_get_child_count(dai_node);
-
+ dai_node = rsnd_dai_of_node(priv, &nr, &is_graph);
if (!nr)
return -EINVAL;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/5] ASoC: rsnd: enable multi Component support for Audio Graph Card/Card2
2023-07-24 0:20 [PATCH 0/5] ASoC: rsnd: add multi Component support Kuninori Morimoto
2023-07-24 0:21 ` [PATCH 1/5] ASoC: rsnd: use DAI driver ID instead of DAI ID Kuninori Morimoto
2023-07-24 0:21 ` [PATCH 2/5] ASoC: rsnd: cleanup rsnd_dai_of_node() Kuninori Morimoto
@ 2023-07-24 0:21 ` Kuninori Morimoto
2023-07-24 0:21 ` [PATCH 4/5] ASoC: dt-bindings: renesas,rsnd.yaml: add common port-def Kuninori Morimoto
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2023-07-24 0:21 UTC (permalink / raw)
To: Mark Brown, Krzysztof Kozlowski, Rob Herring; +Cc: Linux-ALSA, devicetree
+-- Basic Board ---------+
|+--------+ +------+|
|| CPU ch0| <--> |CodecA||
|| ch1| <-+ +------+|
|+--------+ | |
+-------------|----------+
+-- expansion board -----+
| | +------+|
| +->|CodecB||
| +------+|
+------------------------+
In above HW connection case, we intuitively think we want to handle these
as "2 Sound Cards".
card0,0: CPU-ch0 - CodecA
card1,0: CPU-ch1 - CodecB
But, we needed to handle it as "1 big Sound Card", because of
Component vs Card limitation.
card0,0: CPU-ch0 - CodecA
card0,1: CPU-ch1 - CodecB
This patch enables multi Component to handle multi Cards.
To support it, it needs
- Fill dai_args for each DAI on snd_soc_dai_driver
- Parse DT for each Component (Simple Card/Audio Graph Card)
Ex) Simple Card
rcar_sound {
...
/* Component0 */
rcar_sound,dai@0 {
...
};
/* Component1 */
rcar_sound,dai@1 {
...
};
};
Ex) Audio Graph Card/Card2
rcar_sound {
/* Component0 */
ports@0 {
...
};
/* Component1 */
ports@1 {
...
};
};
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/rcar/core.c | 134 ++++++++++++++++++++++++++-------------
sound/soc/sh/rcar/rsnd.h | 4 ++
2 files changed, 95 insertions(+), 43 deletions(-)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index a87d7fa55f7b..9f3d97bc177a 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1260,13 +1260,13 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name
return i;
}
-static struct device_node *rsnd_dai_of_node(struct rsnd_priv *priv,
- int *nr, int *is_graph)
+static int rsnd_dai_of_node(struct rsnd_priv *priv, int *is_graph)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *np = dev->of_node;
- struct device_node *dai_node;
- struct device_node *ret;
+ struct device_node *ports, *node;
+ int nr = 0;
+ int i = 0;
*is_graph = 0;
@@ -1278,30 +1278,47 @@ static struct device_node *rsnd_dai_of_node(struct rsnd_priv *priv,
/*
* Simple-Card
*/
- dai_node = of_get_child_by_name(np, RSND_NODE_DAI);
- if (dai_node) {
- *nr = of_get_child_count(dai_node);
- ret = dai_node;
- goto of_node_compatible;
+ node = of_get_child_by_name(np, RSND_NODE_DAI);
+ if (!node)
+ goto audio_graph;
+
+ of_node_put(node);
+
+ for_each_child_of_node(np, node) {
+ if (!of_node_name_eq(node, RSND_NODE_DAI))
+ continue;
+
+ priv->component_dais[i] = of_get_child_count(node);
+ nr += priv->component_dais[i];
+ i++;
+ if (i >= RSND_MAX_COMPONENT) {
+ dev_info(dev, "reach to max component\n");
+ break;
+ }
}
+ return nr;
+
+audio_graph:
/*
* Audio-Graph-Card
*/
- dai_node = of_graph_get_next_endpoint(np, NULL);
- if (dai_node) {
- *nr = of_graph_get_endpoint_count(np);
- *is_graph = 1;
- ret = np;
- goto of_node_compatible;
+ for_each_child_of_node(np, ports) {
+ if (!of_node_name_eq(ports, "ports") &&
+ !of_node_name_eq(ports, "port"))
+ continue;
+ priv->component_dais[i] = of_graph_get_endpoint_count(ports);
+ nr += priv->component_dais[i];
+ i++;
+ if (i >= RSND_MAX_COMPONENT) {
+ dev_info(dev, "reach to max component\n");
+ break;
+ }
}
- return NULL;
-
-of_node_compatible:
- of_node_put(dai_node);
+ *is_graph = 1;
- return ret;
+ return nr;
}
@@ -1365,6 +1382,8 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd,
static void __rsnd_dai_probe(struct rsnd_priv *priv,
struct device_node *dai_np,
+ struct device_node *node_np,
+ uint32_t node_arg,
int dai_i)
{
struct rsnd_dai_stream *io_playback;
@@ -1382,11 +1401,17 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
snprintf(rdai->name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", dai_i);
+ /* for multi Component */
+ rdai->dai_args.np = node_np;
+ rdai->dai_args.args_count = 1;
+ rdai->dai_args.args[0] = node_arg;
+
rdai->priv = priv;
drv->name = rdai->name;
drv->ops = &rsnd_soc_dai_ops;
drv->pcm_new = rsnd_pcm_new;
drv->id = dai_i;
+ drv->dai_args = &rdai->dai_args;
io_playback->rdai = rdai;
io_capture->rdai = rdai;
@@ -1450,16 +1475,15 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
static int rsnd_dai_probe(struct rsnd_priv *priv)
{
- struct device_node *dai_node;
- struct device_node *dai_np;
struct snd_soc_dai_driver *rdrv;
struct device *dev = rsnd_priv_to_dev(priv);
+ struct device_node *np = dev->of_node;
struct rsnd_dai *rdai;
int nr = 0;
int is_graph;
int dai_i;
- dai_node = rsnd_dai_of_node(priv, &nr, &is_graph);
+ nr = rsnd_dai_of_node(priv, &is_graph);
if (!nr)
return -EINVAL;
@@ -1477,26 +1501,42 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
*/
dai_i = 0;
if (is_graph) {
- for_each_endpoint_of_node(dai_node, dai_np) {
- __rsnd_dai_probe(priv, dai_np, dai_i);
- if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) {
- rdai = rsnd_rdai_get(priv, dai_i);
-
- rsnd_parse_connect_graph(priv, &rdai->playback, dai_np);
- rsnd_parse_connect_graph(priv, &rdai->capture, dai_np);
+ struct device_node *ports;
+ struct device_node *dai_np;
+
+ for_each_child_of_node(np, ports) {
+ if (!of_node_name_eq(ports, "ports") &&
+ !of_node_name_eq(ports, "port"))
+ continue;
+ for_each_endpoint_of_node(ports, dai_np) {
+ __rsnd_dai_probe(priv, dai_np, dai_np, 0, dai_i);
+ if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) {
+ rdai = rsnd_rdai_get(priv, dai_i);
+
+ rsnd_parse_connect_graph(priv, &rdai->playback, dai_np);
+ rsnd_parse_connect_graph(priv, &rdai->capture, dai_np);
+ }
+ dai_i++;
}
- dai_i++;
}
} else {
- for_each_child_of_node(dai_node, dai_np) {
- __rsnd_dai_probe(priv, dai_np, dai_i);
- if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) {
- rdai = rsnd_rdai_get(priv, dai_i);
+ struct device_node *node;
+ struct device_node *dai_np;
+
+ for_each_child_of_node(np, node) {
+ if (!of_node_name_eq(node, RSND_NODE_DAI))
+ continue;
- rsnd_parse_connect_simple(priv, &rdai->playback, dai_np);
- rsnd_parse_connect_simple(priv, &rdai->capture, dai_np);
+ for_each_child_of_node(node, dai_np) {
+ __rsnd_dai_probe(priv, dai_np, np, dai_i, dai_i);
+ if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) {
+ rdai = rsnd_rdai_get(priv, dai_i);
+
+ rsnd_parse_connect_simple(priv, &rdai->playback, dai_np);
+ rsnd_parse_connect_simple(priv, &rdai->capture, dai_np);
+ }
+ dai_i++;
}
- dai_i++;
}
}
@@ -1926,6 +1966,7 @@ static int rsnd_probe(struct platform_device *pdev)
rsnd_dai_probe,
};
int ret, i;
+ int ci;
/*
* init priv data
@@ -1962,11 +2003,18 @@ static int rsnd_probe(struct platform_device *pdev)
/*
* asoc register
*/
- ret = devm_snd_soc_register_component(dev, &rsnd_soc_component,
- priv->daidrv, rsnd_rdai_nr(priv));
- if (ret < 0) {
- dev_err(dev, "cannot snd dai register\n");
- goto exit_snd_probe;
+ ci = 0;
+ for (i = 0; priv->component_dais[i] > 0; i++) {
+ int nr = priv->component_dais[i];
+
+ ret = devm_snd_soc_register_component(dev, &rsnd_soc_component,
+ priv->daidrv + ci, nr);
+ if (ret < 0) {
+ dev_err(dev, "cannot snd component register\n");
+ goto exit_snd_probe;
+ }
+
+ ci += nr;
}
pm_runtime_enable(dev);
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 239705d52517..43c0d675cc34 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -545,6 +545,7 @@ struct rsnd_dai {
struct rsnd_dai_stream capture;
struct rsnd_priv *priv;
struct snd_pcm_hw_constraint_list constraint;
+ struct of_phandle_args dai_args;
int max_channels; /* 2ch - 16ch */
int ssi_lane; /* 1lane - 4lane */
@@ -702,6 +703,9 @@ struct rsnd_priv {
struct snd_soc_dai_driver *daidrv;
struct rsnd_dai *rdai;
int rdai_nr;
+
+#define RSND_MAX_COMPONENT 3
+ int component_dais[RSND_MAX_COMPONENT];
};
#define rsnd_priv_to_pdev(priv) ((priv)->pdev)
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/5] ASoC: dt-bindings: renesas,rsnd.yaml: enable multi ports for multi Component support
2023-07-24 0:20 [PATCH 0/5] ASoC: rsnd: add multi Component support Kuninori Morimoto
` (3 preceding siblings ...)
2023-07-24 0:21 ` [PATCH 4/5] ASoC: dt-bindings: renesas,rsnd.yaml: add common port-def Kuninori Morimoto
@ 2023-07-24 0:22 ` Kuninori Morimoto
2023-07-31 16:58 ` [PATCH 0/5] ASoC: rsnd: add " Mark Brown
5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2023-07-24 0:22 UTC (permalink / raw)
To: Mark Brown, Krzysztof Kozlowski, Rob Herring; +Cc: Linux-ALSA, devicetree
To enable multi Component support, "multi ports" is needed for Audio Graph
Card/Card2, and "multi rcar_sound,dai" is needed for Simple Audio Card.
This patch enable these.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
.../bindings/sound/renesas,rsnd.yaml | 24 ++++++++++++-------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
index d9808b130e8d..13a5a0a10fe6 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
@@ -91,6 +91,12 @@ properties:
it must be 1 if your system has audio_clkout0/1/2/3
enum: [0, 1]
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
clock-frequency:
description: for audio_clkout0/1/2/3
@@ -117,13 +123,7 @@ properties:
description: List of necessary clock names.
# details are defined below
- ports:
- $ref: audio-graph-port.yaml#/definitions/port-base
- unevaluatedProperties: false
- patternProperties:
- '^port(@[0-9a-f]+)?$':
- $ref: "#/definitions/port-def"
-
+ # ports is below
port:
$ref: "#/definitions/port-def"
@@ -242,8 +242,9 @@ properties:
- interrupts
additionalProperties: false
+patternProperties:
# For DAI base
- rcar_sound,dai:
+ 'rcar_sound,dai(@[0-9a-f]+)?$':
description: DAI subnode.
type: object
patternProperties:
@@ -263,6 +264,13 @@ properties:
- capture
additionalProperties: false
+ 'ports(@[0-9a-f]+)?$':
+ $ref: audio-graph-port.yaml#/definitions/port-base
+ unevaluatedProperties: false
+ patternProperties:
+ '^port(@[0-9a-f]+)?$':
+ $ref: "#/definitions/port-def"
+
required:
- compatible
- reg
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread