ASoC: audio-graph-card2: expand dai_link property part
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tue, 28 May 2024 05:05:28 +0000 (05:05 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 3 Jun 2024 14:59:36 +0000 (15:59 +0100)
Current dai_link related property are parsed and enabled only on CPU
port node (A)(b)(c). OTOH, Audio Graph Card2 supports many connections
like Multi-CPU, DPCM, Codec2Codec today. For example in Multi-CPU case,
it will be checked via (X) -> (B) -> (b) process, but (X) / (B) part
property is not parsed.

>From dai_link related settings point of view, (B) (C) part and Codec
port also enabled is more viscerally understandable, and useful.

card2 {
(X) links = <&snd-cpu (A)
 &snd-multi (B)
 &snd-dpcm (C)
 ...>

multi {
ports {
(B) snd-multi: port { ... };
...
};
};
dpcm {
ports {
(C) snd-dpcm: port { ... };
...
};
};
codec2codec {
...
};
};

cpu_device {
ports {
(A) snd-cpu: port { ... };
(b) mcpu:    port { ... };
(c) dcpu:    port { ... };
}
};

One note here is that if it was Multi-CPU/Codec case, 1st port only
enabled to have property it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://msgid.link/r/875xuyh6g7.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/generic/audio-graph-card2.c
sound/soc/generic/simple-card-utils.c

index 3029e8e..bd714a6 100644 (file)
@@ -763,42 +763,55 @@ static void graph_parse_daifmt(struct device_node *node,
 }
 
 static void graph_link_init(struct simple_util_priv *priv,
-                           struct device_node *port,
+                           struct device_node *lnk,
+                           struct device_node *port_cpu,
+                           struct device_node *port_codec,
                            struct link_info *li,
                            int is_cpu_node)
 {
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
-       struct device_node *ep;
-       struct device_node *ports;
+       struct device_node *ep_cpu, *ep_codec;
+       struct device_node *ports_cpu, *ports_codec;
        unsigned int daifmt = 0, daiclk = 0;
        bool playback_only = 0, capture_only = 0;
        unsigned int bit_frame = 0;
 
-       if (graph_lnk_is_multi(port)) {
-               of_node_get(port);
-               ep = graph_get_next_multi_ep(&port);
-               port = ep_to_port(ep);
+       of_node_get(port_cpu);
+       if (graph_lnk_is_multi(port_cpu)) {
+               ep_cpu = graph_get_next_multi_ep(&port_cpu);
+               of_node_put(port_cpu);
+               port_cpu = ep_to_port(ep_cpu);
        } else {
-               ep = port_to_endpoint(port);
+               ep_cpu = port_to_endpoint(port_cpu);
        }
+       ports_cpu = port_to_ports(port_cpu);
 
-       ports = port_to_ports(port);
+       of_node_get(port_codec);
+       if (graph_lnk_is_multi(port_codec)) {
+               ep_codec = graph_get_next_multi_ep(&port_codec);
+               of_node_put(port_cpu);
+               port_codec = ep_to_port(ep_codec);
+       } else {
+               ep_codec = port_to_endpoint(port_codec);
+       }
+       ports_codec = port_to_ports(port_codec);
 
-       /*
-        *      ports {
-        * (A)
-        *              port {
-        * (B)
-        *                      endpoint {
-        * (C)
-        *                      };
-        *              };
-        *      };
-        * };
-        */
-       graph_parse_daifmt(ep,    &daifmt, &bit_frame);         /* (C) */
-       graph_parse_daifmt(port,  &daifmt, &bit_frame);         /* (B) */
-       graph_parse_daifmt(ports, &daifmt, &bit_frame);         /* (A) */
+
+       graph_parse_daifmt(ep_cpu,      &daifmt, &bit_frame);
+       graph_parse_daifmt(ep_codec,    &daifmt, &bit_frame);
+       graph_parse_daifmt(port_cpu,    &daifmt, &bit_frame);
+       graph_parse_daifmt(port_codec,  &daifmt, &bit_frame);
+       graph_parse_daifmt(ports_cpu,   &daifmt, &bit_frame);
+       graph_parse_daifmt(ports_codec, &daifmt, &bit_frame);
+       graph_parse_daifmt(lnk,         &daifmt, &bit_frame);
+
+       graph_util_parse_link_direction(lnk,            &playback_only, &capture_only);
+       graph_util_parse_link_direction(ports_cpu,      &playback_only, &capture_only);
+       graph_util_parse_link_direction(ports_codec,    &playback_only, &capture_only);
+       graph_util_parse_link_direction(port_cpu,       &playback_only, &capture_only);
+       graph_util_parse_link_direction(port_codec,     &playback_only, &capture_only);
+       graph_util_parse_link_direction(ep_cpu,         &playback_only, &capture_only);
+       graph_util_parse_link_direction(ep_codec,       &playback_only, &capture_only);
 
        /*
         * convert bit_frame
@@ -809,16 +822,21 @@ static void graph_link_init(struct simple_util_priv *priv,
        if (is_cpu_node)
                daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk);
 
-       graph_util_parse_link_direction(port, &playback_only, &capture_only);
-
-       dai_link->playback_only = playback_only;
-       dai_link->capture_only = capture_only;
+       dai_link->playback_only = playback_only;
+       dai_link->capture_only  = capture_only;
 
        dai_link->dai_fmt       = daifmt | daiclk;
        dai_link->init          = simple_util_dai_init;
        dai_link->ops           = &graph_ops;
        if (priv->ops)
                dai_link->ops   = priv->ops;
+
+       of_node_put(ports_cpu);
+       of_node_put(ports_codec);
+       of_node_put(port_cpu);
+       of_node_put(port_codec);
+       of_node_put(ep_cpu);
+       of_node_put(ep_codec);
 }
 
 int audio_graph2_link_normal(struct simple_util_priv *priv,
@@ -846,7 +864,7 @@ int audio_graph2_link_normal(struct simple_util_priv *priv,
        if (ret < 0)
                goto err;
 
-       graph_link_init(priv, cpu_port, li, 1);
+       graph_link_init(priv, lnk, cpu_port, codec_port, li, 1);
 err:
        of_node_put(codec_port);
        of_node_put(cpu_ep);
@@ -861,13 +879,16 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
 {
        struct device_node *ep = port_to_endpoint(lnk);
        struct device_node *rep = of_graph_get_remote_endpoint(ep);
-       struct device_node *rport = of_graph_get_remote_port(ep);
+       struct device_node *cpu_port = NULL;
+       struct device_node *codec_port = NULL;
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
        int is_cpu = graph_util_is_ports0(lnk);
        int ret;
 
        if (is_cpu) {
+               cpu_port = of_graph_get_remote_port(ep); /* rport */
+
                /*
                 * dpcm {
                 *      // Front-End
@@ -895,10 +916,13 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
                dai_link->dynamic               = 1;
                dai_link->dpcm_merged_format    = 1;
 
-               ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1);
+               ret = graph_parse_node(priv, GRAPH_DPCM, cpu_port, li, 1);
                if (ret)
                        goto err;
+
        } else {
+               codec_port = of_graph_get_remote_port(ep); /* rport */
+
                /*
                 * dpcm {
                 *      // Front-End
@@ -928,7 +952,7 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
                dai_link->no_pcm                = 1;
                dai_link->be_hw_params_fixup    = simple_util_be_hw_params_fixup;
 
-               ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0);
+               ret = graph_parse_node(priv, GRAPH_DPCM, codec_port, li, 0);
                if (ret < 0)
                        goto err;
        }
@@ -938,11 +962,12 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
 
        snd_soc_dai_link_set_capabilities(dai_link);
 
-       graph_link_init(priv, rport, li, is_cpu);
+       graph_link_init(priv, lnk, cpu_port, codec_port, li, is_cpu);
 err:
        of_node_put(ep);
        of_node_put(rep);
-       of_node_put(rport);
+       of_node_put(cpu_port);
+       of_node_put(codec_port);
 
        return ret;
 }
@@ -1030,7 +1055,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
        if (ret < 0)
                goto err2;
 
-       graph_link_init(priv, codec0_port, li, 1);
+       graph_link_init(priv, lnk, codec0_port, codec1_port, li, 1);
 err2:
        of_node_put(ep0);
        of_node_put(ep1);
index a655f20..dcd0569 100644 (file)
@@ -1146,14 +1146,13 @@ EXPORT_SYMBOL_GPL(graph_util_parse_dai);
 void graph_util_parse_link_direction(struct device_node *np,
                                    bool *playback_only, bool *capture_only)
 {
-       bool is_playback_only = false;
-       bool is_capture_only = false;
+       bool is_playback_only = of_property_read_bool(np, "playback-only");
+       bool is_capture_only  = of_property_read_bool(np, "capture-only");
 
-       is_playback_only = of_property_read_bool(np, "playback-only");
-       is_capture_only = of_property_read_bool(np, "capture-only");
-
-       *playback_only = is_playback_only;
-       *capture_only = is_capture_only;
+       if (is_playback_only)
+               *playback_only = is_playback_only;
+       if (is_capture_only)
+               *capture_only = is_capture_only;
 }
 EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);