[PATCH v2] ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint parsing

From: Prabhakar
Date: Fri Oct 11 2024 - 09:12:26 EST


From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>

On HiHope boards, the audio configuration uses a single port with one
endpoint, defined as:

rsnd_port: port {
rsnd_endpoint: endpoint {
remote-endpoint = <&dw_hdmi0_snd_in>;
dai-format = "i2s";
bitclock-master = <&rsnd_endpoint>;
frame-master = <&rsnd_endpoint>;
playback = <&ssi2>;
};
};

Commit 547b02f74e4a ("ASoC: rsnd: enable multi Component support for Audio
Graph Card/Card2") added support for multiple ports. This caused probe
failures on HiHope boards because the device node pointers used to
retrieve the endpoint were incorrect.

This patch resolves the issue by introducing a new helper function,
`rsnd_pick_endpoint_node_for_ports()`, which retrieves the correct device
node pointer by checking if the port is named 'port' or 'ports'. The
`rsnd_dai_of_node()` and `rsnd_dai_probe()` functions are updated to use
this helper, ensuring proper endpoint parsing in both single-port and
multi-port configurations. This restores compatibility with HiHope boards.

Fixes: 547b02f74e4a ("ASoC: rsnd: enable multi Component support for Audio Graph Card/Card2")
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
---
v1->v2
- Added a helper function rsnd_pick_endpoint_node_for_ports()
- Updated commit message
- Dropped ACK from Morimoto-san
---
sound/soc/sh/rcar/core.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 9784718a2b6f..b74061b04968 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1233,6 +1233,19 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name
return i;
}

+static struct device_node*
+ rsnd_pick_endpoint_node_for_ports(struct device_node *e_ports,
+ struct device_node *e_port)
+{
+ if (of_node_name_eq(e_ports, "ports"))
+ return e_ports;
+
+ if (of_node_name_eq(e_ports, "port"))
+ return e_port;
+
+ return NULL;
+}
+
static int rsnd_dai_of_node(struct rsnd_priv *priv, int *is_graph)
{
struct device *dev = rsnd_priv_to_dev(priv);
@@ -1278,10 +1291,10 @@ static int rsnd_dai_of_node(struct rsnd_priv *priv, int *is_graph)
* Audio-Graph-Card
*/
for_each_child_of_node(np, ports) {
- if (!of_node_name_eq(ports, "ports") &&
- !of_node_name_eq(ports, "port"))
+ node = rsnd_pick_endpoint_node_for_ports(ports, np);
+ if (!node)
continue;
- priv->component_dais[i] = of_graph_get_endpoint_count(ports);
+ priv->component_dais[i] = of_graph_get_endpoint_count(node);
nr += priv->component_dais[i];
i++;
if (i >= RSND_MAX_COMPONENT) {
@@ -1486,14 +1499,15 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
*/
dai_i = 0;
if (is_graph) {
+ struct device_node *dai_np_port;
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"))
+ dai_np_port = rsnd_pick_endpoint_node_for_ports(ports, np);
+ if (!dai_np_port)
continue;
- for_each_endpoint_of_node(ports, dai_np) {
+ for_each_endpoint_of_node(dai_np_port, dai_np) {
__rsnd_dai_probe(priv, dai_np, dai_np, 0, dai_i);
if (!rsnd_is_gen1(priv) && !rsnd_is_gen2(priv)) {
rdai = rsnd_rdai_get(priv, dai_i);
--
2.43.0