diff options
author | Mark Brown <broonie@kernel.org> | 2021-03-31 17:53:49 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-03-31 17:53:49 +0300 |
commit | 326b0037fd6b5fc5640f3d37c80b62e2b3329017 (patch) | |
tree | 9249beb35343b61c8841f390709bbeffec01b21e | |
parent | e896ec390870287dcc92f3b46d80da88f3b4b1f8 (diff) | |
parent | 39af7f7a03d007e5590f0b852b3f2fed9e703d0f (diff) | |
download | linux-326b0037fd6b5fc5640f3d37c80b62e2b3329017.tar.xz |
Merge series "ASoC: simple-card: cleanup and prepare for Multi CPU/Codec support" from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:
Hi Mark
I want to add new audio-graph-card2 driver which can support
not only DPCM, but also Multi-CPU/Codec, and Codec2Codec.
And it is also supporting user customization.
But before supporting such driver, we need to cleanup existing
simple-card / audio-graph, because these and new driver are
sharing code.
This patch-set are cleanup and prepare for Multi-CPU/Codec support.
Kuninori Morimoto (6):
ASoC: simple-card-utils.c: remove old comment
ASoC: simple-card-utils: alloc dai_link information for CPU/Codec/Platform
ASoC: audio-graph: count DAI / link numbers as in order
ASoC: audio-graph: cleanup graph_for_each_link()
ASoC: simple-card: count DAI / link numbers as in order
ASoC: simple-card: cleanup graph_for_each_link()
include/sound/simple_card_utils.h | 7 +-
sound/soc/generic/audio-graph-card.c | 112 +++++++++++++------------
sound/soc/generic/simple-card-utils.c | 20 +++--
sound/soc/generic/simple-card.c | 115 +++++++++++++++-----------
4 files changed, 143 insertions(+), 111 deletions(-)
--
2.25.1
-rw-r--r-- | include/sound/simple_card_utils.h | 7 | ||||
-rw-r--r-- | sound/soc/generic/audio-graph-card.c | 112 | ||||
-rw-r--r-- | sound/soc/generic/simple-card-utils.c | 20 | ||||
-rw-r--r-- | sound/soc/generic/simple-card.c | 115 |
4 files changed, 143 insertions, 111 deletions
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index ba4a3e1897b9..86e46cbf9e14 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -43,9 +43,9 @@ struct asoc_simple_priv { struct simple_dai_props { struct asoc_simple_dai *cpu_dai; struct asoc_simple_dai *codec_dai; - struct snd_soc_dai_link_component cpus; /* single cpu */ - struct snd_soc_dai_link_component codecs; /* single codec */ - struct snd_soc_dai_link_component platforms; + struct snd_soc_dai_link_component *cpus; + struct snd_soc_dai_link_component *codecs; + struct snd_soc_dai_link_component *platforms; struct asoc_simple_data adata; struct snd_soc_codec_conf *codec_conf; unsigned int mclk_fs; @@ -54,6 +54,7 @@ struct asoc_simple_priv { struct asoc_simple_jack mic_jack; struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; + struct snd_soc_dai_link_component *dlcs; struct snd_soc_codec_conf *codec_conf; struct gpio_desc *pa_gpio; const struct snd_soc_ops *ops; diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 8c5cdcdc8713..ee1d924d68e5 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -212,8 +212,7 @@ static void graph_parse_mclk_fs(struct device_node *top, static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, struct device_node *cpu_ep, struct device_node *codec_ep, - struct link_info *li, - int dup_codec) + struct link_info *li) { struct device *dev = simple_priv_to_dev(priv); struct snd_soc_card *card = simple_priv_to_card(priv); @@ -229,18 +228,6 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, struct snd_soc_dai_link_component *codecs = dai_link->codecs; int ret; - /* - * Codec endpoint can be NULL for pluggable audio HW. - * Platform DT can populate the Codec endpoint depending on the - * plugged HW. - */ - if (!li->cpu && !codec_ep) - return 0; - - /* Do it all CPU endpoint, and 1st Codec endpoint */ - if (!li->cpu && dup_codec) - return 0; - port = of_get_parent(ep); ports = of_get_parent(port); node = of_graph_get_port_parent(ep); @@ -382,10 +369,6 @@ static int graph_dai_link_of(struct asoc_simple_priv *priv, struct asoc_simple_dai *codec_dai; int ret, single_cpu; - /* Do it only CPU turn */ - if (!li->cpu) - return 0; - dev_dbg(dev, "link_of (%pOF)\n", cpu_ep); li->link++; @@ -466,7 +449,7 @@ static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv, return false; } -static int graph_for_each_link(struct asoc_simple_priv *priv, +static int __graph_for_each_link(struct asoc_simple_priv *priv, struct link_info *li, int (*func_noml)(struct asoc_simple_priv *priv, struct device_node *cpu_ep, @@ -475,7 +458,7 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, int (*func_dpcm)(struct asoc_simple_priv *priv, struct device_node *cpu_ep, struct device_node *codec_ep, - struct link_info *li, int dup_codec)) + struct link_info *li)) { struct of_phandle_iterator it; struct device *dev = simple_priv_to_dev(priv); @@ -486,7 +469,7 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, struct device_node *codec_port; struct device_node *codec_port_old = NULL; struct asoc_simple_data adata; - int rc, ret; + int rc, ret = 0; /* loop for all listed CPU port */ of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { @@ -509,12 +492,21 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, graph_parse_convert(dev, cpu_ep, &adata); /* check if link requires DPCM parsing */ - if (parse_as_dpcm_link(priv, codec_port, &adata)) - ret = func_dpcm(priv, cpu_ep, codec_ep, li, - (codec_port_old == codec_port)); + if (parse_as_dpcm_link(priv, codec_port, &adata)) { + /* + * Codec endpoint can be NULL for pluggable audio HW. + * Platform DT can populate the Codec endpoint depending on the + * plugged HW. + */ + /* Do it all CPU endpoint, and 1st Codec endpoint */ + if (li->cpu || + ((codec_port_old != codec_port) && codec_ep)) + ret = func_dpcm(priv, cpu_ep, codec_ep, li); /* else normal sound */ - else - ret = func_noml(priv, cpu_ep, codec_ep, li); + } else { + if (li->cpu) + ret = func_noml(priv, cpu_ep, codec_ep, li); + } of_node_put(codec_ep); of_node_put(codec_port); @@ -529,6 +521,39 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, return 0; } +static int graph_for_each_link(struct asoc_simple_priv *priv, + struct link_info *li, + int (*func_noml)(struct asoc_simple_priv *priv, + struct device_node *cpu_ep, + struct device_node *codec_ep, + struct link_info *li), + int (*func_dpcm)(struct asoc_simple_priv *priv, + struct device_node *cpu_ep, + struct device_node *codec_ep, + struct link_info *li)) +{ + int ret; + /* + * Detect all CPU first, and Detect all Codec 2nd. + * + * In Normal sound case, all DAIs are detected + * as "CPU-Codec". + * + * In DPCM sound case, + * all CPUs are detected as "CPU-dummy", and + * all Codecs are detected as "dummy-Codec". + * To avoid random sub-device numbering, + * detect "dummy-Codec" in last; + */ + for (li->cpu = 1; li->cpu >= 0; li->cpu--) { + ret = __graph_for_each_link(priv, li, func_noml, func_dpcm); + if (ret < 0) + break; + } + + return ret; +} + static void graph_get_dais_count(struct asoc_simple_priv *priv, struct link_info *li); @@ -566,25 +591,11 @@ int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev) return ret; memset(&li, 0, sizeof(li)); - for (li.cpu = 1; li.cpu >= 0; li.cpu--) { - /* - * Detect all CPU first, and Detect all Codec 2nd. - * - * In Normal sound case, all DAIs are detected - * as "CPU-Codec". - * - * In DPCM sound case, - * all CPUs are detected as "CPU-dummy", and - * all Codecs are detected as "dummy-Codec". - * To avoid random sub-device numbering, - * detect "dummy-Codec" in last; - */ - ret = graph_for_each_link(priv, &li, - graph_dai_link_of, - graph_dai_link_of_dpcm); - if (ret < 0) - goto err; - } + ret = graph_for_each_link(priv, &li, + graph_dai_link_of, + graph_dai_link_of_dpcm); + if (ret < 0) + goto err; ret = asoc_simple_parse_card_name(card, NULL); if (ret < 0) @@ -628,15 +639,14 @@ static int graph_count_noml(struct asoc_simple_priv *priv, static int graph_count_dpcm(struct asoc_simple_priv *priv, struct device_node *cpu_ep, struct device_node *codec_ep, - struct link_info *li, - int dup_codec) + struct link_info *li) { struct device *dev = simple_priv_to_dev(priv); - li->link++; /* 1xCPU-dummy */ - li->dais++; /* 1xCPU */ - - if (!dup_codec && codec_ep) { + if (li->cpu) { + li->link++; /* 1xCPU-dummy */ + li->dais++; /* 1xCPU */ + } else { li->link++; /* 1xdummy-Codec */ li->conf++; /* 1xdummy-Codec */ li->dais++; /* 1xCodec */ diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 06c2512b6f2d..f05954529dfc 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -601,13 +601,15 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, struct snd_soc_dai_link *dai_link; struct simple_dai_props *dai_props; struct asoc_simple_dai *dais; + struct snd_soc_dai_link_component *dlcs; struct snd_soc_codec_conf *cconf = NULL; int i; dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL); dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL); dais = devm_kcalloc(dev, li->dais, sizeof(*dais), GFP_KERNEL); - if (!dai_props || !dai_link || !dais) + dlcs = devm_kcalloc(dev, li->link * 3, sizeof(*dai_props), GFP_KERNEL); + if (!dai_props || !dai_link || !dais || !dlcs) return -ENOMEM; if (li->conf) { @@ -617,27 +619,27 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, } /* - * Use snd_soc_dai_link_component instead of legacy style - * It is codec only. but cpu/platform will be supported in the future. - * see - * soc-core.c :: snd_soc_init_multicodec() - * * "platform" might be removed * see * simple-card-utils.c :: asoc_simple_canonicalize_platform() */ for (i = 0; i < li->link; i++) { - dai_link[i].cpus = &dai_props[i].cpus; + dai_props[i].cpus = dlcs + (3 * i) + 0; + dai_props[i].codecs = dlcs + (3 * i) + 1; + dai_props[i].platforms = dlcs + (3 * i) + 2; + + dai_link[i].cpus = dai_props[i].cpus; dai_link[i].num_cpus = 1; - dai_link[i].codecs = &dai_props[i].codecs; + dai_link[i].codecs = dai_props[i].codecs; dai_link[i].num_codecs = 1; - dai_link[i].platforms = &dai_props[i].platforms; + dai_link[i].platforms = dai_props[i].platforms; dai_link[i].num_platforms = 1; } priv->dai_props = dai_props; priv->dai_link = dai_link; priv->dais = dais; + priv->dlcs = dlcs; priv->codec_conf = cconf; card->dai_link = priv->dai_link; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 75365c7bb393..41aa40765a8d 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -129,15 +129,6 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, char *prefix = ""; int ret; - /* - * |CPU |Codec : turn - * CPU |Pass |return - * Codec |return|Pass - * np - */ - if (li->cpu == (np == codec)) - return 0; - dev_dbg(dev, "link_of DPCM (%pOF)\n", np); li->link++; @@ -260,15 +251,6 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv, char *prefix = ""; int ret, single_cpu; - /* - * |CPU |Codec : turn - * CPU |Pass |return - * Codec |return|return - * np - */ - if (!li->cpu || np == codec) - return 0; - cpu = np; node = of_get_parent(np); li->link++; @@ -342,7 +324,7 @@ dai_link_of_err: return ret; } -static int simple_for_each_link(struct asoc_simple_priv *priv, +static int __simple_for_each_link(struct asoc_simple_priv *priv, struct link_info *li, int (*func_noml)(struct asoc_simple_priv *priv, struct device_node *np, @@ -402,11 +384,26 @@ static int simple_for_each_link(struct asoc_simple_priv *priv, */ if (dpcm_selectable && (num > 2 || - adata.convert_rate || adata.convert_channels)) - ret = func_dpcm(priv, np, codec, li, is_top); + adata.convert_rate || adata.convert_channels)) { + /* + * np + * |1(CPU)|0(Codec) li->cpu + * CPU |Pass |return + * Codec |return|Pass + */ + if (li->cpu != (np == codec)) + ret = func_dpcm(priv, np, codec, li, is_top); /* else normal sound */ - else - ret = func_noml(priv, np, codec, li, is_top); + } else { + /* + * np + * |1(CPU)|0(Codec) li->cpu + * CPU |Pass |return + * Codec |return|return + */ + if (li->cpu && (np != codec)) + ret = func_noml(priv, np, codec, li, is_top); + } if (ret < 0) { of_node_put(codec); @@ -424,6 +421,39 @@ static int simple_for_each_link(struct asoc_simple_priv *priv, return ret; } +static int simple_for_each_link(struct asoc_simple_priv *priv, + struct link_info *li, + int (*func_noml)(struct asoc_simple_priv *priv, + struct device_node *np, + struct device_node *codec, + struct link_info *li, bool is_top), + int (*func_dpcm)(struct asoc_simple_priv *priv, + struct device_node *np, + struct device_node *codec, + struct link_info *li, bool is_top)) +{ + int ret; + /* + * Detect all CPU first, and Detect all Codec 2nd. + * + * In Normal sound case, all DAIs are detected + * as "CPU-Codec". + * + * In DPCM sound case, + * all CPUs are detected as "CPU-dummy", and + * all Codecs are detected as "dummy-Codec". + * To avoid random sub-device numbering, + * detect "dummy-Codec" in last; + */ + for (li->cpu = 1; li->cpu >= 0; li->cpu--) { + ret = __simple_for_each_link(priv, li, func_noml, func_dpcm); + if (ret < 0) + break; + } + + return ret; +} + static int simple_parse_of(struct asoc_simple_priv *priv) { struct device *dev = simple_priv_to_dev(priv); @@ -449,25 +479,11 @@ static int simple_parse_of(struct asoc_simple_priv *priv) /* Single/Muti DAI link(s) & New style of DT node */ memset(&li, 0, sizeof(li)); - for (li.cpu = 1; li.cpu >= 0; li.cpu--) { - /* - * Detect all CPU first, and Detect all Codec 2nd. - * - * In Normal sound case, all DAIs are detected - * as "CPU-Codec". - * - * In DPCM sound case, - * all CPUs are detected as "CPU-dummy", and - * all Codecs are detected as "dummy-Codec". - * To avoid random sub-device numbering, - * detect "dummy-Codec" in last; - */ - ret = simple_for_each_link(priv, &li, - simple_dai_link_of, - simple_dai_link_of_dpcm); - if (ret < 0) - return ret; - } + ret = simple_for_each_link(priv, &li, + simple_dai_link_of, + simple_dai_link_of_dpcm); + if (ret < 0) + return ret; ret = asoc_simple_parse_card_name(card, PREFIX); if (ret < 0) @@ -483,9 +499,8 @@ static int simple_count_noml(struct asoc_simple_priv *priv, struct device_node *codec, struct link_info *li, bool is_top) { - li->dais++; /* CPU or Codec */ - if (np != codec) - li->link++; /* CPU-Codec */ + li->link += 1; + li->dais += 2; return 0; } @@ -495,10 +510,14 @@ static int simple_count_dpcm(struct asoc_simple_priv *priv, struct device_node *codec, struct link_info *li, bool is_top) { - li->dais++; /* CPU or Codec */ - li->link++; /* CPU-dummy or dummy-Codec */ - if (np == codec) + if (li->cpu) { + li->link++; /* CPU-dummy */ + li->dais++; + } else { + li->link++; /* dummy-Codec */ + li->dais++; li->conf++; + } return 0; } |