[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