[alsa-devel] [PATCH v2 10/13] ASoC: Support adding a DAI dynamically
mengdong.lin at linux.intel.com
mengdong.lin at linux.intel.com
Thu Nov 5 10:59:50 CET 2015
From: Mengdong Lin <mengdong.lin at linux.intel.com>
API snd_soc_add_dai() is defined to register a DAI dynamically and
create its DAI widget. This API can be used by the topology core
to add DAIs.
Signed-off-by: Mengdong Lin <mengdong.lin at linux.intel.com>
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 13e1409..a6e6a1b 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1667,6 +1667,9 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
void snd_soc_add_dai_link(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link);
+int snd_soc_add_dai(struct snd_soc_component *component,
+ struct snd_soc_dai_driver *dai_drv);
+
#include <sound/soc-dai.h>
#ifdef CONFIG_DEBUG_FS
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 23d067ae..f4bf26c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2786,6 +2786,91 @@ err:
return ret;
}
+static struct snd_soc_dai *soc_register_dai(struct snd_soc_component *component,
+ struct snd_soc_dai_driver *dai_drv,
+ bool legacy_dai_naming)
+{
+ struct device *dev = component->dev;
+ struct snd_soc_dai *dai;
+ int ret;
+
+ dev_dbg(dev, "ASoC: dynamically register DAI %s\n", dev_name(dev));
+
+ dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
+ if (dai == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /*
+ * Back in the old days when we still had component-less DAIs,
+ * instead of having a static name, component-less DAIs would
+ * inherit the name of the parent device so it is possible to
+ * register multiple instances of the DAI. We still need to keep
+ * the same naming style even though those DAIs are not
+ * component-less anymore.
+ */
+ if (legacy_dai_naming) {
+ dai->name = fmt_single_name(dev, &dai->id);
+ } else {
+ dai->name = fmt_multiple_name(dev, dai_drv);
+ if (dai_drv->id)
+ dai->id = dai_drv->id;
+ else
+ dai->id = component->num_dai;
+ }
+ if (dai->name == NULL) {
+ kfree(dai);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ dai->component = component;
+ dai->dev = dev;
+ dai->driver = dai_drv;
+ if (!dai->driver->ops)
+ dai->driver->ops = &null_dai_ops;
+
+ list_add(&dai->list, &component->dai_list);
+ component->num_dai++;
+
+ dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
+ return dai;
+
+err:
+ kfree(dai);
+ return NULL;
+}
+
+/**
+ * snd_soc_add_dai - Add a DAI dynamically with the ASoC core
+ *
+ * @component: The component the DAIs are registered for
+ * @dai_drv: DAI driver to use for the DAI
+ */
+int snd_soc_add_dai(struct snd_soc_component *component,
+ struct snd_soc_dai_driver *dai_drv)
+{
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_component_get_dapm(component);
+ struct snd_soc_dai *dai;
+ int ret;
+
+ lockdep_assert_held(&client_mutex);
+ dai = soc_register_dai(component, dai_drv, false);
+ if (!dai)
+ return -ENOMEM;
+
+ ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
+ if (ret != 0) {
+ dev_err(component->dev,
+ "Failed to create DAI widgets %d\n", ret);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_add_dai);
+
static void snd_soc_component_seq_notifier(struct snd_soc_dapm_context *dapm,
enum snd_soc_dapm_type type, int subseq)
{
--
1.9.1
More information about the Alsa-devel
mailing list