[alsa-devel] [RFC][PATCH] ASoC: add simple-graph-card document

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Thu Jan 26 00:59:37 CET 2017


Hi Sylwester

> 	hdmi: hdmi at 20034000 {
> 		compatible = "rockchip,rk3036-inno-hdmi";
> 		..
> 		ports {
> 			#address-cells = <1>;
> 			#size-cells = <0>;
> 
> 			/* video */
> 			hdmi_in: port at 0 {
> 				reg = <0>;
> 				hdmi_in_vop: endpoint {
> 					remote-endpoint = <&vop_out_hdmi>;
> 				};
> 			};
> 
> 			/* audio */
> 			hdmi_audio_out: port@? {
> 				reg = <?>;	
> 				endpoint {
> 					remote-endpoint = <&i2s>;
> 				};
> 			};
> 	};
> 
> 	i2s: i2s at 10220000 {
> 		compatible = "rockchip,rk3036-i2s", "rockchip,rk3066-i2s";
> 		reg = <0x10220000 0x4000>;
> 		...
> 	};
> 
> Now within individual device bindings the type of the port (audio, 
> video) could be determined by reg property, by assigning specific 
> values for video and audio.  But if we wanted to make this more generic 
> we would probably need something like a property determining the port's 
> purpose, e.g.
> 
> 	type = "audio";
> 
> Regarding compatible string for the card, how about "soc-sound-card-v1"
> instead of "asoc-simple-graph-card" ? Or "soc-simple-graph-card"? 
> Appending version now could let us avoid inventing funny names when 
> it turns we need some different binding in future.

It seems you are fighting with this issue which I was fighting :)
I guess your issue is related to getting dai_name ?
Unfortunately, the idea which adding this "type" property on OF-graph was
already rejected by Rob before.
He said each driver should know each video/sound port somehow.

So, I'm creating new callback .of_xlate_dai_id on component driver.
This callback will exchange reg number to sound dai id.
In your case, I think your HDMI sound will be located as reg = <1>; ?
If so, your driver can have like below.
 1) Your HDMI driver can have .of_xlate_dai_id to exchange reg to sound dai id
 2) (If you use simple-graph-card) simple card will call asoc_simple_card_parse_graph_dai()
 3) It will try to get dai_id by using .of_xlate_dai_id() first.
    It will get gai_id simply counting DT ports if driver doesn't have callback.
 4) you can get correct dai name

Of course this is not yet accepted/reviewed, but I'm ready to
post this patch-set now. It includes both OF-graph simple card,
and HDMI sound (= of_xlate_dai_id()) solution.
But it is a little bit big volume.
Thus, before posting it, I wanted to confirm DT bindings.
This mail thread is for it. I'm waiting Rob's reply now

-- on your HDMI driver --

static int xxx_get_dai_id(struct snd_soc_component *component,
				  struct device_node *endpoint)
{
	struct of_endpoint of_ep;
	int ret;

	ret = of_graph_parse_endpoint(endpoint, &of_ep);
	if (ret < 0)
		return ret;

	/*
	 * HDMI sound should be located as reg = <1>
	 * Then, it is sound port 0
	 */
	if (of_ep.port == 1)
		return 0;

	return -EINVAL;
}


--- on soc-core ---

int snd_soc_get_dai_id(struct device_node *ep)
{
	struct snd_soc_component *pos;
	struct device_node *node;
	struct device_node *endpoint;
	int i, id;
	int ret;

	node = of_graph_get_port_parent(ep);

	/*
	 * For example HDMI case, HDMI has video/sound port,
	 * but ALSA SoC needs sound port number only.
	 * Thus counting HDMI DT port/endpoint doesn't work.
	 * Then, it should have .of_xlate_dai_id
	 */
	ret = -ENOTSUPP;
	mutex_lock(&client_mutex);
	list_for_each_entry(pos, &component_list, list) {
		struct device_node *component_of_node = pos->dev->of_node;

		if (!component_of_node && pos->dev->parent)
			component_of_node = pos->dev->parent->of_node;

		if (component_of_node != node)
			continue;

		if (pos->driver->of_xlate_dai_id)
			ret = pos->driver->of_xlate_dai_id(pos, ep);

		break;
	}
	mutex_unlock(&client_mutex);

	if (ret != -ENOTSUPP)
		return ret;

	/*
	 * Non HDMI sound case, counting port/endpoint on its DT
	 * is enough. Let's count it.
	 */
	i = 0;
	id = -1;
	for_each_endpoint_of_node(node, endpoint) {
		if (endpoint == ep)
			id = i;
		i++;
	}
	if (id < 0)
		return -ENODEV;

	return id;
}
EXPORT_SYMBOL_GPL(snd_soc_get_dai_id);

--- simple-card-utils ----

int asoc_simple_card_parse_graph_dai(struct device_node *ep,
				     struct device_node **dai_of_node,
				     const char **dai_name)
{
	struct device_node *node;
	struct of_phandle_args args;
	int ret;

	if (!ep)
		return 0;
	if (!dai_name)
		return 0;

	node = of_graph_get_port_parent(ep);

	/* Get dai->name */
	args.np		= node;
	args.args[0]	= snd_soc_get_dai_id(ep);
	args.args_count	= (of_graph_get_endpoint_count(node) > 1);

	ret = snd_soc_get_dai_name(&args, dai_name);
	if (ret < 0)
		return ret;

	*dai_of_node = node;

	return 0;
}
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai);


Best regards
---
Kuninori Morimoto


More information about the Alsa-devel mailing list