alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/13] ASoC: Componentization: Unified probe/remove path
@ 2014-08-19 13:51 Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 01/13] ASoC: Move debugfs registration to the component level Lars-Peter Clausen
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

This patch-set starts with consolidating the probe and remove paths of
snd_soc_codec and snd_soc_platform drivers. Once that has been done it uses the
new generic paths to also add probe and remove support to snd_soc_component
drivers. With that in place the AUX dev handling is then moved to the component
layer as there is no longer any snd_soc_codec specifics required to handle
them. The later patches in the series deal with cleaning things up and
consolidating a few code paths between CPU and CODEC DAI handling.

After this patch-set the core of the ASoC core is now fully componentized and
doesn't care anymore (except for one small hack which is documented in the
commit) about whether something is a snd_soc_codec, snd_soc_platform or
snd_soc_component. This does unfortunately not mean that componentization is
done yet. There are still a few things left to do. This includes bringing more
things to the component level for example clock and PCM handling. There is also
still the issue that we handle CPU DAIs and CODEC DAIs differently. For CODEC
DAIs the capture stream is output and the playback stream is input while it is
the other way around for CPU DAIs. Also we expect them to handle the
SND_SOC_DAIFMT_CBx_CFx settings depending on whether they are a CPU or CODEC
DAI. So we need a way to distinguish between the two.

At this point it is already possible though to convert simple snd_soc_codec
drivers that don't need any of this (e.g. some of the external amplifier
drivers) to snd_soc_components. Since the series adds a centralized path for
probing and removing it also paves the way towards easier integration of the
drivers/base/component.c framework, which in turn will allow some cleanups and
to fix some long standing bugs in the way hot-unplug is handled (or rather not
handled).

- Lars

Lars-Peter Clausen (13):
  ASoC: Move debugfs registration to the component level
  ASoC: Consolidate platform and CODEC probe/remove
  ASoC: Make rtd->codec optional
  ASoC: Add component level probe/remove support
  ASoC: Move AUX dev support to the component level
  ASoC: Pass component instead of DAPM context to AUX dev init callback
  ASoC: Move component->probed check into
    soc_{remove,probe}_component()
  ASoC: Cleanup DAI module reference counting
  ASoC: Consolidate CPU and CODEC DAI removal
  ASoC: Consolidate CPU and CODEC DAI look-up
  ASoC: Automatically initialize regmap for all components
  ASoC: Remove support for legacy snd_soc_platform IO
  ASoC: Replace list_empty(&card->codec_dev_list) with
    !card->instantiated

 include/sound/soc.h                   |  67 ++--
 sound/soc/samsung/speyside.c          |   6 +-
 sound/soc/soc-core.c                  | 667 ++++++++++++++++------------------
 sound/soc/soc-generic-dmaengine-pcm.c |   4 +-
 sound/soc/soc-io.c                    |  28 --
 5 files changed, 357 insertions(+), 415 deletions(-)

-- 
1.8.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/13] ASoC: Move debugfs registration to the component level
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 02/13] ASoC: Consolidate platform and CODEC probe/remove Lars-Peter Clausen
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

The debugfs registration is mostly identical between platforms and CODECs. This
patches consolidates the two implementations at the component level.

Unfortunately there are still a couple of CODEC specific debugfs files that are
related to legacy ASoC IO that need to be registered. For this a new callback is
added to the component struct that will be initialized when a CODEC is
registered and will be used to register the CODEC specific files. Once there are
no drivers left using legacy IO this can be removed again.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h  |  20 ++++++---
 sound/soc/soc-core.c | 122 ++++++++++++++++++++++-----------------------------
 2 files changed, 67 insertions(+), 75 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6f6064a..4506de8 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -728,9 +728,24 @@ struct snd_soc_component {
 
 	struct mutex io_mutex;
 
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_root;
+#endif
+
+	/*
+	* DO NOT use any of the fields below in drivers, they are temporary and
+	* are going to be removed again soon. If you use them in driver code the
+	* driver will be marked as BROKEN when these fields are removed.
+	*/
+
 	/* Don't use these, use snd_soc_component_get_dapm() */
 	struct snd_soc_dapm_context dapm;
 	struct snd_soc_dapm_context *dapm_ptr;
+
+#ifdef CONFIG_DEBUG_FS
+	void (*init_debugfs)(struct snd_soc_component *component);
+	const char *debugfs_prefix;
+#endif
 };
 
 /* SoC Audio Codec device */
@@ -766,7 +781,6 @@ struct snd_soc_codec {
 	struct snd_soc_dapm_context dapm;
 
 #ifdef CONFIG_DEBUG_FS
-	struct dentry *debugfs_codec_root;
 	struct dentry *debugfs_reg;
 #endif
 };
@@ -879,10 +893,6 @@ struct snd_soc_platform {
 	struct list_head list;
 
 	struct snd_soc_component component;
-
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *debugfs_platform_root;
-#endif
 };
 
 struct snd_soc_dai_link {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 889f4e3..8d1e319 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -270,79 +270,56 @@ static const struct file_operations codec_reg_fops = {
 	.llseek = default_llseek,
 };
 
-static struct dentry *soc_debugfs_create_dir(struct dentry *parent,
-	const char *fmt, ...)
+static void soc_init_component_debugfs(struct snd_soc_component *component)
 {
-	struct dentry *de;
-	va_list ap;
-	char *s;
+	if (component->debugfs_prefix) {
+		char *name;
 
-	va_start(ap, fmt);
-	s = kvasprintf(GFP_KERNEL, fmt, ap);
-	va_end(ap);
+		name = kasprintf(GFP_KERNEL, "%s:%s",
+			component->debugfs_prefix, component->name);
+		if (name) {
+			component->debugfs_root = debugfs_create_dir(name,
+				component->card->debugfs_card_root);
+			kfree(name);
+		}
+	} else {
+		component->debugfs_root = debugfs_create_dir(component->name,
+				component->card->debugfs_card_root);
+	}
 
-	if (!s)
-		return NULL;
+	if (!component->debugfs_root) {
+		dev_warn(component->dev,
+			"ASoC: Failed to create component debugfs directory\n");
+		return;
+	}
 
-	de = debugfs_create_dir(s, parent);
-	kfree(s);
+	snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
+		component->debugfs_root);
 
-	return de;
+	if (component->init_debugfs)
+		component->init_debugfs(component);
 }
 
-static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
+static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
 {
-	struct dentry *debugfs_card_root = codec->component.card->debugfs_card_root;
+	debugfs_remove_recursive(component->debugfs_root);
+}
 
-	codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root,
-						"codec:%s",
-						codec->component.name);
-	if (!codec->debugfs_codec_root) {
-		dev_warn(codec->dev,
-			"ASoC: Failed to create codec debugfs directory\n");
-		return;
-	}
+static void soc_init_codec_debugfs(struct snd_soc_component *component)
+{
+	struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-	debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root,
+	debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root,
 			    &codec->cache_sync);
-	debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
+	debugfs_create_bool("cache_only", 0444, codec->component.debugfs_root,
 			    &codec->cache_only);
 
 	codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
-						 codec->debugfs_codec_root,
+						 codec->component.debugfs_root,
 						 codec, &codec_reg_fops);
 	if (!codec->debugfs_reg)
 		dev_warn(codec->dev,
 			"ASoC: Failed to create codec register debugfs file\n");
-
-	snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
-}
-
-static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
-{
-	debugfs_remove_recursive(codec->debugfs_codec_root);
-}
-
-static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
-{
-	struct dentry *debugfs_card_root = platform->component.card->debugfs_card_root;
-
-	platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root,
-						"platform:%s",
-						platform->component.name);
-	if (!platform->debugfs_platform_root) {
-		dev_warn(platform->dev,
-			"ASoC: Failed to create platform debugfs directory\n");
-		return;
-	}
-
-	snd_soc_dapm_debugfs_init(&platform->component.dapm,
-		platform->debugfs_platform_root);
-}
-
-static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
-{
-	debugfs_remove_recursive(platform->debugfs_platform_root);
 }
 
 static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
@@ -474,19 +451,15 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
 
 #else
 
-static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
-{
-}
+#define soc_init_codec_debugfs NULL
 
-static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
+static inline void soc_init_component_debugfs(
+	struct snd_soc_component *component)
 {
 }
 
-static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform)
-{
-}
-
-static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
+static inline void soc_cleanup_component_debugfs(
+	struct snd_soc_component *component)
 {
 }
 
@@ -1026,7 +999,7 @@ static int soc_remove_platform(struct snd_soc_platform *platform)
 	/* Make sure all DAPM widgets are freed */
 	snd_soc_dapm_free(&platform->component.dapm);
 
-	soc_cleanup_platform_debugfs(platform);
+	soc_cleanup_component_debugfs(&platform->component);
 	platform->probed = 0;
 	module_put(platform->dev->driver->owner);
 
@@ -1046,7 +1019,7 @@ static void soc_remove_codec(struct snd_soc_codec *codec)
 	/* Make sure all DAPM widgets are freed */
 	snd_soc_dapm_free(&codec->dapm);
 
-	soc_cleanup_codec_debugfs(codec);
+	soc_cleanup_component_debugfs(&codec->component);
 	codec->probed = 0;
 	list_del(&codec->card_list);
 	module_put(codec->dev->driver->owner);
@@ -1187,7 +1160,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
 	if (!try_module_get(codec->dev->driver->owner))
 		return -ENODEV;
 
-	soc_init_codec_debugfs(codec);
+	soc_init_component_debugfs(&codec->component);
 
 	if (driver->dapm_widgets) {
 		ret = snd_soc_dapm_new_controls(&codec->dapm,
@@ -1242,7 +1215,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
 	return 0;
 
 err_probe:
-	soc_cleanup_codec_debugfs(codec);
+	soc_cleanup_component_debugfs(&codec->component);
 	module_put(codec->dev->driver->owner);
 
 	return ret;
@@ -1262,7 +1235,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
 	if (!try_module_get(platform->dev->driver->owner))
 		return -ENODEV;
 
-	soc_init_platform_debugfs(platform);
+	soc_init_component_debugfs(&platform->component);
 
 	if (driver->dapm_widgets)
 		snd_soc_dapm_new_controls(&platform->component.dapm,
@@ -1302,7 +1275,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
 	return 0;
 
 err_probe:
-	soc_cleanup_platform_debugfs(platform);
+	soc_cleanup_component_debugfs(&platform->component);
 	module_put(platform->dev->driver->owner);
 
 	return ret;
@@ -4266,6 +4239,10 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 	if (platform_drv->read)
 		platform->component.read = snd_soc_platform_drv_read;
 
+#ifdef CONFIG_DEBUG_FS
+	platform->component.debugfs_prefix = "platform";
+#endif
+
 	mutex_lock(&client_mutex);
 	snd_soc_component_add_unlocked(&platform->component);
 	list_add(&platform->list, &platform_list);
@@ -4455,6 +4432,11 @@ int snd_soc_register_codec(struct device *dev,
 	codec->component.val_bytes = codec_drv->reg_word_size;
 	mutex_init(&codec->mutex);
 
+#ifdef CONFIG_DEBUG_FS
+	codec->component.init_debugfs = soc_init_codec_debugfs;
+	codec->component.debugfs_prefix = "codec";
+#endif
+
 	if (!codec->component.write) {
 		if (codec_drv->get_regmap)
 			regmap = codec_drv->get_regmap(dev);
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/13] ASoC: Consolidate platform and CODEC probe/remove
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 01/13] ASoC: Move debugfs registration to the component level Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 03/13] ASoC: Make rtd->codec optional Lars-Peter Clausen
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

The platform and CODEC probe and remove code is now largely identical. This
patch consolidates it at the component level.

The resulting code is slightly larger due to all the boiler plate code setting
up the indirection for the table based control and DAPM registration.  Once all
drivers have been update to no longer use the snd_soc_codec_driver and
snd_soc_platform_driver specific fields for this the indirection can be removed
again.

This patch contains two noteworthy hacks that are only meant to be temporary to
be able to update drivers and the core in separate incremental patches.

The first hack is related to that some DPCM platforms expect that the DAPM
widgets for the DAIs of a snd_soc_component are created in the DAPM context of
the snd_soc_platform that has the same parent device. For handling this the
steal_sibling_dai_widgets attribute is introduced. It gets set for
snd_soc_platforms that register DAPM elements. When creating the DAI widgets for
a component this flag is checked and if it is found on one of the siblings the
component will not create any DAI widgets in its own DAPM context. If the
attribute is set on a platform it will look for siblings components and create
DAI widgets for them in its own context. The fix for this will be to update
the offending drivers to only register a single component rather than two.

The second hack deals with the fact that the ASoC card suspend and resume code
still needs a list of CODECs that have been registered for the card. To handle
this the generic probe and remove path have a check to see if the component is
CODEC and if yes add/remove it to the card's CODEC list. While it is possible to
clean up the suspend/resume code to not need the CODEC list anymore this is a
bit of a chicken and egg problem since it will become easier to clean up the
suspend/resume code once there is a unified component layer.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h                   |  27 ++-
 sound/soc/soc-core.c                  | 335 ++++++++++++++++++----------------
 sound/soc/soc-generic-dmaengine-pcm.c |   4 +-
 3 files changed, 194 insertions(+), 172 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 4506de8..0e7e761 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -697,6 +697,10 @@ struct snd_soc_component_driver {
 	void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
 		int subseq);
 	int (*stream_event)(struct snd_soc_component *, int event);
+
+	/* probe ordering - for components with runtime dependencies */
+	int probe_order;
+	int remove_order;
 };
 
 struct snd_soc_component {
@@ -710,6 +714,7 @@ struct snd_soc_component {
 
 	unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
 	unsigned int registered_as_component:1;
+	unsigned int probed:1;
 
 	struct list_head list;
 
@@ -742,6 +747,18 @@ struct snd_soc_component {
 	struct snd_soc_dapm_context dapm;
 	struct snd_soc_dapm_context *dapm_ptr;
 
+	const struct snd_kcontrol_new *controls;
+	unsigned int num_controls;
+	const struct snd_soc_dapm_widget *dapm_widgets;
+	unsigned int num_dapm_widgets;
+	const struct snd_soc_dapm_route *dapm_routes;
+	unsigned int num_dapm_routes;
+	bool steal_sibling_dai_widgets;
+	struct snd_soc_codec *codec;
+
+	int (*probe)(struct snd_soc_component *);
+	void (*remove)(struct snd_soc_component *);
+
 #ifdef CONFIG_DEBUG_FS
 	void (*init_debugfs)(struct snd_soc_component *component);
 	const char *debugfs_prefix;
@@ -761,7 +778,6 @@ struct snd_soc_codec {
 	struct snd_ac97 *ac97;  /* for ad-hoc ac97 devices */
 	unsigned int cache_bypass:1; /* Suppress access to the cache */
 	unsigned int suspended:1; /* Codec is in suspend PM state */
-	unsigned int probed:1; /* Codec has been probed */
 	unsigned int ac97_registered:1; /* Codec has been AC97 registered */
 	unsigned int ac97_created:1; /* Codec has been created by SoC */
 	unsigned int cache_init:1; /* codec cache has been initialized */
@@ -827,10 +843,6 @@ struct snd_soc_codec_driver {
 			     enum snd_soc_dapm_type, int);
 
 	bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
-
-	/* probe ordering - for components with runtime dependencies */
-	int probe_order;
-	int remove_order;
 };
 
 /* SoC platform interface */
@@ -867,10 +879,6 @@ struct snd_soc_platform_driver {
 	/* platform stream compress ops */
 	const struct snd_compr_ops *compr_ops;
 
-	/* probe ordering - for components with runtime dependencies */
-	int probe_order;
-	int remove_order;
-
 	/* platform IO - used for platform DAPM */
 	unsigned int (*read)(struct snd_soc_platform *, unsigned int);
 	int (*write)(struct snd_soc_platform *, unsigned int, unsigned int);
@@ -888,7 +896,6 @@ struct snd_soc_platform {
 	const struct snd_soc_platform_driver *driver;
 
 	unsigned int suspended:1; /* platform is suspended */
-	unsigned int probed:1;
 
 	struct list_head list;
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 8d1e319..abc1a05 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -985,44 +985,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 	return 0;
 }
 
-static int soc_remove_platform(struct snd_soc_platform *platform)
+static void soc_remove_component(struct snd_soc_component *component)
 {
-	int ret;
-
-	if (platform->driver->remove) {
-		ret = platform->driver->remove(platform);
-		if (ret < 0)
-			dev_err(platform->dev, "ASoC: failed to remove %d\n",
-				ret);
-	}
-
-	/* Make sure all DAPM widgets are freed */
-	snd_soc_dapm_free(&platform->component.dapm);
-
-	soc_cleanup_component_debugfs(&platform->component);
-	platform->probed = 0;
-	module_put(platform->dev->driver->owner);
-
-	return 0;
-}
-
-static void soc_remove_codec(struct snd_soc_codec *codec)
-{
-	int err;
+	/* This is a HACK and will be removed soon */
+	if (component->codec)
+		list_del(&component->codec->card_list);
 
-	if (codec->driver->remove) {
-		err = codec->driver->remove(codec);
-		if (err < 0)
-			dev_err(codec->dev, "ASoC: failed to remove %d\n", err);
-	}
+	if (component->remove)
+		component->remove(component);
 
-	/* Make sure all DAPM widgets are freed */
-	snd_soc_dapm_free(&codec->dapm);
+	snd_soc_dapm_free(snd_soc_component_get_dapm(component));
 
-	soc_cleanup_component_debugfs(&codec->component);
-	codec->probed = 0;
-	list_del(&codec->card_list);
-	module_put(codec->dev->driver->owner);
+	soc_cleanup_component_debugfs(component);
+	component->probed = 0;
+	module_put(component->dev->driver->owner);
 }
 
 static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order)
@@ -1086,25 +1062,24 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
 	int i;
 
 	/* remove the platform */
-	if (platform && platform->probed &&
-	    platform->driver->remove_order == order) {
-		soc_remove_platform(platform);
-	}
+	if (platform && platform->component.probed &&
+	    platform->component.driver->remove_order == order)
+		soc_remove_component(&platform->component);
 
 	/* remove the CODEC-side CODEC */
 	for (i = 0; i < rtd->num_codecs; i++) {
 		codec = rtd->codec_dais[i]->codec;
-		if (codec && codec->probed &&
-		    codec->driver->remove_order == order)
-			soc_remove_codec(codec);
+		if (codec && codec->component.probed &&
+		    codec->component.driver->remove_order == order)
+			soc_remove_component(&codec->component);
 	}
 
 	/* remove any CPU-side CODEC */
 	if (cpu_dai) {
 		codec = cpu_dai->codec;
-		if (codec && codec->probed &&
-		    codec->driver->remove_order == order)
-			soc_remove_codec(codec);
+		if (codec && codec->component.probed &&
+		    codec->component.driver->remove_order == order)
+			soc_remove_component(&codec->component);
 	}
 }
 
@@ -1146,137 +1121,108 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
 	}
 }
 
-static int soc_probe_codec(struct snd_soc_card *card,
-			   struct snd_soc_codec *codec)
+static int soc_probe_component(struct snd_soc_card *card,
+	struct snd_soc_component *component)
 {
-	int ret = 0;
-	const struct snd_soc_codec_driver *driver = codec->driver;
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct snd_soc_component *dai_component, *component2;
 	struct snd_soc_dai *dai;
+	int ret;
 
-	codec->component.card = card;
-	codec->dapm.card = card;
-	soc_set_name_prefix(card, &codec->component);
+	component->card = card;
+	dapm->card = card;
+	soc_set_name_prefix(card, component);
 
-	if (!try_module_get(codec->dev->driver->owner))
+	if (!try_module_get(component->dev->driver->owner))
 		return -ENODEV;
 
-	soc_init_component_debugfs(&codec->component);
+	soc_init_component_debugfs(component);
 
-	if (driver->dapm_widgets) {
-		ret = snd_soc_dapm_new_controls(&codec->dapm,
-						driver->dapm_widgets,
-					 	driver->num_dapm_widgets);
+	if (component->dapm_widgets) {
+		ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets,
+			component->num_dapm_widgets);
 
 		if (ret != 0) {
-			dev_err(codec->dev,
+			dev_err(component->dev,
 				"Failed to create new controls %d\n", ret);
 			goto err_probe;
 		}
 	}
 
-	/* Create DAPM widgets for each DAI stream */
-	list_for_each_entry(dai, &codec->component.dai_list, list) {
-		ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
+	/*
+	 * This is rather ugly, but certain platforms expect that the DAPM
+	 * widgets for the DAIs for components with the same parent device are
+	 * created in the platforms DAPM context. Until that is fixed we need to
+	 * keep this.
+	 */
+	if (component->steal_sibling_dai_widgets) {
+		dai_component = NULL;
+		list_for_each_entry(component2, &component_list, list) {
+			if (component == component2)
+				continue;
 
-		if (ret != 0) {
-			dev_err(codec->dev,
-				"Failed to create DAI widgets %d\n", ret);
-			goto err_probe;
+			if (component2->dev == component->dev &&
+			    !list_empty(&component2->dai_list)) {
+				dai_component = component2;
+				break;
+			}
 		}
-	}
-
-	codec->dapm.idle_bias_off = driver->idle_bias_off;
-
-	if (driver->probe) {
-		ret = driver->probe(codec);
-		if (ret < 0) {
-			dev_err(codec->dev,
-				"ASoC: failed to probe CODEC %d\n", ret);
-			goto err_probe;
+	} else {
+		dai_component = component;
+		list_for_each_entry(component2, &component_list, list) {
+			if (component2->dev == component->dev &&
+			    component2->steal_sibling_dai_widgets) {
+				dai_component = NULL;
+				break;
+			}
 		}
-		WARN(codec->dapm.idle_bias_off &&
-			codec->dapm.bias_level != SND_SOC_BIAS_OFF,
-			"codec %s can not start from non-off bias with idle_bias_off==1\n",
-			codec->component.name);
 	}
 
-	if (driver->controls)
-		snd_soc_add_codec_controls(codec, driver->controls,
-				     driver->num_controls);
-	if (driver->dapm_routes)
-		snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
-					driver->num_dapm_routes);
-
-	/* mark codec as probed and add to card codec list */
-	codec->probed = 1;
-	list_add(&codec->card_list, &card->codec_dev_list);
-	list_add(&codec->dapm.list, &card->dapm_list);
-
-	return 0;
-
-err_probe:
-	soc_cleanup_component_debugfs(&codec->component);
-	module_put(codec->dev->driver->owner);
-
-	return ret;
-}
-
-static int soc_probe_platform(struct snd_soc_card *card,
-			   struct snd_soc_platform *platform)
-{
-	int ret = 0;
-	const struct snd_soc_platform_driver *driver = platform->driver;
-	struct snd_soc_component *component;
-	struct snd_soc_dai *dai;
-
-	platform->component.card = card;
-	platform->component.dapm.card = card;
-
-	if (!try_module_get(platform->dev->driver->owner))
-		return -ENODEV;
-
-	soc_init_component_debugfs(&platform->component);
-
-	if (driver->dapm_widgets)
-		snd_soc_dapm_new_controls(&platform->component.dapm,
-			driver->dapm_widgets, driver->num_dapm_widgets);
-
-	/* Create DAPM widgets for each DAI stream */
-	list_for_each_entry(component, &component_list, list) {
-		if (component->dev != platform->dev)
-			continue;
-		list_for_each_entry(dai, &component->dai_list, list)
-			snd_soc_dapm_new_dai_widgets(&platform->component.dapm,
-				dai);
+	if (dai_component) {
+		list_for_each_entry(dai, &dai_component->dai_list, list) {
+			snd_soc_dapm_new_dai_widgets(dapm, dai);
+			if (ret != 0) {
+				dev_err(component->dev,
+					"Failed to create DAI widgets %d\n",
+					ret);
+				goto err_probe;
+			}
+		}
 	}
 
-	platform->component.dapm.idle_bias_off = 1;
-
-	if (driver->probe) {
-		ret = driver->probe(platform);
+	if (component->probe) {
+		ret = component->probe(component);
 		if (ret < 0) {
-			dev_err(platform->dev,
-				"ASoC: failed to probe platform %d\n", ret);
+			dev_err(component->dev,
+				"ASoC: failed to probe component %d\n", ret);
 			goto err_probe;
 		}
+
+		WARN(dapm->idle_bias_off &&
+			dapm->bias_level != SND_SOC_BIAS_OFF,
+			"codec %s can not start from non-off bias with idle_bias_off==1\n",
+			component->name);
 	}
 
-	if (driver->controls)
-		snd_soc_add_platform_controls(platform, driver->controls,
-				     driver->num_controls);
-	if (driver->dapm_routes)
-		snd_soc_dapm_add_routes(&platform->component.dapm,
-			driver->dapm_routes, driver->num_dapm_routes);
+	if (component->controls)
+		snd_soc_add_component_controls(component, component->controls,
+				     component->num_controls);
+	if (component->dapm_routes)
+		snd_soc_dapm_add_routes(dapm, component->dapm_routes,
+					component->num_dapm_routes);
 
-	/* mark platform as probed and add to card platform list */
-	platform->probed = 1;
-	list_add(&platform->component.dapm.list, &card->dapm_list);
+	component->probed = 1;
+	list_add(&dapm->list, &card->dapm_list);
+
+	/* This is a HACK and will be removed soon */
+	if (component->codec)
+		list_add(&component->codec->card_list, &card->codec_dev_list);
 
 	return 0;
 
 err_probe:
-	soc_cleanup_component_debugfs(&platform->component);
-	module_put(platform->dev->driver->owner);
+	soc_cleanup_component_debugfs(component);
+	module_put(component->dev->driver->owner);
 
 	return ret;
 }
@@ -1334,33 +1280,36 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
 				     int order)
 {
 	struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_component *component;
 	int i, ret;
 
 	/* probe the CPU-side component, if it is a CODEC */
-	if (cpu_dai->codec &&
-	    !cpu_dai->codec->probed &&
-	    cpu_dai->codec->driver->probe_order == order) {
-		ret = soc_probe_codec(card, cpu_dai->codec);
-		if (ret < 0)
-			return ret;
+	if (rtd->cpu_dai->codec) {
+		component = &rtd->cpu_dai->codec->component;
+		if (!component->probed &&
+		    component->driver->probe_order == order) {
+			ret = soc_probe_component(card, component);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
 	/* probe the CODEC-side components */
 	for (i = 0; i < rtd->num_codecs; i++) {
-		if (!rtd->codec_dais[i]->codec->probed &&
-		    rtd->codec_dais[i]->codec->driver->probe_order == order) {
-			ret = soc_probe_codec(card, rtd->codec_dais[i]->codec);
+		component = &rtd->codec_dais[i]->codec->component;
+		if (!component->probed &&
+		    component->driver->probe_order == order) {
+			ret = soc_probe_component(card, component);
 			if (ret < 0)
 				return ret;
 		}
 	}
 
 	/* probe the platform */
-	if (!platform->probed &&
-	    platform->driver->probe_order == order) {
-		ret = soc_probe_platform(card, platform);
+	if (!platform->component.probed &&
+	    platform->component.driver->probe_order == order) {
+		ret = soc_probe_component(card, &platform->component);
 		if (ret < 0)
 			return ret;
 	}
@@ -1647,12 +1596,12 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
 	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
 	int ret;
 
-	if (rtd->codec->probed) {
+	if (rtd->codec->component.probed) {
 		dev_err(rtd->codec->dev, "ASoC: codec already probed\n");
 		return -EBUSY;
 	}
 
-	ret = soc_probe_codec(card, rtd->codec);
+	ret = soc_probe_component(card, &rtd->codec->component);
 	if (ret < 0)
 		return ret;
 
@@ -1681,8 +1630,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
 		rtd->dev_registered = 0;
 	}
 
-	if (codec && codec->probed)
-		soc_remove_codec(codec);
+	if (codec && codec->component.probed)
+		soc_remove_component(&codec->component);
 }
 
 static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -4198,6 +4147,20 @@ found:
 }
 EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
 
+static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
+{
+	struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+	return platform->driver->probe(platform);
+}
+
+static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
+{
+	struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+	platform->driver->remove(platform);
+}
+
 static int snd_soc_platform_drv_write(struct snd_soc_component *component,
 	unsigned int reg, unsigned int val)
 {
@@ -4234,6 +4197,24 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 
 	platform->dev = dev;
 	platform->driver = platform_drv;
+	if (platform_drv->controls) {
+		platform->component.controls = platform_drv->controls;
+		platform->component.num_controls = platform_drv->num_controls;
+	}
+	if (platform_drv->dapm_widgets) {
+		platform->component.dapm_widgets = platform_drv->dapm_widgets;
+		platform->component.num_dapm_widgets = platform_drv->num_dapm_widgets;
+		platform->component.steal_sibling_dai_widgets = true;
+	}
+	if (platform_drv->dapm_routes) {
+		platform->component.dapm_routes = platform_drv->dapm_routes;
+		platform->component.num_dapm_routes = platform_drv->num_dapm_routes;
+	}
+
+	if (platform_drv->probe)
+		platform->component.probe = snd_soc_platform_drv_probe;
+	if (platform_drv->remove)
+		platform->component.remove = snd_soc_platform_drv_remove;
 	if (platform_drv->write)
 		platform->component.write = snd_soc_platform_drv_write;
 	if (platform_drv->read)
@@ -4363,6 +4344,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
 			stream->formats |= codec_format_map[i];
 }
 
+static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
+{
+	struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+
+	return codec->driver->probe(codec);
+}
+
+static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
+{
+	struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+
+	codec->driver->remove(codec);
+}
+
 static int snd_soc_codec_drv_write(struct snd_soc_component *component,
 	unsigned int reg, unsigned int val)
 {
@@ -4411,12 +4406,30 @@ int snd_soc_register_codec(struct device *dev,
 		return -ENOMEM;
 
 	codec->component.dapm_ptr = &codec->dapm;
+	codec->component.codec = codec;
 
 	ret = snd_soc_component_initialize(&codec->component,
 			&codec_drv->component_driver, dev);
 	if (ret)
 		goto err_free;
 
+	if (codec_drv->controls) {
+		codec->component.controls = codec_drv->controls;
+		codec->component.num_controls = codec_drv->num_controls;
+	}
+	if (codec_drv->dapm_widgets) {
+		codec->component.dapm_widgets = codec_drv->dapm_widgets;
+		codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
+	}
+	if (codec_drv->dapm_routes) {
+		codec->component.dapm_routes = codec_drv->dapm_routes;
+		codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
+	}
+
+	if (codec_drv->probe)
+		codec->component.probe = snd_soc_codec_drv_probe;
+	if (codec_drv->remove)
+		codec->component.remove = snd_soc_codec_drv_remove;
 	if (codec_drv->write)
 		codec->component.write = snd_soc_codec_drv_write;
 	if (codec_drv->read)
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 6307f85..b329b84 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -336,10 +336,12 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
 };
 
 static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
+	.component_driver = {
+		.probe_order = SND_SOC_COMP_ORDER_LATE,
+	},
 	.ops		= &dmaengine_pcm_ops,
 	.pcm_new	= dmaengine_pcm_new,
 	.pcm_free	= dmaengine_pcm_free,
-	.probe_order	= SND_SOC_COMP_ORDER_LATE,
 };
 
 static const char * const dmaengine_pcm_dma_channel_names[] = {
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 03/13] ASoC: Make rtd->codec optional
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 01/13] ASoC: Move debugfs registration to the component level Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 02/13] ASoC: Consolidate platform and CODEC probe/remove Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 04/13] ASoC: Add component level probe/remove support Lars-Peter Clausen
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

There are some place in the ASoC core that expect rtd->codec to be non NULL
(mainly CODEC specific sysfs files). With componentization going forward
rtd->codec might be NULL in some cases. This patch prepares the core for this by
not registering CODEC specific sysfs files if rtd->codec is NULL. sysfs file
removal does not need to be conditionalized as it handles the removal of
non-existing files just fine.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/soc-core.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index abc1a05..1e0d212 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1261,17 +1261,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
 	}
 	rtd->dev_registered = 1;
 
-	/* add DAPM sysfs entries for this codec */
-	ret = snd_soc_dapm_sys_add(rtd->dev);
-	if (ret < 0)
-		dev_err(rtd->dev,
-			"ASoC: failed to add codec dapm sysfs entries: %d\n", ret);
+	if (rtd->codec) {
+		/* add DAPM sysfs entries for this codec */
+		ret = snd_soc_dapm_sys_add(rtd->dev);
+		if (ret < 0)
+			dev_err(rtd->dev,
+				"ASoC: failed to add codec dapm sysfs entries: %d\n",
+				ret);
 
-	/* add codec sysfs entries */
-	ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
-	if (ret < 0)
-		dev_err(rtd->dev,
-			"ASoC: failed to add codec sysfs files: %d\n", ret);
+		/* add codec sysfs entries */
+		ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
+		if (ret < 0)
+			dev_err(rtd->dev,
+				"ASoC: failed to add codec sysfs files: %d\n",
+				ret);
+	}
 
 	return 0;
 }
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/13] ASoC: Add component level probe/remove support
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (2 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 03/13] ASoC: Make rtd->codec optional Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 05/13] ASoC: Move AUX dev support to the component level Lars-Peter Clausen
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

Now that we have a unified probe and remove path make sure to call them for all
components. soc_{probe,remove}_component are responsible for setting up the DAPM
context for the component, initialize the component prefix, manage the debugfs
entries as well as do the registration of table based controls and DAPM
elements. They also call the component drivers probe and remove callbacks. This
patch makes these things available for generic snd_soc_component drivers rather
than only having them for snd_soc_codec and snd_soc_platform drivers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h  | 11 +++++++++++
 sound/soc/soc-core.c | 42 ++++++++++++++++++++++++------------------
 2 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 0e7e761..cb5c9ca 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -690,6 +690,17 @@ struct snd_soc_compr_ops {
 struct snd_soc_component_driver {
 	const char *name;
 
+	/* Default control and setup, added after probe() is run */
+	const struct snd_kcontrol_new *controls;
+	unsigned int num_controls;
+	const struct snd_soc_dapm_widget *dapm_widgets;
+	unsigned int num_dapm_widgets;
+	const struct snd_soc_dapm_route *dapm_routes;
+	unsigned int num_dapm_routes;
+
+	int (*probe)(struct snd_soc_component *);
+	void (*remove)(struct snd_soc_component *);
+
 	/* DT */
 	int (*of_xlate_dai_name)(struct snd_soc_component *component,
 				 struct of_phandle_args *args,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1e0d212..76598cc 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1058,7 +1058,7 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
 	struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_platform *platform = rtd->platform;
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
 	int i;
 
 	/* remove the platform */
@@ -1068,18 +1068,17 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
 
 	/* remove the CODEC-side CODEC */
 	for (i = 0; i < rtd->num_codecs; i++) {
-		codec = rtd->codec_dais[i]->codec;
-		if (codec && codec->component.probed &&
-		    codec->component.driver->remove_order == order)
-			soc_remove_component(&codec->component);
+		component = rtd->codec_dais[i]->component;
+		if (component->probed &&
+		    component->driver->remove_order == order)
+			soc_remove_component(component);
 	}
 
 	/* remove any CPU-side CODEC */
 	if (cpu_dai) {
-		codec = cpu_dai->codec;
-		if (codec && codec->component.probed &&
-		    codec->component.driver->remove_order == order)
-			soc_remove_component(&codec->component);
+		if (cpu_dai->component->probed &&
+		    cpu_dai->component->driver->remove_order == order)
+			soc_remove_component(cpu_dai->component);
 	}
 }
 
@@ -1289,19 +1288,17 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
 	int i, ret;
 
 	/* probe the CPU-side component, if it is a CODEC */
-	if (rtd->cpu_dai->codec) {
-		component = &rtd->cpu_dai->codec->component;
-		if (!component->probed &&
-		    component->driver->probe_order == order) {
-			ret = soc_probe_component(card, component);
-			if (ret < 0)
-				return ret;
-		}
+	component = rtd->cpu_dai->component;
+	if (!component->probed &&
+	    component->driver->probe_order == order) {
+		ret = soc_probe_component(card, component);
+		if (ret < 0)
+			return ret;
 	}
 
 	/* probe the CODEC-side components */
 	for (i = 0; i < rtd->num_codecs; i++) {
-		component = &rtd->codec_dais[i]->codec->component;
+		component = rtd->codec_dais[i]->component;
 		if (!component->probed &&
 		    component->driver->probe_order == order) {
 			ret = soc_probe_component(card, component);
@@ -4042,6 +4039,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 
 	component->dev = dev;
 	component->driver = driver;
+	component->probe = component->driver->probe;
+	component->remove = component->driver->remove;
 
 	if (!component->dapm_ptr)
 		component->dapm_ptr = &component->dapm;
@@ -4055,6 +4054,13 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	if (driver->stream_event)
 		dapm->stream_event = snd_soc_component_stream_event;
 
+	component->controls = driver->controls;
+	component->num_controls = driver->num_controls;
+	component->dapm_widgets = driver->dapm_widgets;
+	component->num_dapm_widgets = driver->num_dapm_widgets;
+	component->dapm_routes = driver->dapm_routes;
+	component->num_dapm_routes = driver->num_dapm_routes;
+
 	INIT_LIST_HEAD(&component->dai_list);
 	mutex_init(&component->io_mutex);
 
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/13] ASoC: Move AUX dev support to the component level
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (3 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 04/13] ASoC: Add component level probe/remove support Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 06/13] ASoC: Pass component instead of DAPM context to AUX dev init callback Lars-Peter Clausen
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

This patch makes it possible to register arbitrary components as a AUX dev
for a card. This was previously only possible for CODEC components. With
componentization having made it possible for components to have DAPM contexts
and controls there is no reason why AUX devs should be artificially limited to
snd_soc_codec devices.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h  |  1 +
 sound/soc/soc-core.c | 48 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index cb5c9ca..ec35ca3 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1140,6 +1140,7 @@ struct snd_soc_pcm_runtime {
 	struct snd_soc_platform *platform;
 	struct snd_soc_dai *codec_dai;
 	struct snd_soc_dai *cpu_dai;
+	struct snd_soc_component *component; /* Only valid for AUX dev rtds */
 
 	struct snd_soc_dai **codec_dais;
 	unsigned int num_codecs;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 76598cc..1d4776e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -860,6 +860,23 @@ EXPORT_SYMBOL_GPL(snd_soc_resume);
 static const struct snd_soc_dai_ops null_dai_ops = {
 };
 
+static struct snd_soc_component *soc_find_component(
+	const struct device_node *of_node, const char *name)
+{
+	struct snd_soc_component *component;
+
+	list_for_each_entry(component, &component_list, list) {
+		if (of_node) {
+			if (component->dev->of_node == of_node)
+				return component;
+		} else if (strcmp(component->name, name) == 0) {
+			return component;
+		}
+	}
+
+	return NULL;
+}
+
 static struct snd_soc_codec *soc_find_codec(
 					const struct device_node *codec_of_node,
 					const char *codec_name)
@@ -1577,17 +1594,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
 {
 	struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
 	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
-	const char *codecname = aux_dev->codec_name;
+	const char *name = aux_dev->codec_name;
 
-	rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname);
-	if (!rtd->codec) {
+	rtd->component = soc_find_component(aux_dev->codec_of_node, name);
+	if (!rtd->component) {
 		if (aux_dev->codec_of_node)
-			codecname = of_node_full_name(aux_dev->codec_of_node);
+			name = of_node_full_name(aux_dev->codec_of_node);
 
-		dev_err(card->dev, "ASoC: %s not registered\n", codecname);
+		dev_err(card->dev, "ASoC: %s not registered\n", name);
 		return -EPROBE_DEFER;
 	}
 
+	/*
+	 * Some places still reference rtd->codec, so we have to keep that
+	 * initialized if the component is a CODEC. Once all those references
+	 * have been removed, this code can be removed as well.
+	 */
+	 rtd->codec = rtd->component->codec;
+
 	return 0;
 }
 
@@ -1597,18 +1621,18 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
 	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
 	int ret;
 
-	if (rtd->codec->component.probed) {
-		dev_err(rtd->codec->dev, "ASoC: codec already probed\n");
+	if (rtd->component->probed) {
+		dev_err(rtd->dev, "ASoC: codec already probed\n");
 		return -EBUSY;
 	}
 
-	ret = soc_probe_component(card, &rtd->codec->component);
+	ret = soc_probe_component(card, rtd->component);
 	if (ret < 0)
 		return ret;
 
 	/* do machine specific initialization */
 	if (aux_dev->init) {
-		ret = aux_dev->init(&rtd->codec->dapm);
+		ret = aux_dev->init(snd_soc_component_get_dapm(rtd->component));
 		if (ret < 0) {
 			dev_err(card->dev, "ASoC: failed to init %s: %d\n",
 				aux_dev->name, ret);
@@ -1622,7 +1646,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
 static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
 {
 	struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_component *component = rtd->component;
 
 	/* unregister the rtd device */
 	if (rtd->dev_registered) {
@@ -1631,8 +1655,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
 		rtd->dev_registered = 0;
 	}
 
-	if (codec && codec->component.probed)
-		soc_remove_component(&codec->component);
+	if (component && component->probed)
+		soc_remove_component(component);
 }
 
 static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/13] ASoC: Pass component instead of DAPM context to AUX dev init callback
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (4 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 05/13] ASoC: Move AUX dev support to the component level Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 07/13] ASoC: Move component->probed check into soc_{remove, probe}_component() Lars-Peter Clausen
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

Given that the component is the containing structure it makes more sense to pass
the component rather than the DAPM context to the AUX dev init callback.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h          | 2 +-
 sound/soc/samsung/speyside.c | 6 ++++--
 sound/soc/soc-core.c         | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index ec35ca3..f8abe22 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1022,7 +1022,7 @@ struct snd_soc_aux_dev {
 	const struct device_node *codec_of_node;
 
 	/* codec/machine specific init - e.g. add machine controls */
-	int (*init)(struct snd_soc_dapm_context *dapm);
+	int (*init)(struct snd_soc_component *component);
 };
 
 /* SoC card */
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 9902efc..a054826 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -228,10 +228,12 @@ static struct snd_soc_dai_link speyside_dai[] = {
 	},
 };
 
-static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
+static int speyside_wm9081_init(struct snd_soc_component *component)
 {
+	struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+
 	/* At any time the WM9081 is active it will have this clock */
-	return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
+	return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
 					MCLK_AUDIO_RATE, 0);
 }
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1d4776e..b84bf05 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1632,7 +1632,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
 
 	/* do machine specific initialization */
 	if (aux_dev->init) {
-		ret = aux_dev->init(snd_soc_component_get_dapm(rtd->component));
+		ret = aux_dev->init(rtd->component);
 		if (ret < 0) {
 			dev_err(card->dev, "ASoC: failed to init %s: %d\n",
 				aux_dev->name, ret);
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/13] ASoC: Move component->probed check into soc_{remove, probe}_component()
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (5 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 06/13] ASoC: Pass component instead of DAPM context to AUX dev init callback Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 08/13] ASoC: Cleanup DAI module reference counting Lars-Peter Clausen
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

Having the check in a centralized place makes the code a bit cleaner and
shorter.

Note: There is a slight semantic change in this patch. soc_probe_aux_dev() will
no longer return -EBUSY if the AUX dev has already been probed before. This is
fine though since it will simply do nothing in that case and return success.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/soc-core.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b84bf05..19b3d2c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1004,6 +1004,9 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 
 static void soc_remove_component(struct snd_soc_component *component)
 {
+	if (!component->probed)
+		return;
+
 	/* This is a HACK and will be removed soon */
 	if (component->codec)
 		list_del(&component->codec->card_list);
@@ -1079,22 +1082,19 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
 	int i;
 
 	/* remove the platform */
-	if (platform && platform->component.probed &&
-	    platform->component.driver->remove_order == order)
+	if (platform && platform->component.driver->remove_order == order)
 		soc_remove_component(&platform->component);
 
 	/* remove the CODEC-side CODEC */
 	for (i = 0; i < rtd->num_codecs; i++) {
 		component = rtd->codec_dais[i]->component;
-		if (component->probed &&
-		    component->driver->remove_order == order)
+		if (component->driver->remove_order == order)
 			soc_remove_component(component);
 	}
 
 	/* remove any CPU-side CODEC */
 	if (cpu_dai) {
-		if (cpu_dai->component->probed &&
-		    cpu_dai->component->driver->remove_order == order)
+		if (cpu_dai->component->driver->remove_order == order)
 			soc_remove_component(cpu_dai->component);
 	}
 }
@@ -1145,6 +1145,9 @@ static int soc_probe_component(struct snd_soc_card *card,
 	struct snd_soc_dai *dai;
 	int ret;
 
+	if (component->probed)
+		return 0;
+
 	component->card = card;
 	dapm->card = card;
 	soc_set_name_prefix(card, component);
@@ -1306,8 +1309,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
 
 	/* probe the CPU-side component, if it is a CODEC */
 	component = rtd->cpu_dai->component;
-	if (!component->probed &&
-	    component->driver->probe_order == order) {
+	if (component->driver->probe_order == order) {
 		ret = soc_probe_component(card, component);
 		if (ret < 0)
 			return ret;
@@ -1316,8 +1318,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
 	/* probe the CODEC-side components */
 	for (i = 0; i < rtd->num_codecs; i++) {
 		component = rtd->codec_dais[i]->component;
-		if (!component->probed &&
-		    component->driver->probe_order == order) {
+		if (component->driver->probe_order == order) {
 			ret = soc_probe_component(card, component);
 			if (ret < 0)
 				return ret;
@@ -1325,8 +1326,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
 	}
 
 	/* probe the platform */
-	if (!platform->component.probed &&
-	    platform->component.driver->probe_order == order) {
+	if (platform->component.driver->probe_order == order) {
 		ret = soc_probe_component(card, &platform->component);
 		if (ret < 0)
 			return ret;
@@ -1621,11 +1621,6 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
 	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
 	int ret;
 
-	if (rtd->component->probed) {
-		dev_err(rtd->dev, "ASoC: codec already probed\n");
-		return -EBUSY;
-	}
-
 	ret = soc_probe_component(card, rtd->component);
 	if (ret < 0)
 		return ret;
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/13] ASoC: Cleanup DAI module reference counting
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (6 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 07/13] ASoC: Move component->probed check into soc_{remove, probe}_component() Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 09/13] ASoC: Consolidate CPU and CODEC DAI removal Lars-Peter Clausen
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

Currently when a DAI has no CODEC associated to it the reference on the module
containing the DAI driver is increased when the DAI is probed and decrease when
the DAI is removed. For DAIs with CODECs the module reference count was already
incremented when the CODEC is probed. Now that all components have their module
reference count incremented when they are probed and all DAIs do have a
component it is possible to remove the module reference counting on DAI probe
and removal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/soc-core.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 19b3d2c..59020735 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1067,8 +1067,6 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
 					cpu_dai->name, err);
 		}
 		cpu_dai->probed = 0;
-		if (!cpu_dai->codec)
-			module_put(cpu_dai->dev->driver->owner);
 	}
 }
 
@@ -1422,18 +1420,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
 	/* probe the cpu_dai */
 	if (!cpu_dai->probed &&
 			cpu_dai->driver->probe_order == order) {
-		if (!cpu_dai->codec) {
-			if (!try_module_get(cpu_dai->dev->driver->owner))
-				return -ENODEV;
-		}
-
 		if (cpu_dai->driver->probe) {
 			ret = cpu_dai->driver->probe(cpu_dai);
 			if (ret < 0) {
 				dev_err(cpu_dai->dev,
 					"ASoC: failed to probe CPU DAI %s: %d\n",
 					cpu_dai->name, ret);
-				module_put(cpu_dai->dev->driver->owner);
 				return ret;
 			}
 		}
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/13] ASoC: Consolidate CPU and CODEC DAI removal
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (7 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 08/13] ASoC: Cleanup DAI module reference counting Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 10/13] ASoC: Consolidate CPU and CODEC DAI lookup Lars-Peter Clausen
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

CPU and CODEC DAI works exactly the same way. There is already a helper function
for CODEC DAI removal, use that one as well for CPU DAI removal.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/soc-core.c | 34 +++++++++++-----------------------
 1 file changed, 11 insertions(+), 23 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 59020735..04cc3d7 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1021,28 +1021,27 @@ static void soc_remove_component(struct snd_soc_component *component)
 	module_put(component->dev->driver->owner);
 }
 
-static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order)
+static void soc_remove_dai(struct snd_soc_dai *dai, int order)
 {
 	int err;
 
-	if (codec_dai && codec_dai->probed &&
-			codec_dai->driver->remove_order == order) {
-		if (codec_dai->driver->remove) {
-			err = codec_dai->driver->remove(codec_dai);
+	if (dai && dai->probed &&
+			dai->driver->remove_order == order) {
+		if (dai->driver->remove) {
+			err = dai->driver->remove(dai);
 			if (err < 0)
-				dev_err(codec_dai->dev,
+				dev_err(dai->dev,
 					"ASoC: failed to remove %s: %d\n",
-					codec_dai->name, err);
+					dai->name, err);
 		}
-		codec_dai->probed = 0;
+		dai->probed = 0;
 	}
 }
 
 static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
 {
 	struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	int i, err;
+	int i;
 
 	/* unregister the rtd device */
 	if (rtd->dev_registered) {
@@ -1054,20 +1053,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
 
 	/* remove the CODEC DAI */
 	for (i = 0; i < rtd->num_codecs; i++)
-		soc_remove_codec_dai(rtd->codec_dais[i], order);
+		soc_remove_dai(rtd->codec_dais[i], order);
 
-	/* remove the cpu_dai */
-	if (cpu_dai && cpu_dai->probed &&
-			cpu_dai->driver->remove_order == order) {
-		if (cpu_dai->driver->remove) {
-			err = cpu_dai->driver->remove(cpu_dai);
-			if (err < 0)
-				dev_err(cpu_dai->dev,
-					"ASoC: failed to remove %s: %d\n",
-					cpu_dai->name, err);
-		}
-		cpu_dai->probed = 0;
-	}
+	soc_remove_dai(rtd->cpu_dai, order);
 }
 
 static void soc_remove_link_components(struct snd_soc_card *card, int num,
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/13] ASoC: Consolidate CPU and CODEC DAI lookup
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (8 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 09/13] ASoC: Consolidate CPU and CODEC DAI removal Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 11/13] ASoC: Automatically initialize regmap for all components Lars-Peter Clausen
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

The lookup of CPU and CODEC DAIs is fairly similar and can easily be
consolidated into a single helper function.

There are two main differences in the current implementation of the CPU and
CODEC DAI lookup:
 1) CPU DAIs can be looked up by the DAI name alone and do not necessarily
   require a component name/of_node.
 2) The CODEC DAI search only considers DAIs from CODEC components.

For 1) the new helper function will allow to lookup DAIs without providing a
component name or of_node, but since snd_soc_register_card() already rejects
CODEC DAI link components without neither a of_node or a name we'll never get
into the situation where we try to lookup a CODEC DAI without a name/of_node.
For 2) the new helper function just always considers all components.
Componentization is now at a point where it is possible to register a CODEC as a
snd_soc_component rather than a snd_soc_codec, by considering DAIs from all
components it is possible to use such a CODEC in a DAI link.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/soc-core.c | 72 ++++++++++++++--------------------------------------
 1 file changed, 19 insertions(+), 53 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 04cc3d7..9d05a28 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -877,35 +877,23 @@ static struct snd_soc_component *soc_find_component(
 	return NULL;
 }
 
-static struct snd_soc_codec *soc_find_codec(
-					const struct device_node *codec_of_node,
-					const char *codec_name)
+static struct snd_soc_dai *snd_soc_find_dai(
+	const struct snd_soc_dai_link_component *dlc)
 {
-	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
+	struct snd_soc_dai *dai;
 
-	list_for_each_entry(codec, &codec_list, list) {
-		if (codec_of_node) {
-			if (codec->dev->of_node != codec_of_node)
-				continue;
-		} else {
-			if (strcmp(codec->component.name, codec_name))
+	/* Find CPU DAI from registered DAIs*/
+	list_for_each_entry(component, &component_list, list) {
+		if (dlc->of_node && component->dev->of_node != dlc->of_node)
+			continue;
+		if (dlc->name && strcmp(dev_name(component->dev), dlc->name))
+			continue;
+		list_for_each_entry(dai, &component->dai_list, list) {
+			if (dlc->dai_name && strcmp(dai->name, dlc->dai_name))
 				continue;
-		}
-
-		return codec;
-	}
-
-	return NULL;
-}
-
-static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec,
-					      const char *codec_dai_name)
-{
-	struct snd_soc_dai *codec_dai;
 
-	list_for_each_entry(codec_dai, &codec->component.dai_list, list) {
-		if (!strcmp(codec_dai->name, codec_dai_name)) {
-			return codec_dai;
+			return dai;
 		}
 	}
 
@@ -916,33 +904,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 {
 	struct snd_soc_dai_link *dai_link = &card->dai_link[num];
 	struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
-	struct snd_soc_component *component;
 	struct snd_soc_dai_link_component *codecs = dai_link->codecs;
+	struct snd_soc_dai_link_component cpu_dai_component;
 	struct snd_soc_dai **codec_dais = rtd->codec_dais;
 	struct snd_soc_platform *platform;
-	struct snd_soc_dai *cpu_dai;
 	const char *platform_name;
 	int i;
 
 	dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
 
-	/* Find CPU DAI from registered DAIs*/
-	list_for_each_entry(component, &component_list, list) {
-		if (dai_link->cpu_of_node &&
-			component->dev->of_node != dai_link->cpu_of_node)
-			continue;
-		if (dai_link->cpu_name &&
-			strcmp(dev_name(component->dev), dai_link->cpu_name))
-			continue;
-		list_for_each_entry(cpu_dai, &component->dai_list, list) {
-			if (dai_link->cpu_dai_name &&
-				strcmp(cpu_dai->name, dai_link->cpu_dai_name))
-				continue;
-
-			rtd->cpu_dai = cpu_dai;
-		}
-	}
-
+	cpu_dai_component.name = dai_link->cpu_name;
+	cpu_dai_component.of_node = dai_link->cpu_of_node;
+	cpu_dai_component.dai_name = dai_link->cpu_dai_name;
+	rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
 	if (!rtd->cpu_dai) {
 		dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
 			dai_link->cpu_dai_name);
@@ -953,15 +927,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 
 	/* Find CODEC from registered CODECs */
 	for (i = 0; i < rtd->num_codecs; i++) {
-		struct snd_soc_codec *codec;
-		codec = soc_find_codec(codecs[i].of_node, codecs[i].name);
-		if (!codec) {
-			dev_err(card->dev, "ASoC: CODEC %s not registered\n",
-				codecs[i].name);
-			return -EPROBE_DEFER;
-		}
-
-		codec_dais[i] = soc_find_codec_dai(codec, codecs[i].dai_name);
+		codec_dais[i] = snd_soc_find_dai(&codecs[i]);
 		if (!codec_dais[i]) {
 			dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
 				codecs[i].dai_name);
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 11/13] ASoC: Automatically initialize regmap for all components
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (9 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 10/13] ASoC: Consolidate CPU and CODEC DAI lookup Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 12/13] ASoC: Remove support for legacy snd_soc_platform IO Lars-Peter Clausen
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

So far regmap is only automatically initialized for CODECs. Now that we have the
infrastructure in place to let components have DAPM widgets and controls that
want to use the generic regmap based IO also make sure to automatically
initialize regmap for all components.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h  |  3 ---
 sound/soc/soc-core.c | 35 +++++++++++++++++------------------
 sound/soc/soc-io.c   | 28 ----------------------------
 3 files changed, 17 insertions(+), 49 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index f8abe22..d4ba8048 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1289,9 +1289,6 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
 int snd_soc_component_test_bits(struct snd_soc_component *component,
 	unsigned int reg, unsigned int mask, unsigned int value);
 
-int snd_soc_component_init_io(struct snd_soc_component *component,
-	struct regmap *regmap);
-
 /* device driver data */
 
 static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 9d05a28..5c78098 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4032,8 +4032,23 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	return 0;
 }
 
+static void snd_soc_component_init_regmap(struct snd_soc_component *component)
+{
+	if (!component->regmap)
+		component->regmap = dev_get_regmap(component->dev, NULL);
+	if (component->regmap) {
+		int val_bytes = regmap_get_val_bytes(component->regmap);
+		/* Errors are legitimate for non-integer byte multiples */
+		if (val_bytes > 0)
+			component->val_bytes = val_bytes;
+	}
+}
+
 static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
 {
+	if (!component->write && !component->read)
+		snd_soc_component_init_regmap(component);
+
 	list_add(&component->list, &component_list);
 }
 
@@ -4371,7 +4386,6 @@ int snd_soc_register_codec(struct device *dev,
 {
 	struct snd_soc_codec *codec;
 	struct snd_soc_dai *dai;
-	struct regmap *regmap;
 	int ret, i;
 
 	dev_dbg(dev, "codec register %s\n", dev_name(dev));
@@ -4425,23 +4439,8 @@ int snd_soc_register_codec(struct device *dev,
 	codec->component.debugfs_prefix = "codec";
 #endif
 
-	if (!codec->component.write) {
-		if (codec_drv->get_regmap)
-			regmap = codec_drv->get_regmap(dev);
-		else
-			regmap = dev_get_regmap(dev, NULL);
-
-		if (regmap) {
-			ret = snd_soc_component_init_io(&codec->component,
-				regmap);
-			if (ret) {
-				dev_err(codec->dev,
-						"Failed to set cache I/O:%d\n",
-						ret);
-				goto err_cleanup;
-			}
-		}
-	}
+	if (codec_drv->get_regmap)
+		codec->component.regmap = codec_drv->get_regmap(dev);
 
 	for (i = 0; i < num_dai; i++) {
 		fixup_codec_formats(&dai_drv[i].playback);
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 7767fbd..9b39390 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -271,31 +271,3 @@ int snd_soc_platform_write(struct snd_soc_platform *platform,
 	return snd_soc_component_write(&platform->component, reg, val);
 }
 EXPORT_SYMBOL_GPL(snd_soc_platform_write);
-
-/**
- * snd_soc_component_init_io() - Initialize regmap IO
- *
- * @component: component to initialize
- * @regmap: regmap instance to use for IO operations
- *
- * Return: 0 on success, a negative error code otherwise
- */
-int snd_soc_component_init_io(struct snd_soc_component *component,
-	struct regmap *regmap)
-{
-	int ret;
-
-	if (!regmap)
-		return -EINVAL;
-
-	ret = regmap_get_val_bytes(regmap);
-	/* Errors are legitimate for non-integer byte
-	 * multiples */
-	if (ret > 0)
-		component->val_bytes = ret;
-
-	component->regmap = regmap;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_component_init_io);
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 12/13] ASoC: Remove support for legacy snd_soc_platform IO
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (10 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 11/13] ASoC: Automatically initialize regmap for all components Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 13:51 ` [PATCH 13/13] ASoC: Replace list_empty(&card->codec_dev_list) with !card->instantiated Lars-Peter Clausen
  2014-08-19 16:01 ` [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Mark Brown
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

There were never any actual users of this in upstream and by we have with
regmap a replacement in place, which should be used by new drivers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h  |  3 ---
 sound/soc/soc-core.c | 22 ----------------------
 2 files changed, 25 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index d4ba8048..e43fbb6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -890,9 +890,6 @@ struct snd_soc_platform_driver {
 	/* platform stream compress ops */
 	const struct snd_compr_ops *compr_ops;
 
-	/* platform IO - used for platform DAPM */
-	unsigned int (*read)(struct snd_soc_platform *, unsigned int);
-	int (*write)(struct snd_soc_platform *, unsigned int, unsigned int);
 	int (*bespoke_trigger)(struct snd_pcm_substream *, int);
 };
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 5c78098..f359da2 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4151,24 +4151,6 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
 	platform->driver->remove(platform);
 }
 
-static int snd_soc_platform_drv_write(struct snd_soc_component *component,
-	unsigned int reg, unsigned int val)
-{
-	struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
-
-	return platform->driver->write(platform, reg, val);
-}
-
-static int snd_soc_platform_drv_read(struct snd_soc_component *component,
-	unsigned int reg, unsigned int *val)
-{
-	struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
-
-	*val = platform->driver->read(platform, reg);
-
-	return 0;
-}
-
 /**
  * snd_soc_add_platform - Add a platform to the ASoC core
  * @dev: The parent device for the platform
@@ -4205,10 +4187,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 		platform->component.probe = snd_soc_platform_drv_probe;
 	if (platform_drv->remove)
 		platform->component.remove = snd_soc_platform_drv_remove;
-	if (platform_drv->write)
-		platform->component.write = snd_soc_platform_drv_write;
-	if (platform_drv->read)
-		platform->component.read = snd_soc_platform_drv_read;
 
 #ifdef CONFIG_DEBUG_FS
 	platform->component.debugfs_prefix = "platform";
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 13/13] ASoC: Replace list_empty(&card->codec_dev_list) with !card->instantiated
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (11 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 12/13] ASoC: Remove support for legacy snd_soc_platform IO Lars-Peter Clausen
@ 2014-08-19 13:51 ` Lars-Peter Clausen
  2014-08-19 16:01 ` [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Mark Brown
  13 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2014-08-19 13:51 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Lars-Peter Clausen

With componentization we no longer necessarily need a snd_soc_codec struct for a
card. Instead of checking if the card's CODEC list is empty just use
card->instantiated to check if the card has been instantiated yet.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/soc-core.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index f359da2..e982cb0 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -552,10 +552,8 @@ int snd_soc_suspend(struct device *dev)
 	struct snd_soc_codec *codec;
 	int i, j;
 
-	/* If the initialization of this soc device failed, there is no codec
-	 * associated with it. Just bail out in this case.
-	 */
-	if (list_empty(&card->codec_dev_list))
+	/* If the card is not initialized yet there is nothing to do */
+	if (!card->instantiated)
 		return 0;
 
 	/* Due to the resume being scheduled into a workqueue we could
@@ -808,10 +806,8 @@ int snd_soc_resume(struct device *dev)
 	struct snd_soc_card *card = dev_get_drvdata(dev);
 	int i, ac97_control = 0;
 
-	/* If the initialization of this soc device failed, there is no codec
-	 * associated with it. Just bail out in this case.
-	 */
-	if (list_empty(&card->codec_dev_list))
+	/* If the card is not initialized yet there is nothing to do */
+	if (!card->instantiated)
 		return 0;
 
 	/* activate pins from sleep state */
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 00/13] ASoC: Componentization: Unified probe/remove path
  2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
                   ` (12 preceding siblings ...)
  2014-08-19 13:51 ` [PATCH 13/13] ASoC: Replace list_empty(&card->codec_dev_list) with !card->instantiated Lars-Peter Clausen
@ 2014-08-19 16:01 ` Mark Brown
  13 siblings, 0 replies; 15+ messages in thread
From: Mark Brown @ 2014-08-19 16:01 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: alsa-devel, Liam Girdwood


[-- Attachment #1.1: Type: text/plain, Size: 323 bytes --]

On Tue, Aug 19, 2014 at 03:51:17PM +0200, Lars-Peter Clausen wrote:
> This patch-set starts with consolidating the probe and remove paths of
> snd_soc_codec and snd_soc_platform drivers. Once that has been done it uses the
> new generic paths to also add probe and remove support to snd_soc_component

Applied all, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-08-19 16:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-19 13:51 [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 01/13] ASoC: Move debugfs registration to the component level Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 02/13] ASoC: Consolidate platform and CODEC probe/remove Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 03/13] ASoC: Make rtd->codec optional Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 04/13] ASoC: Add component level probe/remove support Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 05/13] ASoC: Move AUX dev support to the component level Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 06/13] ASoC: Pass component instead of DAPM context to AUX dev init callback Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 07/13] ASoC: Move component->probed check into soc_{remove, probe}_component() Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 08/13] ASoC: Cleanup DAI module reference counting Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 09/13] ASoC: Consolidate CPU and CODEC DAI removal Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 10/13] ASoC: Consolidate CPU and CODEC DAI lookup Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 11/13] ASoC: Automatically initialize regmap for all components Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 12/13] ASoC: Remove support for legacy snd_soc_platform IO Lars-Peter Clausen
2014-08-19 13:51 ` [PATCH 13/13] ASoC: Replace list_empty(&card->codec_dev_list) with !card->instantiated Lars-Peter Clausen
2014-08-19 16:01 ` [PATCH 00/13] ASoC: Componentization: Unified probe/remove path Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).