Unverified Commit 844de7ee authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: audio-graph-card2: expand dai_link property part



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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://msgid.link/r/875xuyh6g7.wl-kuninori.morimoto.gx@renesas.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 33ae5727
Loading
Loading
Loading
Loading
+60 −35
Original line number Diff line number Diff line
@@ -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,8 +822,6 @@ 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;

@@ -819,6 +830,13 @@ static void graph_link_init(struct simple_util_priv *priv,
	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);
+6 −7
Original line number Diff line number Diff line
@@ -1146,13 +1146,12 @@ 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;

	is_playback_only = of_property_read_bool(np, "playback-only");
	is_capture_only = of_property_read_bool(np, "capture-only");
	bool is_playback_only = of_property_read_bool(np, "playback-only");
	bool is_capture_only  = of_property_read_bool(np, "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);