[PATCH 00/11] ASoC: simple-card: sync support
Hi Mark
We have simle-card / audio-graph / audio-graph2, basically these supports same feature but is using different DT style.
Because we are using 3 drivers, some feature was added to one driver, but other drivers doesn't have it. This patch set try to sync it on these 3 drivers.
Kuninori Morimoto (11): ASoC: simple-card-utils: remove both playback/capture_only check ASoC: audio-graph-card2: add ep_to_port() / port_to_ports() ASoC: audio-graph-card2: remove ports node name check ASoC: audio-graph-card2: expand dai_link property part ASoC: audio-graph-card2: merge graph_parse_mclk_fs() into graph_link_init() ASoC: audio-graph-card: add ep_to_port() / port_to_ports() ASoC: audio-graph-card: remove ports node name check ASoC: audio-graph-card: enable playback/capture_only property ASoC: audio-graph-card: merge graph_parse_mclk_fs() into graph_link_init() ASoC: simple-audio-card: enable playback/capture_only property ASoC: simple-audio-card: merge simple_parse_mclk_fs() into simple_link_init()
include/sound/simple_card_utils.h | 2 +- sound/soc/generic/audio-graph-card.c | 95 ++++++++------ sound/soc/generic/audio-graph-card2.c | 171 +++++++++++++++----------- sound/soc/generic/simple-card-utils.c | 23 ++-- sound/soc/generic/simple-card.c | 56 +++++---- 5 files changed, 198 insertions(+), 149 deletions(-)
soc-pcm.c :: soc_get_playback_capture() will indicate error if both playback_only / capture_only were true.
Thus, graph_util_parse_link_direction() which setup playback_only / capture_only don't need to check it. And, its return value is not used on existing driver. Let's remove it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/simple_card_utils.h | 2 +- sound/soc/generic/simple-card-utils.c | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index ad67957b7b48c..1a96e177158c8 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -195,7 +195,7 @@ int graph_util_is_ports0(struct device_node *port); int graph_util_parse_dai(struct device *dev, struct device_node *ep, struct snd_soc_dai_link_component *dlc, int *is_single_link);
-int graph_util_parse_link_direction(struct device_node *np, +void graph_util_parse_link_direction(struct device_node *np, bool *is_playback_only, bool *is_capture_only);
#ifdef DEBUG diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index b4876b4f259dd..17718c58793d2 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -1126,7 +1126,7 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep, } EXPORT_SYMBOL_GPL(graph_util_parse_dai);
-int graph_util_parse_link_direction(struct device_node *np, +void graph_util_parse_link_direction(struct device_node *np, bool *playback_only, bool *capture_only) { bool is_playback_only = false; @@ -1135,13 +1135,8 @@ int graph_util_parse_link_direction(struct device_node *np, is_playback_only = of_property_read_bool(np, "playback-only"); is_capture_only = of_property_read_bool(np, "capture-only");
- if (is_playback_only && is_capture_only) - return -EINVAL; - *playback_only = is_playback_only; *capture_only = is_capture_only; - - return 0; } EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
Current audio-graph-card2 is using of_get_parent() to get "port" from "ep", or get "ports" from "port". But it is difficlut to understand, and "ports" might not exist. This patch adds ep_to_port() to get "port" from "ep", and port_to_ports() to get "ports" from "port". "ports" will be NULL if not exist.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card2.c | 46 +++++++++++++++++---------- 1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 81e84095107ed..58123fbc29046 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -236,6 +236,18 @@ enum graph_type {
#define port_to_endpoint(port) of_get_child_by_name(port, "endpoint")
+#define ep_to_port(ep) of_get_parent(ep) +static struct device_node *port_to_ports(struct device_node *port) +{ + struct device_node *ports = of_get_parent(port); + + if (!of_node_name_eq(ports, "ports")) { + of_node_put(ports); + return NULL; + } + return ports; +} + static enum graph_type __graph_get_type(struct device_node *lnk) { struct device_node *np, *parent_np; @@ -320,7 +332,7 @@ static int graph_lnk_is_multi(struct device_node *lnk)
static struct device_node *graph_get_next_multi_ep(struct device_node **port) { - struct device_node *ports = of_get_parent(*port); + struct device_node *ports = port_to_ports(*port); struct device_node *ep = NULL; struct device_node *rep = NULL;
@@ -365,8 +377,8 @@ static const struct snd_soc_ops graph_ops = { static void graph_parse_convert(struct device_node *ep, struct simple_dai_props *props) { - struct device_node *port = of_get_parent(ep); - struct device_node *ports = of_get_parent(port); + struct device_node *port = ep_to_port(ep); + struct device_node *ports = port_to_ports(port); struct simple_util_data *adata = &props->adata;
if (of_node_name_eq(ports, "ports")) @@ -381,8 +393,8 @@ static void graph_parse_convert(struct device_node *ep, static void graph_parse_mclk_fs(struct device_node *ep, struct simple_dai_props *props) { - struct device_node *port = of_get_parent(ep); - struct device_node *ports = of_get_parent(port); + struct device_node *port = ep_to_port(ep); + struct device_node *ports = port_to_ports(port);
if (of_node_name_eq(ports, "ports")) of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); @@ -481,8 +493,8 @@ static int __graph_parse_node(struct simple_util_priv *priv, if (!is_cpu && gtype == GRAPH_DPCM) { struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx); struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx); - struct device_node *rport = of_get_parent(ep); - struct device_node *rports = of_get_parent(rport); + struct device_node *rport = ep_to_port(ep); + struct device_node *rports = port_to_ports(rport);
if (of_node_name_eq(rports, "ports")) snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); @@ -539,11 +551,11 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, */ struct device_node *mcpu_ep = port_to_endpoint(mcpu_port); struct device_node *mcpu_ep_n = mcpu_ep; - struct device_node *mcpu_port_top = of_get_next_child(of_get_parent(mcpu_port), NULL); + struct device_node *mcpu_port_top = of_get_next_child(port_to_ports(mcpu_port), NULL); struct device_node *mcpu_ep_top = port_to_endpoint(mcpu_port_top); struct device_node *mcodec_ep_top = of_graph_get_remote_endpoint(mcpu_ep_top); - struct device_node *mcodec_port_top = of_get_parent(mcodec_ep_top); - struct device_node *mcodec_ports = of_get_parent(mcodec_port_top); + struct device_node *mcodec_port_top = ep_to_port(mcodec_ep_top); + struct device_node *mcodec_ports = port_to_ports(mcodec_port_top); int nm_max = max(dai_link->num_cpus, dai_link->num_codecs); int ret = -EINVAL;
@@ -566,9 +578,9 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, }
mcodec_ep_n = of_graph_get_remote_endpoint(mcpu_ep_n); - mcodec_port = of_get_parent(mcodec_ep_n); + mcodec_port = ep_to_port(mcodec_ep_n);
- if (mcodec_ports != of_get_parent(mcodec_port)) + if (mcodec_ports != port_to_ports(mcodec_port)) goto mcpu_err;
codec_idx = 0; @@ -765,12 +777,12 @@ static void graph_link_init(struct simple_util_priv *priv, if (graph_lnk_is_multi(port)) { of_node_get(port); ep = graph_get_next_multi_ep(&port); - port = of_get_parent(ep); + port = ep_to_port(ep); } else { ep = port_to_endpoint(port); }
- ports = of_get_parent(port); + ports = port_to_ports(port);
/* * ports { @@ -966,7 +978,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv, */ of_node_get(lnk); port0 = lnk; - ports = of_get_parent(port0); + ports = port_to_ports(port0); port1 = of_get_next_child(ports, lnk);
/* @@ -1098,7 +1110,7 @@ static int graph_counter(struct device_node *lnk) * ignore first lnk part */ if (graph_lnk_is_multi(lnk)) { - struct device_node *ports = of_get_parent(lnk); + struct device_node *ports = port_to_ports(lnk); struct device_node *port = NULL; int cnt = 0;
@@ -1195,7 +1207,7 @@ static int graph_count_c2c(struct simple_util_priv *priv, struct device_node *lnk, struct link_info *li) { - struct device_node *ports = of_get_parent(lnk); + struct device_node *ports = port_to_ports(lnk); struct device_node *port0 = lnk; struct device_node *port1 = of_get_next_child(ports, of_node_get(lnk)); struct device_node *ep0 = port_to_endpoint(port0);
Current audio-graph-card2 is checking if the node name was "ports" or not when parsing the property.
if (of_node_name_eq(ports, "ports")) of_xxx(ports, ...);
Now, it is using new port_to_ports() which will be NULL if the node doesn't have "ports", and each of_xxx functions will do nothing if node was NULL. Now we don't need to check ports node name. Let's remove and cleanup it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card2.c | 15 +++++++-------- sound/soc/generic/simple-card-utils.c | 3 +++ 2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 58123fbc29046..3029e8ebfa222 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -381,8 +381,7 @@ static void graph_parse_convert(struct device_node *ep, struct device_node *ports = port_to_ports(port); struct simple_util_data *adata = &props->adata;
- if (of_node_name_eq(ports, "ports")) - simple_util_parse_convert(ports, NULL, adata); + simple_util_parse_convert(ports, NULL, adata); simple_util_parse_convert(port, NULL, adata); simple_util_parse_convert(ep, NULL, adata);
@@ -396,8 +395,7 @@ static void graph_parse_mclk_fs(struct device_node *ep, struct device_node *port = ep_to_port(ep); struct device_node *ports = port_to_ports(port);
- if (of_node_name_eq(ports, "ports")) - of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); + of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); of_property_read_u32(port, "mclk-fs", &props->mclk_fs); of_property_read_u32(ep, "mclk-fs", &props->mclk_fs);
@@ -496,8 +494,7 @@ static int __graph_parse_node(struct simple_util_priv *priv, struct device_node *rport = ep_to_port(ep); struct device_node *rports = port_to_ports(rport);
- if (of_node_name_eq(rports, "ports")) - snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); + snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix");
of_node_put(rport); @@ -717,6 +714,9 @@ static void graph_parse_daifmt(struct device_node *node, { unsigned int fmt;
+ if (!node) + return; + /* * see also above "daifmt" explanation * and samples. @@ -798,8 +798,7 @@ static void graph_link_init(struct simple_util_priv *priv, */ graph_parse_daifmt(ep, &daifmt, &bit_frame); /* (C) */ graph_parse_daifmt(port, &daifmt, &bit_frame); /* (B) */ - if (of_node_name_eq(ports, "ports")) - graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */ + graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */
/* * convert bit_frame diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 17718c58793d2..7ebf59a03e698 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -46,6 +46,9 @@ void simple_util_parse_convert(struct device_node *np, { char prop[128];
+ if (!np) + return; + if (!prefix) prefix = "";
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 --- sound/soc/generic/audio-graph-card2.c | 95 +++++++++++++++++---------- sound/soc/generic/simple-card-utils.c | 13 ++-- 2 files changed, 66 insertions(+), 42 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 3029e8ebfa222..bd714a6f74e61 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -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); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 7ebf59a03e698..d0f8258a4790a 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -1132,14 +1132,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);
Now graph_link_init() is parsing dai_link related property. Let's handle mclk_fs on it, too.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card2.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index bd714a6f74e61..8eea818887580 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -389,20 +389,6 @@ static void graph_parse_convert(struct device_node *ep, of_node_put(ports); }
-static void graph_parse_mclk_fs(struct device_node *ep, - struct simple_dai_props *props) -{ - struct device_node *port = ep_to_port(ep); - struct device_node *ports = port_to_ports(port); - - of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); - of_property_read_u32(port, "mclk-fs", &props->mclk_fs); - of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); - - of_node_put(port); - of_node_put(ports); -} - static int __graph_parse_node(struct simple_util_priv *priv, enum graph_type gtype, struct device_node *ep, @@ -424,8 +410,6 @@ static int __graph_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, idx); }
- graph_parse_mclk_fs(ep, dai_props); - ret = graph_util_parse_dai(dev, ep, dlc, &is_single_links); if (ret < 0) return ret; @@ -770,6 +754,7 @@ static void graph_link_init(struct simple_util_priv *priv, int is_cpu_node) { 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); struct device_node *ep_cpu, *ep_codec; struct device_node *ports_cpu, *ports_codec; unsigned int daifmt = 0, daiclk = 0; @@ -813,6 +798,14 @@ static void graph_link_init(struct simple_util_priv *priv, graph_util_parse_link_direction(ep_cpu, &playback_only, &capture_only); graph_util_parse_link_direction(ep_codec, &playback_only, &capture_only);
+ of_property_read_u32(lnk, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ports_cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ports_codec, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(port_cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(port_codec, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ep_cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ep_codec, "mclk-fs", &dai_props->mclk_fs); + /* * convert bit_frame * We need to flip clock_provider if it was CPU node,
Current audio-graph-card is using of_get_parent() to get "port" from "ep", or get "ports" from "port". But it is difficlut to understand, and "ports" might not exist. This patch adds ep_to_port() to get "port" from "ep", and port_to_ports() to get "ports" from "port". "ports" will be NULL if not exist.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 83e3ba773fbd6..552b94908cf7c 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -19,6 +19,18 @@
#define DPCM_SELECTABLE 1
+#define ep_to_port(ep) of_get_parent(ep) +static struct device_node *port_to_ports(struct device_node *port) +{ + struct device_node *ports = of_get_parent(port); + + if (!of_node_name_eq(ports, "ports")) { + of_node_put(ports); + return NULL; + } + return ports; +} + static int graph_outdrv_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -68,8 +80,8 @@ static void graph_parse_convert(struct device *dev, struct simple_util_data *adata) { struct device_node *top = dev->of_node; - struct device_node *port = of_get_parent(ep); - struct device_node *ports = of_get_parent(port); + struct device_node *port = ep_to_port(ep); + struct device_node *ports = port_to_ports(port); struct device_node *node = of_graph_get_port_parent(ep);
simple_util_parse_convert(top, NULL, adata); @@ -87,8 +99,8 @@ static void graph_parse_mclk_fs(struct device_node *top, struct device_node *ep, struct simple_dai_props *props) { - struct device_node *port = of_get_parent(ep); - struct device_node *ports = of_get_parent(port); + struct device_node *port = ep_to_port(ep); + struct device_node *ports = port_to_ports(port);
of_property_read_u32(top, "mclk-fs", &props->mclk_fs); if (of_node_name_eq(ports, "ports")) @@ -231,8 +243,8 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, "be.%pOFP.%s", codecs->of_node, codecs->dai_name);
/* check "prefix" from top node */ - port = of_get_parent(ep); - ports = of_get_parent(port); + port = ep_to_port(ep); + ports = port_to_ports(port); snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, "prefix"); if (of_node_name_eq(ports, "ports")) @@ -350,7 +362,7 @@ static int __graph_for_each_link(struct simple_util_priv *priv,
/* get codec */ codec_ep = of_graph_get_remote_endpoint(cpu_ep); - codec_port = of_get_parent(codec_ep); + codec_port = ep_to_port(codec_ep);
/* get convert-xxx property */ memset(&adata, 0, sizeof(adata));
Current audio-graph-card is checking if the node name was "ports" or not when parsing the property.
if (of_node_name_eq(ports, "ports")) of_xxx(ports, ...);
Now, it is using new port_to_ports() which will be NULL if the node doesn't have "ports", and each of_xxx functions will do nothing if node was NULL. Now we don't need to check ports node name. Let's remove and cleanup it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 552b94908cf7c..c60f001468591 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -85,8 +85,7 @@ static void graph_parse_convert(struct device *dev, struct device_node *node = of_graph_get_port_parent(ep);
simple_util_parse_convert(top, NULL, adata); - if (of_node_name_eq(ports, "ports")) - simple_util_parse_convert(ports, NULL, adata); + simple_util_parse_convert(ports, NULL, adata); simple_util_parse_convert(port, NULL, adata); simple_util_parse_convert(ep, NULL, adata);
@@ -103,8 +102,7 @@ static void graph_parse_mclk_fs(struct device_node *top, struct device_node *ports = port_to_ports(port);
of_property_read_u32(top, "mclk-fs", &props->mclk_fs); - if (of_node_name_eq(ports, "ports")) - of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); + of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); of_property_read_u32(port, "mclk-fs", &props->mclk_fs); of_property_read_u32(ep, "mclk-fs", &props->mclk_fs);
@@ -245,12 +243,9 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, /* check "prefix" from top node */ port = ep_to_port(ep); ports = port_to_ports(port); - snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, - "prefix"); - if (of_node_name_eq(ports, "ports")) - snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, "prefix"); - snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node, - "prefix"); + snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, "prefix"); + snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, "prefix"); + snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node, "prefix");
of_node_put(ports); of_node_put(port);
Audio Graph Card2 is supporting playback/capture_only property, let's follow Audio Graph Card, too.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index c60f001468591..6a19e40d2c4aa 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -149,26 +149,44 @@ static int graph_parse_node(struct simple_util_priv *priv, }
static int graph_link_init(struct simple_util_priv *priv, - struct device_node *cpu_ep, - struct device_node *codec_ep, + struct device_node *ep_cpu, + struct device_node *ep_codec, struct link_info *li, char *name) { struct device *dev = simple_priv_to_dev(priv); + struct device_node *top = dev->of_node; struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct device_node *port_cpu = ep_to_port(ep_cpu); + struct device_node *port_codec = ep_to_port(ep_codec); + bool playback_only = 0, capture_only = 0; int ret;
- ret = simple_util_parse_daifmt(dev, cpu_ep, codec_ep, + ret = simple_util_parse_daifmt(dev, ep_cpu, ep_codec, NULL, &dai_link->dai_fmt); if (ret < 0) - return ret; + goto init_end; + + graph_util_parse_link_direction(top, &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); + + dai_link->playback_only = playback_only; + dai_link->capture_only = capture_only;
dai_link->init = simple_util_dai_init; dai_link->ops = &graph_ops; if (priv->ops) dai_link->ops = priv->ops;
- return simple_util_set_dailink_name(dev, dai_link, name); + ret = simple_util_set_dailink_name(dev, dai_link, name); +init_end: + of_node_put(port_cpu); + of_node_put(port_codec); + + return ret; }
static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
Now graph_link_init() is parsing dai_link related property. Let's handle mclk_fs on it, too.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/audio-graph-card.c | 32 +++++++++++----------------- 1 file changed, 13 insertions(+), 19 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 6a19e40d2c4aa..7b981aa8690ac 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -94,29 +94,12 @@ static void graph_parse_convert(struct device *dev, of_node_put(node); }
-static void graph_parse_mclk_fs(struct device_node *top, - struct device_node *ep, - struct simple_dai_props *props) -{ - struct device_node *port = ep_to_port(ep); - struct device_node *ports = port_to_ports(port); - - of_property_read_u32(top, "mclk-fs", &props->mclk_fs); - of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); - of_property_read_u32(port, "mclk-fs", &props->mclk_fs); - of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); - - of_node_put(port); - of_node_put(ports); -} - static int graph_parse_node(struct simple_util_priv *priv, struct device_node *ep, struct link_info *li, int *cpu) { struct device *dev = simple_priv_to_dev(priv); - struct device_node *top = dev->of_node; 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); struct snd_soc_dai_link_component *dlc; @@ -131,8 +114,6 @@ static int graph_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, 0); }
- graph_parse_mclk_fs(top, ep, dai_props); - ret = graph_util_parse_dai(dev, ep, dlc, cpu); if (ret < 0) return ret; @@ -157,8 +138,11 @@ static int graph_link_init(struct simple_util_priv *priv, struct device *dev = simple_priv_to_dev(priv); struct device_node *top = dev->of_node; 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); struct device_node *port_cpu = ep_to_port(ep_cpu); struct device_node *port_codec = ep_to_port(ep_codec); + struct device_node *ports_cpu = port_to_ports(port_cpu); + struct device_node *ports_codec = port_to_ports(port_codec); bool playback_only = 0, capture_only = 0; int ret;
@@ -173,6 +157,14 @@ static int graph_link_init(struct simple_util_priv *priv, graph_util_parse_link_direction(ep_cpu, &playback_only, &capture_only); graph_util_parse_link_direction(ep_codec, &playback_only, &capture_only);
+ of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ports_cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ports_codec, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(port_cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(port_codec, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ep_cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(ep_codec, "mclk-fs", &dai_props->mclk_fs); + dai_link->playback_only = playback_only; dai_link->capture_only = capture_only;
@@ -183,6 +175,8 @@ static int graph_link_init(struct simple_util_priv *priv,
ret = simple_util_set_dailink_name(dev, dai_link, name); init_end: + of_node_put(ports_cpu); + of_node_put(ports_codec); of_node_put(port_cpu); of_node_put(port_codec);
Audio Graph Card2 is supporting playback/capture_only property, let's follow Simple Audio Card, too.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/simple-card.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 9c79ff6a568f0..e436e8fcfa0f2 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -187,24 +187,39 @@ static int simple_parse_node(struct simple_util_priv *priv, }
static int simple_link_init(struct simple_util_priv *priv, - struct device_node *node, + struct device_node *cpu, struct device_node *codec, struct link_info *li, char *prefix, char *name) { struct device *dev = simple_priv_to_dev(priv); + struct device_node *top = dev->of_node; struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); + struct device_node *node = of_get_parent(cpu); + bool playback_only = 0, capture_only = 0; int ret;
ret = simple_util_parse_daifmt(dev, node, codec, prefix, &dai_link->dai_fmt); if (ret < 0) - return 0; + goto init_end; + + graph_util_parse_link_direction(top, &playback_only, &capture_only); + graph_util_parse_link_direction(node, &playback_only, &capture_only); + graph_util_parse_link_direction(cpu, &playback_only, &capture_only); + graph_util_parse_link_direction(codec, &playback_only, &capture_only); + + dai_link->playback_only = playback_only; + dai_link->capture_only = capture_only;
dai_link->init = simple_util_dai_init; dai_link->ops = &simple_ops;
- return simple_util_set_dailink_name(dev, dai_link, name); + ret = simple_util_set_dailink_name(dev, dai_link, name); +init_end: + of_node_put(node); + + return ret; }
static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, @@ -278,7 +293,7 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv,
snd_soc_dai_link_set_capabilities(dai_link);
- ret = simple_link_init(priv, node, codec, li, prefix, dai_name); + ret = simple_link_init(priv, np, codec, li, prefix, dai_name);
out_put_node: li->link++; @@ -336,7 +351,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv, simple_util_canonicalize_cpu(cpus, single_cpu); simple_util_canonicalize_platform(platforms, cpus);
- ret = simple_link_init(priv, node, codec, li, prefix, dai_name); + ret = simple_link_init(priv, cpu, codec, li, prefix, dai_name);
dai_link_of_err: of_node_put(plat);
Now graph_link_init() is parsing dai_link related property. Let's handle mclk_fs on it, too.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/simple-card.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index e436e8fcfa0f2..2de5e6efe947f 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -129,24 +129,6 @@ static void simple_parse_convert(struct device *dev, of_node_put(node); }
-static void simple_parse_mclk_fs(struct device_node *top, - struct device_node *np, - struct simple_dai_props *props, - char *prefix) -{ - struct device_node *node = of_get_parent(np); - char prop[128]; - - snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX); - of_property_read_u32(top, prop, &props->mclk_fs); - - snprintf(prop, sizeof(prop), "%smclk-fs", prefix); - of_property_read_u32(node, prop, &props->mclk_fs); - of_property_read_u32(np, prop, &props->mclk_fs); - - of_node_put(node); -} - static int simple_parse_node(struct simple_util_priv *priv, struct device_node *np, struct link_info *li, @@ -154,7 +136,6 @@ static int simple_parse_node(struct simple_util_priv *priv, int *cpu) { struct device *dev = simple_priv_to_dev(priv); - struct device_node *top = dev->of_node; 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); struct snd_soc_dai_link_component *dlc; @@ -169,8 +150,6 @@ static int simple_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, 0); }
- simple_parse_mclk_fs(top, np, dai_props, prefix); - ret = simple_parse_dai(dev, np, dlc, cpu); if (ret) return ret; @@ -195,6 +174,7 @@ static int simple_link_init(struct simple_util_priv *priv, struct device *dev = simple_priv_to_dev(priv); struct device_node *top = dev->of_node; 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); struct device_node *node = of_get_parent(cpu); bool playback_only = 0, capture_only = 0; int ret; @@ -209,6 +189,15 @@ static int simple_link_init(struct simple_util_priv *priv, graph_util_parse_link_direction(cpu, &playback_only, &capture_only); graph_util_parse_link_direction(codec, &playback_only, &capture_only);
+ of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(node, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(cpu, PREFIX "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec, "mclk-fs", &dai_props->mclk_fs); + of_property_read_u32(codec, PREFIX "mclk-fs", &dai_props->mclk_fs); + dai_link->playback_only = playback_only; dai_link->capture_only = capture_only;
On Tue, 28 May 2024 05:04:58 +0000, Kuninori Morimoto wrote:
We have simle-card / audio-graph / audio-graph2, basically these supports same feature but is using different DT style.
Because we are using 3 drivers, some feature was added to one driver, but other drivers doesn't have it. This patch set try to sync it on these 3 drivers.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/11] ASoC: simple-card-utils: remove both playback/capture_only check commit: 45919c28134519080a85a5fb66d0f65955ef7572 [02/11] ASoC: audio-graph-card2: add ep_to_port() / port_to_ports() commit: 72999a1b6663f1ff604e79aea54f168f78e2441a [03/11] ASoC: audio-graph-card2: remove ports node name check commit: 33ae57277ce08b83c65c18a09bf09499de613c01 [04/11] ASoC: audio-graph-card2: expand dai_link property part commit: 844de7eebe97a1c277f8a408457712086c957195 [05/11] ASoC: audio-graph-card2: merge graph_parse_mclk_fs() into graph_link_init() commit: f2d7e85962baf410b1bbbb4cf23a1ca59261ef76 [06/11] ASoC: audio-graph-card: add ep_to_port() / port_to_ports() commit: df23fcd56bb75ab522350bd8cb52bde9067aea45 [07/11] ASoC: audio-graph-card: remove ports node name check commit: 84c9601a92b755f869ac811607402e5b2162c225 [08/11] ASoC: audio-graph-card: enable playback/capture_only property commit: f23bac6e6913eed9eb831b4893255ea862d40ea5 [09/11] ASoC: audio-graph-card: merge graph_parse_mclk_fs() into graph_link_init() commit: a0174c88386b48bea7c35bc5a927f7057cb45d38 [10/11] ASoC: simple-audio-card: enable playback/capture_only property commit: 42d37e8de8f2d121481a65e6a3e10f6387c0ad4c [11/11] ASoC: simple-audio-card: merge simple_parse_mclk_fs() into simple_link_init() commit: c4cfe1136d6edf8970ccdd944b7f86f7aa3edb77
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Kuninori Morimoto
-
Mark Brown