summaryrefslogtreecommitdiff
path: root/sound/soc/generic/simple-card-utils.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2023-06-26 16:38:02 +0300
committerTakashi Iwai <tiwai@suse.de>2023-06-26 16:38:02 +0300
commitd6048fdc870240e5020343f8af0c825829c232bd (patch)
treed83ca76eaac5f8bf1c4c16f003aad64baa8fae62 /sound/soc/generic/simple-card-utils.c
parenta15b51375684c2bfa6017bb185139477e7a3b96c (diff)
parent2d0cad0473bd1ffbc5842be0b9f2546265acb011 (diff)
downloadlinux-d6048fdc870240e5020343f8af0c825829c232bd.tar.xz
Merge tag 'asoc-v6.5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v6.5 A fairly quiet release from a core and framework point of view, but a very big one from the point of view of new drivers: - More refectoring from Morimoto-san, this time mainly around DAI links and how we control the ordering of trigger() callbacks. - Convert a lot of drivers to use maple tree based caches. - Lots of work on the x86 driver stack. - Compressed audio support for Qualcomm. - Support for AMD SoundWire, Analog Devices SSM3515, Google Chameleon, Ingenic X1000, Intel systems with various CODECs, Longsoon platforms, Maxim MAX98388, Mediatek MT8188, Nuvoton NAU8825C, NXP platforms with NAU8822, Qualcomm WSA884x, StarFive JH7110, Texas Instruments TAS2781.
Diffstat (limited to 'sound/soc/generic/simple-card-utils.c')
-rw-r--r--sound/soc/generic/simple-card-utils.c118
1 files changed, 105 insertions, 13 deletions
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index e5ff61c1e9d1..3019626b0592 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -889,11 +889,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
dev_dbg(dev, "link %d, dais %d, ccnf %d\n",
li->link, dai_num, cnf_num);
- /* dummy CPU/Codec */
- priv->dummy.of_node = NULL;
- priv->dummy.dai_name = "snd-soc-dummy-dai";
- priv->dummy.name = "snd-soc-dummy";
-
priv->dai_props = dai_props;
priv->dai_link = dai_link;
priv->dais = dais;
@@ -908,7 +903,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
for (i = 0; i < li->link; i++) {
if (li->num[i].cpus) {
/* Normal CPU */
- dai_props[i].cpus =
dai_link[i].cpus = dlcs;
dai_props[i].num.cpus =
dai_link[i].num_cpus = li->num[i].cpus;
@@ -918,15 +912,13 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
dais += li->num[i].cpus;
} else {
/* DPCM Be's CPU = dummy */
- dai_props[i].cpus =
- dai_link[i].cpus = &priv->dummy;
+ dai_link[i].cpus = &asoc_dummy_dlc;
dai_props[i].num.cpus =
dai_link[i].num_cpus = 1;
}
if (li->num[i].codecs) {
/* Normal Codec */
- dai_props[i].codecs =
dai_link[i].codecs = dlcs;
dai_props[i].num.codecs =
dai_link[i].num_codecs = li->num[i].codecs;
@@ -942,15 +934,13 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
}
} else {
/* DPCM Fe's Codec = dummy */
- dai_props[i].codecs =
- dai_link[i].codecs = &priv->dummy;
+ dai_link[i].codecs = &asoc_dummy_dlc;
dai_props[i].num.codecs =
dai_link[i].num_codecs = 1;
}
if (li->num[i].platforms) {
/* Have Platform */
- dai_props[i].platforms =
dai_link[i].platforms = dlcs;
dai_props[i].num.platforms =
dai_link[i].num_platforms = li->num[i].platforms;
@@ -958,7 +948,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
dlcs += li->num[i].platforms;
} else {
/* Doesn't have Platform */
- dai_props[i].platforms =
dai_link[i].platforms = NULL;
dai_props[i].num.platforms =
dai_link[i].num_platforms = 0;
@@ -1024,6 +1013,109 @@ int asoc_graph_is_ports0(struct device_node *np)
}
EXPORT_SYMBOL_GPL(asoc_graph_is_ports0);
+static int graph_get_dai_id(struct device_node *ep)
+{
+ struct device_node *node;
+ struct device_node *endpoint;
+ struct of_endpoint info;
+ int i, id;
+ int ret;
+
+ /* use driver specified DAI ID if exist */
+ ret = snd_soc_get_dai_id(ep);
+ if (ret != -ENOTSUPP)
+ return ret;
+
+ /* use endpoint/port reg if exist */
+ ret = of_graph_parse_endpoint(ep, &info);
+ if (ret == 0) {
+ /*
+ * Because it will count port/endpoint if it doesn't have "reg".
+ * But, we can't judge whether it has "no reg", or "reg = <0>"
+ * only of_graph_parse_endpoint().
+ * We need to check "reg" property
+ */
+ if (of_property_present(ep, "reg"))
+ return info.id;
+
+ node = of_get_parent(ep);
+ ret = of_property_present(node, "reg");
+ of_node_put(node);
+ if (ret)
+ return info.port;
+ }
+ node = of_graph_get_port_parent(ep);
+
+ /*
+ * 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++;
+ }
+
+ of_node_put(node);
+
+ if (id < 0)
+ return -ENODEV;
+
+ return id;
+}
+
+int asoc_graph_parse_dai(struct device_node *ep,
+ struct snd_soc_dai_link_component *dlc,
+ int *is_single_link)
+{
+ struct device_node *node;
+ struct of_phandle_args args = {};
+ int ret;
+
+ if (!ep)
+ return 0;
+
+ node = of_graph_get_port_parent(ep);
+
+ /* Get dai->name */
+ args.np = node;
+ args.args[0] = graph_get_dai_id(ep);
+ args.args_count = (of_graph_get_endpoint_count(node) > 1);
+
+ /*
+ * FIXME
+ *
+ * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
+ * If user unbinded CPU or Codec driver, but not for Sound Card,
+ * dlc->dai_name is keeping unbinded CPU or Codec
+ * driver's pointer.
+ *
+ * If user re-bind CPU or Codec driver again, ALSA SoC will try
+ * to rebind Card via snd_soc_try_rebind_card(), but because of
+ * above reason, it might can't bind Sound Card.
+ * Because Sound Card is pointing to released dai_name pointer.
+ *
+ * To avoid this rebind Card issue,
+ * 1) It needs to alloc memory to keep dai_name eventhough
+ * CPU or Codec driver was unbinded, or
+ * 2) user need to rebind Sound Card everytime
+ * if he unbinded CPU or Codec.
+ */
+ ret = snd_soc_get_dlc(&args, dlc);
+ if (ret < 0) {
+ of_node_put(node);
+ return ret;
+ }
+
+ if (is_single_link)
+ *is_single_link = of_graph_get_endpoint_count(node) == 1;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_graph_parse_dai);
+
/* Module information */
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");