summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2021-03-31 17:53:49 +0300
committerMark Brown <broonie@kernel.org>2021-03-31 17:53:49 +0300
commit326b0037fd6b5fc5640f3d37c80b62e2b3329017 (patch)
tree9249beb35343b61c8841f390709bbeffec01b21e
parente896ec390870287dcc92f3b46d80da88f3b4b1f8 (diff)
parent39af7f7a03d007e5590f0b852b3f2fed9e703d0f (diff)
downloadlinux-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.h7
-rw-r--r--sound/soc/generic/audio-graph-card.c112
-rw-r--r--sound/soc/generic/simple-card-utils.c20
-rw-r--r--sound/soc/generic/simple-card.c115
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;
}