All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] ASoC: Add support for DAPM at the component level
@ 2014-06-16 16:13 Lars-Peter Clausen
  2014-06-16 16:13 ` [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component Lars-Peter Clausen
                   ` (10 more replies)
  0 siblings, 11 replies; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

Changes since v1:
	* Rebased onto asoc/for-next and 3.16-rc1
	* Added patch to remove platform field from widget and DAPM context to
	  prevent new users from being added


Original cover letter:

Hi,

This series is the next step in componentization. It moves the DAPM support to
the component level. This will allow any component to have DAPM widgets and
routes, which was previously only possible for CODECs, and will allow any
component to have DAPM widgets with controls (i.e. Mixers and MUXs), which was
previously only possible for CODECs. At the end of this patchset the DAPM code
will have (almost) no dependency on snd_soc_codec or snd_soc_platform and the
dependency on snd_soc_component is confined to 4 small helper functions. The
only reason why there is still snd_soc_codec/snd_soc_platform dependent code is
because there are still a lot of drivers which use widget->codec/platform and
dapm->codec/platform. So those still need to be initialized. This will be
cleaned up in a separate series and once that's done the codec and platform
fields will be removed from the widget and DAPM context struct.

One of the major problems of moving DAPM to the component level is that the DAPM
context is directly embedded in the snd_soc_codec and snd_soc_platform structs
and there are many drivers directly accessing that embedded field. This means it
is not possible to move the field without causing a bit of code churn in the
drivers. The patch series solves this by adding two fields to the component
struct. One pointer to a DAPM context, which points to the DAPM context that is
used by the component. And one DAPM context, which is used as the default if no
other DAPM context was provided. Neither of the fields is accessed directly,
instead a inline helper function is added that returns the DAPM context for a
component. This will make it possible to eventually seamlessly switch over once
all direct references to CODEC and platform DAPM contexts have been eliminated.

- Lars

Lars-Peter Clausen (11):
  ASoC: Move name_prefix from CODEC to component
  ASoC: Move name and id from CODEC/platform to component
  ASoC: Split component registration into two steps
  ASoC: Auto disconnect pins from all DAPM contexts
  ASoC: Add a set_bias_level() callback to the DAPM context struct
  ASoC: Add DAPM support at the component level
  ASoC: Use component DAPM context for platforms
  ASoC: Add component level stream_event() and seq_notifier() support
  ASoC: Add component level set_bias_level() support
  ASoC: dapm: Remove DAI DAPM context
  ASoC: dapm: Remove platform field from widget and dapm context struct

 include/sound/soc-dai.h        |   1 -
 include/sound/soc-dapm.h       |   8 +-
 include/sound/soc.h            |  53 +++++--
 include/trace/events/asoc.h    |   6 +-
 sound/soc/codecs/tlv320dac33.c |   2 +-
 sound/soc/soc-cache.c          |   7 +-
 sound/soc/soc-compress.c       |   8 +-
 sound/soc/soc-core.c           | 330 +++++++++++++++++++++++------------------
 sound/soc/soc-dapm.c           | 183 +++++++++++++----------
 sound/soc/soc-pcm.c            |   4 +-
 10 files changed, 344 insertions(+), 258 deletions(-)

-- 
1.8.0

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

* [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:03   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 02/11] ASoC: Move name and id from CODEC/platform " Lars-Peter Clausen
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

Move the name_prefix from the CODEC struct to the component struct. This will
eventually allow to specify prefixes for all types of components. It is also
necessary to make the DAPM code component type independent (i.e. a DAPM context
does not need to know whether it belongs to a CODEC or a platform or something
else).

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

diff --git a/include/sound/soc.h b/include/sound/soc.h
index ed9e2d7..e1cce00 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -682,6 +682,7 @@ struct snd_soc_component_driver {
 struct snd_soc_component {
 	const char *name;
 	int id;
+	const char *name_prefix;
 	struct device *dev;
 
 	unsigned int active;
@@ -710,7 +711,6 @@ struct snd_soc_component {
 /* SoC Audio Codec device */
 struct snd_soc_codec {
 	const char *name;
-	const char *name_prefix;
 	int id;
 	struct device *dev;
 	const struct snd_soc_codec_driver *driver;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b87d7d8..ba822e9 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1108,7 +1108,7 @@ static void soc_remove_dai_links(struct snd_soc_card *card)
 }
 
 static void soc_set_name_prefix(struct snd_soc_card *card,
-				struct snd_soc_codec *codec)
+				struct snd_soc_component *component)
 {
 	int i;
 
@@ -1117,11 +1117,11 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
 
 	for (i = 0; i < card->num_configs; i++) {
 		struct snd_soc_codec_conf *map = &card->codec_conf[i];
-		if (map->of_node && codec->dev->of_node != map->of_node)
+		if (map->of_node && component->dev->of_node != map->of_node)
 			continue;
-		if (map->dev_name && strcmp(codec->name, map->dev_name))
+		if (map->dev_name && strcmp(component->name, map->dev_name))
 			continue;
-		codec->name_prefix = map->name_prefix;
+		component->name_prefix = map->name_prefix;
 		break;
 	}
 }
@@ -1135,7 +1135,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
 
 	codec->card = card;
 	codec->dapm.card = card;
-	soc_set_name_prefix(card, codec);
+	soc_set_name_prefix(card, &codec->component);
 
 	if (!try_module_get(codec->dev->driver->owner))
 		return -ENODEV;
@@ -2403,7 +2403,7 @@ int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
 	struct snd_card *card = codec->card->snd_card;
 
 	return snd_soc_add_controls(card, codec->dev, controls, num_controls,
-			codec->name_prefix, &codec->component);
+			codec->component.name_prefix, &codec->component);
 }
 EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index cdc837e..8e08ace 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -375,6 +375,13 @@ static void dapm_reset(struct snd_soc_card *card)
 	}
 }
 
+static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm)
+{
+	if (!dapm->component)
+		return NULL;
+	return dapm->component->name_prefix;
+}
+
 static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
 	unsigned int *value)
 {
@@ -570,11 +577,7 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
 	const char *name;
 	int ret;
 
-	if (dapm->codec)
-		prefix = dapm->codec->name_prefix;
-	else
-		prefix = NULL;
-
+	prefix = soc_dapm_prefix(dapm);
 	if (prefix)
 		prefix_len = strlen(prefix) + 1;
 	else
@@ -2371,14 +2374,16 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
 	const char *source;
 	char prefixed_sink[80];
 	char prefixed_source[80];
+	const char *prefix;
 	int ret;
 
-	if (dapm->codec && dapm->codec->name_prefix) {
+	prefix = soc_dapm_prefix(dapm);
+	if (prefix) {
 		snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
-			 dapm->codec->name_prefix, route->sink);
+			 prefix, route->sink);
 		sink = prefixed_sink;
 		snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
-			 dapm->codec->name_prefix, route->source);
+			 prefix, route->source);
 		source = prefixed_source;
 	} else {
 		sink = route->sink;
@@ -2439,6 +2444,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
 	const char *source;
 	char prefixed_sink[80];
 	char prefixed_source[80];
+	const char *prefix;
 
 	if (route->control) {
 		dev_err(dapm->dev,
@@ -2446,12 +2452,13 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
 		return -EINVAL;
 	}
 
-	if (dapm->codec && dapm->codec->name_prefix) {
+	prefix = soc_dapm_prefix(dapm);
+	if (prefix) {
 		snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
-			 dapm->codec->name_prefix, route->sink);
+			 prefix, route->sink);
 		sink = prefixed_sink;
 		snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
-			 dapm->codec->name_prefix, route->source);
+			 prefix, route->source);
 		source = prefixed_source;
 	} else {
 		sink = route->sink;
@@ -2971,6 +2978,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 			 const struct snd_soc_dapm_widget *widget)
 {
 	struct snd_soc_dapm_widget *w;
+	const char *prefix;
 	int ret;
 
 	if ((w = dapm_cnew_widget(widget)) == NULL)
@@ -3011,9 +3019,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 		break;
 	}
 
-	if (dapm->codec && dapm->codec->name_prefix)
-		w->name = kasprintf(GFP_KERNEL, "%s %s",
-			dapm->codec->name_prefix, widget->name);
+	prefix = soc_dapm_prefix(dapm);
+	if (prefix)
+		w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name);
 	else
 		w->name = kasprintf(GFP_KERNEL, "%s", widget->name);
 
-- 
1.8.0

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

* [PATCH v2 02/11] ASoC: Move name and id from CODEC/platform to component
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
  2014-06-16 16:13 ` [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:04   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 03/11] ASoC: Split component registration into two steps Lars-Peter Clausen
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

The component struct already has a name and id field which are initialized to
the same values as the same fields in the CODEC and platform structs. So remove
them from the CODEC and platform structs and used the ones from the component
struct instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h            |  4 ----
 include/trace/events/asoc.h    |  6 ++---
 sound/soc/codecs/tlv320dac33.c |  2 +-
 sound/soc/soc-cache.c          |  7 +++---
 sound/soc/soc-compress.c       |  8 ++++---
 sound/soc/soc-core.c           | 53 ++++++++++++++++--------------------------
 sound/soc/soc-dapm.c           |  8 +++----
 sound/soc/soc-pcm.c            |  4 ++--
 8 files changed, 38 insertions(+), 54 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index e1cce00..f64bf94 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -710,8 +710,6 @@ struct snd_soc_component {
 
 /* SoC Audio Codec device */
 struct snd_soc_codec {
-	const char *name;
-	int id;
 	struct device *dev;
 	const struct snd_soc_codec_driver *driver;
 
@@ -848,8 +846,6 @@ struct snd_soc_platform_driver {
 };
 
 struct snd_soc_platform {
-	const char *name;
-	int id;
 	struct device *dev;
 	const struct snd_soc_platform_driver *driver;
 
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index c75c795..0194a64 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -296,17 +296,17 @@ TRACE_EVENT(snd_soc_cache_sync,
 	TP_ARGS(codec, type, status),
 
 	TP_STRUCT__entry(
-		__string(	name,		codec->name	)
+		__string(	name,		codec->component.name)
 		__string(	status,		status		)
 		__string(	type,		type		)
 		__field(	int,		id		)
 	),
 
 	TP_fast_assign(
-		__assign_str(name, codec->name);
+		__assign_str(name, codec->component.name);
 		__assign_str(status, status);
 		__assign_str(type, type);
-		__entry->id = codec->id;
+		__entry->id = codec->component.id;
 	),
 
 	TP_printk("codec=%s.%d type=%s status=%s", __get_str(name),
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index df3a750..ff006cc 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1404,7 +1404,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
 	if (dac33->irq >= 0) {
 		ret = request_irq(dac33->irq, dac33_interrupt_handler,
 				  IRQF_TRIGGER_RISING,
-				  codec->name, codec);
+				  codec->component.name, codec);
 		if (ret < 0) {
 			dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
 						dac33->irq, ret);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 00e70b6..a9f82b5 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -78,7 +78,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
 	mutex_init(&codec->cache_rw_mutex);
 
 	dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
-				codec->name);
+				codec->component.name);
 
 	if (codec_drv->reg_cache_default)
 		codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
@@ -98,8 +98,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
 int snd_soc_cache_exit(struct snd_soc_codec *codec)
 {
 	dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
-			codec->name);
-
+			codec->component.name);
 	kfree(codec->reg_cache);
 	codec->reg_cache = NULL;
 	return 0;
@@ -192,7 +191,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
 		return 0;
 
 	dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n",
-		codec->name);
+		codec->component.name);
 	trace_snd_soc_cache_sync(codec, name, "start");
 	ret = snd_soc_flat_cache_sync(codec);
 	if (!ret)
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 10f7f1d..f96fb96 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -37,7 +37,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
 	if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
 		ret = platform->driver->compr_ops->open(cstream);
 		if (ret < 0) {
-			pr_err("compress asoc: can't open platform %s\n", platform->name);
+			pr_err("compress asoc: can't open platform %s\n",
+				platform->component.name);
 			goto out;
 		}
 	}
@@ -84,7 +85,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 	if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
 		ret = platform->driver->compr_ops->open(cstream);
 		if (ret < 0) {
-			pr_err("compress asoc: can't open platform %s\n", platform->name);
+			pr_err("compress asoc: can't open platform %s\n",
+				platform->component.name);
 			goto out;
 		}
 	}
@@ -680,7 +682,7 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 	ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
 	if (ret < 0) {
 		pr_err("compress asoc: can't create compress for codec %s\n",
-			codec->name);
+			codec->component.name);
 		goto compr_err;
 	}
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ba822e9..b8cc88a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -274,7 +274,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
 {
 	struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
 
-	codec->debugfs_codec_root = debugfs_create_dir(codec->name,
+	codec->debugfs_codec_root = debugfs_create_dir(codec->component.name,
 						       debugfs_card_root);
 	if (!codec->debugfs_codec_root) {
 		dev_warn(codec->dev,
@@ -306,8 +306,8 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
 {
 	struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
 
-	platform->debugfs_platform_root = debugfs_create_dir(platform->name,
-						       debugfs_card_root);
+	platform->debugfs_platform_root = debugfs_create_dir(
+		platform->component.name, debugfs_card_root);
 	if (!platform->debugfs_platform_root) {
 		dev_warn(platform->dev,
 			"ASoC: Failed to create platform debugfs directory\n");
@@ -335,7 +335,7 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
 
 	list_for_each_entry(codec, &codec_list, list) {
 		len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
-			       codec->name);
+			       codec->component.name);
 		if (len >= 0)
 			ret += len;
 		if (ret > PAGE_SIZE) {
@@ -406,7 +406,7 @@ static ssize_t platform_list_read_file(struct file *file,
 
 	list_for_each_entry(platform, &platform_list, list) {
 		len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
-			       platform->name);
+			       platform->component.name);
 		if (len >= 0)
 			ret += len;
 		if (ret > PAGE_SIZE) {
@@ -528,7 +528,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
 	codec->ac97->dev.release = soc_ac97_device_release;
 
 	dev_set_name(&codec->ac97->dev, "%d-%d:%s",
-		     codec->card->snd_card->number, 0, codec->name);
+		     codec->card->snd_card->number, 0, codec->component.name);
 	err = device_register(&codec->ac97->dev);
 	if (err < 0) {
 		dev_err(codec->dev, "ASoC: Can't register ac97 bus\n");
@@ -857,7 +857,7 @@ static struct snd_soc_codec *soc_find_codec(const struct device_node *codec_of_n
 			if (codec->dev->of_node != codec_of_node)
 				continue;
 		} else {
-			if (strcmp(codec->name, codec_name))
+			if (strcmp(codec->component.name, codec_name))
 				continue;
 		}
 
@@ -945,7 +945,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 			    dai_link->platform_of_node)
 				continue;
 		} else {
-			if (strcmp(platform->name, platform_name))
+			if (strcmp(platform->component.name, platform_name))
 				continue;
 		}
 
@@ -1177,7 +1177,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
 		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->name);
+			codec->component.name);
 	}
 
 	if (driver->controls)
@@ -1647,7 +1647,8 @@ static struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card,
 		if (aux_dev->codec_of_node &&
 		   (codec->dev->of_node != aux_dev->codec_of_node))
 			continue;
-		if (aux_dev->codec_name && strcmp(codec->name, aux_dev->codec_name))
+		if (aux_dev->codec_name &&
+			strcmp(codec->component.name, aux_dev->codec_name))
 			continue;
 		return codec;
 	}
@@ -4131,11 +4132,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 {
 	int ret;
 
-	/* create platform component name */
-	platform->name = fmt_single_name(dev, &platform->id);
-	if (platform->name == NULL)
-		return -ENOMEM;
-
 	platform->dev = dev;
 	platform->driver = platform_drv;
 	platform->dapm.dev = dev;
@@ -4161,7 +4157,8 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 	list_add(&platform->list, &platform_list);
 	mutex_unlock(&client_mutex);
 
-	dev_dbg(dev, "ASoC: Registered platform '%s'\n", platform->name);
+	dev_dbg(dev, "ASoC: Registered platform '%s'\n",
+		platform->component.name);
 
 	return 0;
 }
@@ -4205,8 +4202,7 @@ void snd_soc_remove_platform(struct snd_soc_platform *platform)
 	mutex_unlock(&client_mutex);
 
 	dev_dbg(platform->dev, "ASoC: Unregistered platform '%s'\n",
-		platform->name);
-	kfree(platform->name);
+		platform->component.name);
 }
 EXPORT_SYMBOL_GPL(snd_soc_remove_platform);
 
@@ -4312,13 +4308,6 @@ int snd_soc_register_codec(struct device *dev,
 	if (codec == NULL)
 		return -ENOMEM;
 
-	/* create CODEC component name */
-	codec->name = fmt_single_name(dev, &codec->id);
-	if (codec->name == NULL) {
-		ret = -ENOMEM;
-		goto fail_codec;
-	}
-
 	if (codec_drv->write)
 		codec->component.write = snd_soc_codec_drv_write;
 	if (codec_drv->read)
@@ -4368,19 +4357,17 @@ int snd_soc_register_codec(struct device *dev,
 					   codec, dai_drv, num_dai, false);
 	if (ret < 0) {
 		dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
-		goto fail_codec_name;
+		goto fail_codec;
 	}
 
-	dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name);
+	dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n",
+		codec->component.name);
 	return 0;
 
-fail_codec_name:
+fail_codec:
 	mutex_lock(&client_mutex);
 	list_del(&codec->list);
 	mutex_unlock(&client_mutex);
-
-	kfree(codec->name);
-fail_codec:
 	kfree(codec);
 	return ret;
 }
@@ -4408,10 +4395,10 @@ found:
 	list_del(&codec->list);
 	mutex_unlock(&client_mutex);
 
-	dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name);
+	dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n",
+			codec->component.name);
 
 	snd_soc_cache_exit(codec);
-	kfree(codec->name);
 	kfree(codec);
 }
 EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8e08ace..f3ccf6d1 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3403,8 +3403,8 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
 			source = cpu_dai->playback_widget;
 			sink = codec_dai->playback_widget;
 			dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
-				cpu_dai->codec->name, source->name,
-				codec_dai->platform->name, sink->name);
+				cpu_dai->component->name, source->name,
+				codec_dai->component->name, sink->name);
 
 			snd_soc_dapm_add_path(&card->dapm, source, sink,
 				NULL, NULL);
@@ -3415,8 +3415,8 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
 			source = codec_dai->capture_widget;
 			sink = cpu_dai->capture_widget;
 			dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
-				codec_dai->codec->name, source->name,
-				cpu_dai->platform->name, sink->name);
+				codec_dai->component->name, source->name,
+				cpu_dai->component->name, sink->name);
 
 			snd_soc_dapm_add_path(&card->dapm, source, sink,
 				NULL, NULL);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 54d18f2..9b78bb6 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -376,7 +376,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 		ret = platform->driver->ops->open(substream);
 		if (ret < 0) {
 			dev_err(platform->dev, "ASoC: can't open platform"
-				" %s: %d\n", platform->name, ret);
+				" %s: %d\n", platform->component.name, ret);
 			goto platform_err;
 		}
 	}
@@ -707,7 +707,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 		ret = platform->driver->ops->hw_params(substream, params);
 		if (ret < 0) {
 			dev_err(platform->dev, "ASoC: %s hw params failed: %d\n",
-			       platform->name, ret);
+			       platform->component.name, ret);
 			goto platform_err;
 		}
 	}
-- 
1.8.0

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

* [PATCH v2 03/11] ASoC: Split component registration into two steps
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
  2014-06-16 16:13 ` [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component Lars-Peter Clausen
  2014-06-16 16:13 ` [PATCH v2 02/11] ASoC: Move name and id from CODEC/platform " Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:05   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 04/11] ASoC: Auto disconnect pins from all DAPM contexts Lars-Peter Clausen
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

Split snd_soc_component_register() into snd_soc_component_initialize() and
snd_soc_component_add(). Using a 2-stage registration approach has the advantage
that it is possible to modify the component after it has been initialized, but
before it is made visible to the system. This e.g. allows CODECs or platforms to
overwrite some of the default settings made in snd_soc_component_initialize().

Similar snd_soc_component_unregister() is split into two steps as well,
snd_soc_component_delete(), which removes the component from the system, and
snd_soc_component_cleanup(), which frees all the resources allocated by the
component.

Furthermore this patch makes sure that if a component is visible on two list
(e.g. the component list and the CODEC list) it is added or removed to both
lists atomically.

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

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b8cc88a..0944da6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3922,16 +3922,14 @@ static void snd_soc_unregister_dais(struct snd_soc_component *component)
  * snd_soc_register_dais - Register a DAI with the ASoC core
  *
  * @component: The component the DAIs are registered for
- * @codec: The CODEC that the DAIs are registered for, NULL if the component is
- *         not a CODEC.
  * @dai_drv: DAI driver to use for the DAIs
  * @count: Number of DAIs
  * @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the
  *                     parent's name.
  */
 static int snd_soc_register_dais(struct snd_soc_component *component,
-	struct snd_soc_codec *codec, struct snd_soc_dai_driver *dai_drv,
-	size_t count, bool legacy_dai_naming)
+	struct snd_soc_dai_driver *dai_drv, size_t count,
+	bool legacy_dai_naming)
 {
 	struct device *dev = component->dev;
 	struct snd_soc_dai *dai;
@@ -3940,6 +3938,9 @@ static int snd_soc_register_dais(struct snd_soc_component *component,
 
 	dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);
 
+	component->dai_drv = dai_drv;
+	component->num_dai = count;
+
 	for (i = 0; i < count; i++) {
 
 		dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
@@ -3972,7 +3973,6 @@ static int snd_soc_register_dais(struct snd_soc_component *component,
 		}
 
 		dai->component = component;
-		dai->codec = codec;
 		dai->dev = dev;
 		dai->driver = &dai_drv[i];
 		dai->dapm.dev = dev;
@@ -3995,60 +3995,52 @@ err:
 	return ret;
 }
 
-/**
- * snd_soc_register_component - Register a component with the ASoC core
- *
- */
-static int
-__snd_soc_register_component(struct device *dev,
-			     struct snd_soc_component *cmpnt,
-			     const struct snd_soc_component_driver *cmpnt_drv,
-			     struct snd_soc_codec *codec,
-			     struct snd_soc_dai_driver *dai_drv,
-			     int num_dai, bool allow_single_dai)
+static int snd_soc_component_initialize(struct snd_soc_component *component,
+	const struct snd_soc_component_driver *driver, struct device *dev)
 {
-	int ret;
-
-	dev_dbg(dev, "component register %s\n", dev_name(dev));
-
-	if (!cmpnt) {
-		dev_err(dev, "ASoC: Failed to connecting component\n");
+	component->name = fmt_single_name(dev, &component->id);
+	if (!component->name) {
+		dev_err(dev, "ASoC: Failed to allocate name\n");
 		return -ENOMEM;
 	}
 
-	mutex_init(&cmpnt->io_mutex);
+	component->dev = dev;
+	component->driver = driver;
 
-	cmpnt->name = fmt_single_name(dev, &cmpnt->id);
-	if (!cmpnt->name) {
-		dev_err(dev, "ASoC: Failed to simplifying name\n");
-		return -ENOMEM;
-	}
+	INIT_LIST_HEAD(&component->dai_list);
+	mutex_init(&component->io_mutex);
 
-	cmpnt->dev	= dev;
-	cmpnt->driver	= cmpnt_drv;
-	cmpnt->dai_drv	= dai_drv;
-	cmpnt->num_dai	= num_dai;
-	INIT_LIST_HEAD(&cmpnt->dai_list);
+	return 0;
+}
 
-	ret = snd_soc_register_dais(cmpnt, codec, dai_drv, num_dai,
-		allow_single_dai);
-	if (ret < 0) {
-		dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
-		goto error_component_name;
-	}
+static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
+{
+	list_add(&component->list, &component_list);
+}
 
+static void snd_soc_component_add(struct snd_soc_component *component)
+{
 	mutex_lock(&client_mutex);
-	list_add(&cmpnt->list, &component_list);
+	snd_soc_component_add_unlocked(component);
 	mutex_unlock(&client_mutex);
+}
 
-	dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
-
-	return ret;
+static void snd_soc_component_cleanup(struct snd_soc_component *component)
+{
+	snd_soc_unregister_dais(component);
+	kfree(component->name);
+}
 
-error_component_name:
-	kfree(cmpnt->name);
+static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
+{
+	list_del(&component->list);
+}
 
-	return ret;
+static void snd_soc_component_del(struct snd_soc_component *component)
+{
+	mutex_lock(&client_mutex);
+	snd_soc_component_del_unlocked(component);
+	mutex_unlock(&client_mutex);
 }
 
 int snd_soc_register_component(struct device *dev,
@@ -4057,32 +4049,38 @@ int snd_soc_register_component(struct device *dev,
 			       int num_dai)
 {
 	struct snd_soc_component *cmpnt;
+	int ret;
 
-	cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
+	cmpnt = kzalloc(sizeof(*cmpnt), GFP_KERNEL);
 	if (!cmpnt) {
 		dev_err(dev, "ASoC: Failed to allocate memory\n");
 		return -ENOMEM;
 	}
 
+	ret = snd_soc_component_initialize(cmpnt, cmpnt_drv, dev);
+	if (ret)
+		goto err_free;
+
 	cmpnt->ignore_pmdown_time = true;
 	cmpnt->registered_as_component = true;
 
-	return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL,
-					    dai_drv, num_dai, true);
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_component);
+	ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai, true);
+	if (ret < 0) {
+		dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
+		goto err_cleanup;
+	}
 
-static void __snd_soc_unregister_component(struct snd_soc_component *cmpnt)
-{
-	snd_soc_unregister_dais(cmpnt);
+	snd_soc_component_add(cmpnt);
 
-	mutex_lock(&client_mutex);
-	list_del(&cmpnt->list);
-	mutex_unlock(&client_mutex);
+	return 0;
 
-	dev_dbg(cmpnt->dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
-	kfree(cmpnt->name);
+err_cleanup:
+	snd_soc_component_cleanup(cmpnt);
+err_free:
+	kfree(cmpnt);
+	return ret;
 }
+EXPORT_SYMBOL_GPL(snd_soc_register_component);
 
 /**
  * snd_soc_unregister_component - Unregister a component from the ASoC core
@@ -4099,7 +4097,9 @@ void snd_soc_unregister_component(struct device *dev)
 	return;
 
 found:
-	__snd_soc_unregister_component(cmpnt);
+	snd_soc_component_del(cmpnt);
+	snd_soc_component_cleanup(cmpnt);
+	kfree(cmpnt);
 }
 EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
 
@@ -4132,6 +4132,11 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 {
 	int ret;
 
+	ret = snd_soc_component_initialize(&platform->component,
+			&platform_drv->component_driver, dev);
+	if (ret)
+		return ret;
+
 	platform->dev = dev;
 	platform->driver = platform_drv;
 	platform->dapm.dev = dev;
@@ -4143,17 +4148,8 @@ 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;
 
-	/* register component */
-	ret = __snd_soc_register_component(dev, &platform->component,
-					   &platform_drv->component_driver,
-					   NULL, NULL, 0, false);
-	if (ret < 0) {
-		dev_err(platform->component.dev,
-			"ASoC: Failed to register component: %d\n", ret);
-		return ret;
-	}
-
 	mutex_lock(&client_mutex);
+	snd_soc_component_add_unlocked(&platform->component);
 	list_add(&platform->list, &platform_list);
 	mutex_unlock(&client_mutex);
 
@@ -4195,12 +4191,14 @@ EXPORT_SYMBOL_GPL(snd_soc_register_platform);
  */
 void snd_soc_remove_platform(struct snd_soc_platform *platform)
 {
-	__snd_soc_unregister_component(&platform->component);
 
 	mutex_lock(&client_mutex);
 	list_del(&platform->list);
+	snd_soc_component_del_unlocked(&platform->component);
 	mutex_unlock(&client_mutex);
 
+	snd_soc_component_cleanup(&platform->component);
+
 	dev_dbg(platform->dev, "ASoC: Unregistered platform '%s'\n",
 		platform->component.name);
 }
@@ -4299,6 +4297,7 @@ int snd_soc_register_codec(struct device *dev,
 			   int num_dai)
 {
 	struct snd_soc_codec *codec;
+	struct snd_soc_dai *dai;
 	struct regmap *regmap;
 	int ret, i;
 
@@ -4308,6 +4307,11 @@ int snd_soc_register_codec(struct device *dev,
 	if (codec == NULL)
 		return -ENOMEM;
 
+	ret = snd_soc_component_initialize(&codec->component,
+			&codec_drv->component_driver, dev);
+	if (ret)
+		goto err_free;
+
 	if (codec_drv->write)
 		codec->component.write = snd_soc_codec_drv_write;
 	if (codec_drv->read)
@@ -4337,7 +4341,7 @@ int snd_soc_register_codec(struct device *dev,
 				dev_err(codec->dev,
 						"Failed to set cache I/O:%d\n",
 						ret);
-				return ret;
+				goto err_cleanup;
 			}
 		}
 	}
@@ -4347,27 +4351,27 @@ int snd_soc_register_codec(struct device *dev,
 		fixup_codec_formats(&dai_drv[i].capture);
 	}
 
+	ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false);
+	if (ret < 0) {
+		dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
+		goto err_cleanup;
+	}
+
+	list_for_each_entry(dai, &codec->component.dai_list, list)
+		dai->codec = codec;
+
 	mutex_lock(&client_mutex);
+	snd_soc_component_add_unlocked(&codec->component);
 	list_add(&codec->list, &codec_list);
 	mutex_unlock(&client_mutex);
 
-	/* register component */
-	ret = __snd_soc_register_component(dev, &codec->component,
-					   &codec_drv->component_driver,
-					   codec, dai_drv, num_dai, false);
-	if (ret < 0) {
-		dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
-		goto fail_codec;
-	}
-
 	dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n",
 		codec->component.name);
 	return 0;
 
-fail_codec:
-	mutex_lock(&client_mutex);
-	list_del(&codec->list);
-	mutex_unlock(&client_mutex);
+err_cleanup:
+	snd_soc_component_cleanup(&codec->component);
+err_free:
 	kfree(codec);
 	return ret;
 }
@@ -4389,15 +4393,16 @@ void snd_soc_unregister_codec(struct device *dev)
 	return;
 
 found:
-	__snd_soc_unregister_component(&codec->component);
 
 	mutex_lock(&client_mutex);
 	list_del(&codec->list);
+	snd_soc_component_del_unlocked(&codec->component);
 	mutex_unlock(&client_mutex);
 
 	dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n",
 			codec->component.name);
 
+	snd_soc_component_cleanup(&codec->component);
 	snd_soc_cache_exit(codec);
 	kfree(codec);
 }
-- 
1.8.0

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

* [PATCH v2 04/11] ASoC: Auto disconnect pins from all DAPM contexts
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (2 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 03/11] ASoC: Split component registration into two steps Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:07   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct Lars-Peter Clausen
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

Currently only pins in CODEC DAPM contexts are automatically marked as
non-connected if the card has the fully_routed flag set. This makes sense since
widgets which qualify for auto-disconnection are only found in CODEC DAPM
contexts. But with componentisation this is going to change, so consider all
widgets for auto-disconnection.

Also it is probably faster to walk the widgets list only once rather than once
for each CODEC.

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

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 6b59471..8db627c 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -431,7 +431,7 @@ int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
 					   const char *pin);
 int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
 				const char *pin);
-void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);
+void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card);
 
 /* Mostly internal - should not normally be used */
 void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0944da6..bca8a71 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1928,8 +1928,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 	}
 
 	if (card->fully_routed)
-		list_for_each_entry(codec, &card->codec_dev_list, card_list)
-			snd_soc_dapm_auto_nc_codec_pins(codec);
+		snd_soc_dapm_auto_nc_pins(card);
 
 	snd_soc_dapm_new_widgets(card);
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f3ccf6d1..fab1a88 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3766,36 +3766,31 @@ static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
 }
 
 /**
- * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins
- * @codec: The codec whose pins should be processed
+ * snd_soc_dapm_auto_nc_pins - call snd_soc_dapm_nc_pin for unused pins
+ * @card: The card whose pins should be processed
  *
- * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec
- * which are unused. Pins are used if they are connected externally to the
- * codec, whether that be to some other device, or a loop-back connection to
- * the codec itself.
+ * Automatically call snd_soc_dapm_nc_pin() for any external pins in the card
+ * which are unused. Pins are used if they are connected externally to a
+ * component, whether that be to some other device, or a loop-back connection to
+ * the component itself.
  */
-void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec)
+void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card)
 {
-	struct snd_soc_card *card = codec->card;
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	struct snd_soc_dapm_widget *w;
 
-	dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n",
-		&card->dapm, &codec->dapm);
+	dev_dbg(card->dev, "ASoC: Auto NC: DAPMs: card:%p\n", &card->dapm);
 
 	list_for_each_entry(w, &card->widgets, list) {
-		if (w->dapm != dapm)
-			continue;
 		switch (w->id) {
 		case snd_soc_dapm_input:
 		case snd_soc_dapm_output:
 		case snd_soc_dapm_micbias:
-			dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n",
+			dev_dbg(card->dev, "ASoC: Auto NC: Checking widget %s\n",
 				w->name);
 			if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
-				dev_dbg(codec->dev,
+				dev_dbg(card->dev,
 					"... Not in map; disabling\n");
-				snd_soc_dapm_nc_pin(dapm, w->name);
+				snd_soc_dapm_nc_pin(w->dapm, w->name);
 			}
 			break;
 		default:
-- 
1.8.0

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

* [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (3 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 04/11] ASoC: Auto disconnect pins from all DAPM contexts Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:14   ` Mark Brown
  2014-06-21 20:34   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 06/11] ASoC: Add DAPM support at the component level Lars-Peter Clausen
                   ` (5 subsequent siblings)
  10 siblings, 2 replies; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

Currently the DAPM code directly looks at the CODEC driver struct to get a
handle to the set_bias_level() callback. This patch adds a new set_bias_level()
callback to the DAPM context struct. The DAPM code will use this new callback
instead of the CODEC callback. For CODECs the new callback is set up to call the
CODEC specific set_bias_level callback(). Not looking directly at the CODEC
driver struct will allow non CODEC DAPM contexts to implement a set_bias_level()
callback.

This is also similar to how the seq_notifier() and stream_event() callbacks are
currently handled.

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

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8db627c..3a5c4f9 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -601,6 +601,8 @@ struct snd_soc_dapm_context {
 	struct list_head list;
 
 	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
+	int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
+			      enum snd_soc_bias_level level);
 
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs_dapm;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index bca8a71..10e13c4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4285,6 +4285,14 @@ static int snd_soc_codec_drv_read(struct snd_soc_component *component,
 	return 0;
 }
 
+static int snd_soc_codec_set_bias_level(struct snd_soc_dapm_context *dapm,
+	enum snd_soc_bias_level level)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
+
+	return codec->driver->set_bias_level(codec, level);
+}
+
 /**
  * snd_soc_register_codec - Register a codec with the ASoC core
  *
@@ -4322,6 +4330,8 @@ int snd_soc_register_codec(struct device *dev,
 	codec->dapm.component = &codec->component;
 	codec->dapm.seq_notifier = codec_drv->seq_notifier;
 	codec->dapm.stream_event = codec_drv->stream_event;
+	if (codec_drv->set_bias_level)
+		codec->dapm.set_bias_level = snd_soc_codec_set_bias_level;
 	codec->dev = dev;
 	codec->driver = codec_drv;
 	codec->component.val_bytes = codec_drv->reg_word_size;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index fab1a88..6c94a6b 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -427,15 +427,10 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
 	if (ret != 0)
 		goto out;
 
-	if (dapm->codec) {
-		if (dapm->codec->driver->set_bias_level)
-			ret = dapm->codec->driver->set_bias_level(dapm->codec,
-								  level);
-		else
-			dapm->bias_level = level;
-	} else if (!card || dapm != &card->dapm) {
+	if (dapm->set_bias_level)
+		ret = dapm->set_bias_level(dapm, level);
+	else if (!card || dapm != &card->dapm)
 		dapm->bias_level = level;
-	}
 
 	if (ret != 0)
 		goto out;
-- 
1.8.0

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

* [PATCH v2 06/11] ASoC: Add DAPM support at the component level
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (4 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:34   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 07/11] ASoC: Use component DAPM context for platforms Lars-Peter Clausen
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

This patch adds full DAPM support at the component level. Previously there was
only full DAPM support for CODECs and partial DAPM support (e.g. no Mixers nor
MUXs) for platforms. Having DAPM support at the component level will allow all
types of components to use DAPM and also help in consolidating the DAPM support
between CODECs and platforms.

Since the DAPM context is directly embedded into the snd_soc_codec and
snd_soc_platform struct and the 'dapm' field is directly referenced in a lot of
drivers moving the field just right now is not possible without causing code
churn. The approach this patch takes is to add two new fields to the component
struct. One field which is the pointer to the actual DAPM context used by the
component and one DAPM context that will be used as the default if no other
context was specified. For CODECs and platforms the pointer is initialized to
point to the CODEC or platform DAPM context. All generic code when referencing
a component's DAPM struct will go via the pointer. This will make it possible to
eventually seamlessly move the DAPM context from snd_soc_codec and
snd_soc_platform struct over once all direct references have been eliminated.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc-dapm.h |   2 +
 include/sound/soc.h      |  30 ++++++++++++++
 sound/soc/soc-core.c     |  19 ++++++---
 sound/soc/soc-dapm.c     | 100 ++++++++++++++++++++++++++++++-----------------
 4 files changed, 110 insertions(+), 41 deletions(-)

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 3a5c4f9..e292683 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -441,6 +441,8 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
 	struct snd_soc_dapm_widget_list **list);
 
 struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol);
+struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
+	struct snd_kcontrol *kcontrol);
 
 /* dapm widget types */
 enum snd_soc_dapm_type {
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f64bf94..a21dfec 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -706,6 +706,10 @@ struct snd_soc_component {
 	int val_bytes;
 
 	struct mutex io_mutex;
+
+	/* Don't use these, use snd_soc_component_get_dapm() */
+	struct snd_soc_dapm_context dapm;
+	struct snd_soc_dapm_context *dapm_ptr;
 };
 
 /* SoC Audio Codec device */
@@ -1161,6 +1165,21 @@ static inline struct snd_soc_platform *snd_soc_component_to_platform(
 }
 
 /**
+ * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
+ *  embedded in
+ * @dapm: The DAPM context to cast to the component
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a component (e.g. in a component driver). Otherwise the behavior is
+ * undefined.
+ */
+static inline struct snd_soc_component *snd_soc_dapm_to_component(
+	struct snd_soc_dapm_context *dapm)
+{
+	return container_of(dapm, struct snd_soc_component, dapm);
+}
+
+/**
  * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
  * @dapm: The DAPM context to cast to the CODEC
  *
@@ -1187,6 +1206,17 @@ static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
 	return container_of(dapm, struct snd_soc_platform, dapm);
 }
 
+/**
+ * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
+ *  component
+ * @component: The component for which to get the DAPM context
+ */
+static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
+	struct snd_soc_component *component)
+{
+	return component->dapm_ptr;
+}
+
 /* codec IO */
 unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
 int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 10e13c4..f519a9f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3997,6 +3997,8 @@ err:
 static int snd_soc_component_initialize(struct snd_soc_component *component,
 	const struct snd_soc_component_driver *driver, struct device *dev)
 {
+	struct snd_soc_dapm_context *dapm;
+
 	component->name = fmt_single_name(dev, &component->id);
 	if (!component->name) {
 		dev_err(dev, "ASoC: Failed to allocate name\n");
@@ -4006,6 +4008,14 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	component->dev = dev;
 	component->driver = driver;
 
+	if (!component->dapm_ptr)
+		component->dapm_ptr = &component->dapm;
+
+	dapm = component->dapm_ptr;
+	dapm->dev = dev;
+	dapm->component = component;
+	dapm->bias_level = SND_SOC_BIAS_OFF;
+
 	INIT_LIST_HEAD(&component->dai_list);
 	mutex_init(&component->io_mutex);
 
@@ -4131,6 +4141,8 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 {
 	int ret;
 
+	platform->component.dapm_ptr = &platform->dapm;
+
 	ret = snd_soc_component_initialize(&platform->component,
 			&platform_drv->component_driver, dev);
 	if (ret)
@@ -4138,9 +4150,7 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 
 	platform->dev = dev;
 	platform->driver = platform_drv;
-	platform->dapm.dev = dev;
 	platform->dapm.platform = platform;
-	platform->dapm.component = &platform->component;
 	platform->dapm.stream_event = platform_drv->stream_event;
 	if (platform_drv->write)
 		platform->component.write = snd_soc_platform_drv_write;
@@ -4314,6 +4324,8 @@ int snd_soc_register_codec(struct device *dev,
 	if (codec == NULL)
 		return -ENOMEM;
 
+	codec->component.dapm_ptr = &codec->dapm;
+
 	ret = snd_soc_component_initialize(&codec->component,
 			&codec_drv->component_driver, dev);
 	if (ret)
@@ -4324,10 +4336,7 @@ int snd_soc_register_codec(struct device *dev,
 	if (codec_drv->read)
 		codec->component.read = snd_soc_codec_drv_read;
 	codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
-	codec->dapm.bias_level = SND_SOC_BIAS_OFF;
-	codec->dapm.dev = dev;
 	codec->dapm.codec = codec;
-	codec->dapm.component = &codec->component;
 	codec->dapm.seq_notifier = codec_drv->seq_notifier;
 	codec->dapm.stream_event = codec_drv->stream_event;
 	if (codec_drv->set_bias_level)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 6c94a6b..4702b92 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -350,12 +350,27 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
 }
 
 /**
+ * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
+ *  kcontrol
+ * @kcontrol: The kcontrol
+ *
+ * Note: This function must only be used on kcontrols that are known to have
+ * been registered for a CODEC. Otherwise the behaviour is undefined.
+ */
+struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
+	struct snd_kcontrol *kcontrol)
+{
+	return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm);
+
+/**
  * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
  * @kcontrol: The kcontrol
  */
 struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
 {
-	return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->codec;
+	return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
 
@@ -382,23 +397,31 @@ static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm)
 	return dapm->component->name_prefix;
 }
 
-static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
+static int soc_dapm_read(struct snd_soc_dapm_context *dapm, int reg,
 	unsigned int *value)
 {
-	if (!w->dapm->component)
+	if (!dapm->component)
 		return -EIO;
-	return snd_soc_component_read(w->dapm->component, reg, value);
+	return snd_soc_component_read(dapm->component, reg, value);
 }
 
-static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
+static int soc_dapm_update_bits(struct snd_soc_dapm_context *dapm,
 	int reg, unsigned int mask, unsigned int value)
 {
-	if (!w->dapm->component)
+	if (!dapm->component)
 		return -EIO;
-	return snd_soc_component_update_bits_async(w->dapm->component, reg,
+	return snd_soc_component_update_bits_async(dapm->component, reg,
 		mask, value);
 }
 
+static int soc_dapm_test_bits(struct snd_soc_dapm_context *dapm,
+	int reg, unsigned int mask, unsigned int value)
+{
+	if (!dapm->component)
+		return -EIO;
+	return snd_soc_component_test_bits(dapm->component, reg, mask, value);
+}
+
 static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
 {
 	if (dapm->component)
@@ -454,7 +477,7 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
 	int i;
 
 	if (e->reg != SND_SOC_NOPM) {
-		soc_widget_read(dest, e->reg, &val);
+		soc_dapm_read(dapm, e->reg, &val);
 		val = (val >> e->shift_l) & e->mask;
 		item = snd_soc_enum_val_to_item(e, val);
 	} else {
@@ -498,7 +521,7 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
 	unsigned int val;
 
 	if (reg != SND_SOC_NOPM) {
-		soc_widget_read(w, reg, &val);
+		soc_dapm_read(w->dapm, reg, &val);
 		val = (val >> shift) & mask;
 		if (invert)
 			val = max - val;
@@ -1306,16 +1329,18 @@ static void dapm_seq_check_event(struct snd_soc_card *card,
 static void dapm_seq_run_coalesced(struct snd_soc_card *card,
 				   struct list_head *pending)
 {
+	struct snd_soc_dapm_context *dapm;
 	struct snd_soc_dapm_widget *w;
 	int reg;
 	unsigned int value = 0;
 	unsigned int mask = 0;
 
-	reg = list_first_entry(pending, struct snd_soc_dapm_widget,
-			       power_list)->reg;
+	w = list_first_entry(pending, struct snd_soc_dapm_widget, power_list);
+	reg = w->reg;
+	dapm = w->dapm;
 
 	list_for_each_entry(w, pending, power_list) {
-		WARN_ON(reg != w->reg);
+		WARN_ON(reg != w->reg || dapm != w->dapm);
 		w->power = w->new_power;
 
 		mask |= w->mask << w->shift;
@@ -1324,7 +1349,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
 		else
 			value |= w->off_val << w->shift;
 
-		pop_dbg(w->dapm->dev, card->pop_time,
+		pop_dbg(dapm->dev, card->pop_time,
 			"pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
 			w->name, reg, value, mask);
 
@@ -1337,14 +1362,12 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card,
 		/* Any widget will do, they should all be updating the
 		 * same register.
 		 */
-		w = list_first_entry(pending, struct snd_soc_dapm_widget,
-				     power_list);
 
-		pop_dbg(w->dapm->dev, card->pop_time,
+		pop_dbg(dapm->dev, card->pop_time,
 			"pop test : Applying 0x%x/0x%x to %x in %dms\n",
 			value, mask, reg, card->pop_time);
 		pop_wait(card->pop_time);
-		soc_widget_update_bits(w, reg, mask, value);
+		soc_dapm_update_bits(dapm, reg, mask, value);
 	}
 
 	list_for_each_entry(w, pending, power_list) {
@@ -1490,7 +1513,8 @@ static void dapm_widget_update(struct snd_soc_card *card)
 	if (!w)
 		return;
 
-	ret = soc_widget_update_bits(w, update->reg, update->mask, update->val);
+	ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask,
+		update->val);
 	if (ret < 0)
 		dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
 			w->name, ret);
@@ -2672,7 +2696,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
 
 		/* Read the initial power state from the device */
 		if (w->reg >= 0) {
-			soc_widget_read(w, w->reg, &val);
+			soc_dapm_read(w->dapm, w->reg, &val);
 			val = val >> w->shift;
 			val &= w->mask;
 			if (val == w->on_val)
@@ -2703,8 +2727,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
 int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_card *card = codec->card;
+	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct snd_soc_card *card = dapm->card;
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	int reg = mc->reg;
@@ -2713,17 +2737,20 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned int val;
+	int ret = 0;
 
 	if (snd_soc_volsw_is_stereo(mc))
-		dev_warn(codec->dapm.dev,
+		dev_warn(dapm->dev,
 			 "ASoC: Control '%s' is stereo, which is not supported\n",
 			 kcontrol->id.name);
 
 	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
-	if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM)
-		val = (snd_soc_read(codec, reg) >> shift) & mask;
-	else
+	if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) {
+		ret = soc_dapm_read(dapm, reg, &val);
+		val = (val >> shift) & mask;
+	} else {
 		val = dapm_kcontrol_get_value(kcontrol);
+	}
 	mutex_unlock(&card->dapm_mutex);
 
 	if (invert)
@@ -2731,7 +2758,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
 	else
 		ucontrol->value.integer.value[0] = val;
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
 
@@ -2747,8 +2774,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_card *card = codec->card;
+	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct snd_soc_card *card = dapm->card;
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	int reg = mc->reg;
@@ -2762,7 +2789,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	int ret = 0;
 
 	if (snd_soc_volsw_is_stereo(mc))
-		dev_warn(codec->dapm.dev,
+		dev_warn(dapm->dev,
 			 "ASoC: Control '%s' is stereo, which is not supported\n",
 			 kcontrol->id.name);
 
@@ -2780,7 +2807,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 		mask = mask << shift;
 		val = val << shift;
 
-		reg_change = snd_soc_test_bits(codec, reg, mask, val);
+		reg_change = soc_dapm_test_bits(dapm, reg, mask, val);
 	}
 
 	if (change || reg_change) {
@@ -2819,12 +2846,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
 int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int reg_val, val;
+	int ret = 0;
 
 	if (e->reg != SND_SOC_NOPM)
-		reg_val = snd_soc_read(codec, e->reg);
+		ret = soc_dapm_read(dapm, e->reg, &reg_val);
 	else
 		reg_val = dapm_kcontrol_get_value(kcontrol);
 
@@ -2836,7 +2864,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
 		ucontrol->value.enumerated.item[1] = val;
 	}
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
 
@@ -2852,8 +2880,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
 int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-	struct snd_soc_card *card = codec->card;
+	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct snd_soc_card *card = dapm->card;
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int *item = ucontrol->value.enumerated.item;
 	unsigned int val, change;
@@ -2876,7 +2904,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
 	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
 
 	if (e->reg != SND_SOC_NOPM)
-		change = snd_soc_test_bits(codec, e->reg, mask, val);
+		change = soc_dapm_test_bits(dapm, e->reg, mask, val);
 	else
 		change = dapm_kcontrol_set_value(kcontrol, val);
 
-- 
1.8.0

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

* [PATCH v2 07/11] ASoC: Use component DAPM context for platforms
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (5 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 06/11] ASoC: Add DAPM support at the component level Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:34   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 08/11] ASoC: Add component level stream_event() and seq_notifier() support Lars-Peter Clausen
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

The snd_soc_platform dapm field is not accessed outside of the ASoC core. Switch
it over to using the snd_soc_component DAPM context.

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

diff --git a/include/sound/soc.h b/include/sound/soc.h
index a21dfec..84ebc07 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -862,8 +862,6 @@ struct snd_soc_platform {
 
 	struct snd_soc_component component;
 
-	struct snd_soc_dapm_context dapm;
-
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs_platform_root;
 #endif
@@ -1203,7 +1201,7 @@ static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
 static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
 	struct snd_soc_dapm_context *dapm)
 {
-	return container_of(dapm, struct snd_soc_platform, dapm);
+	return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
 }
 
 /**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index f519a9f..711e99c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -314,7 +314,7 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
 		return;
 	}
 
-	snd_soc_dapm_debugfs_init(&platform->dapm,
+	snd_soc_dapm_debugfs_init(&platform->component.dapm,
 		platform->debugfs_platform_root);
 }
 
@@ -974,7 +974,7 @@ static int soc_remove_platform(struct snd_soc_platform *platform)
 	}
 
 	/* Make sure all DAPM widgets are freed */
-	snd_soc_dapm_free(&platform->dapm);
+	snd_soc_dapm_free(&platform->component.dapm);
 
 	soc_cleanup_platform_debugfs(platform);
 	platform->probed = 0;
@@ -1210,7 +1210,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
 	struct snd_soc_dai *dai;
 
 	platform->card = card;
-	platform->dapm.card = card;
+	platform->component.dapm.card = card;
 
 	if (!try_module_get(platform->dev->driver->owner))
 		return -ENODEV;
@@ -1218,7 +1218,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
 	soc_init_platform_debugfs(platform);
 
 	if (driver->dapm_widgets)
-		snd_soc_dapm_new_controls(&platform->dapm,
+		snd_soc_dapm_new_controls(&platform->component.dapm,
 			driver->dapm_widgets, driver->num_dapm_widgets);
 
 	/* Create DAPM widgets for each DAI stream */
@@ -1226,10 +1226,11 @@ static int soc_probe_platform(struct snd_soc_card *card,
 		if (component->dev != platform->dev)
 			continue;
 		list_for_each_entry(dai, &component->dai_list, list)
-			snd_soc_dapm_new_dai_widgets(&platform->dapm, dai);
+			snd_soc_dapm_new_dai_widgets(&platform->component.dapm,
+				dai);
 	}
 
-	platform->dapm.idle_bias_off = 1;
+	platform->component.dapm.idle_bias_off = 1;
 
 	if (driver->probe) {
 		ret = driver->probe(platform);
@@ -1244,13 +1245,13 @@ static int soc_probe_platform(struct snd_soc_card *card,
 		snd_soc_add_platform_controls(platform, driver->controls,
 				     driver->num_controls);
 	if (driver->dapm_routes)
-		snd_soc_dapm_add_routes(&platform->dapm, driver->dapm_routes,
-					driver->num_dapm_routes);
+		snd_soc_dapm_add_routes(&platform->component.dapm,
+			driver->dapm_routes, driver->num_dapm_routes);
 
 	/* mark platform as probed and add to card platform list */
 	platform->probed = 1;
 	list_add(&platform->card_list, &card->platform_dev_list);
-	list_add(&platform->dapm.list, &card->dapm_list);
+	list_add(&platform->component.dapm.list, &card->dapm_list);
 
 	return 0;
 
@@ -4141,8 +4142,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 {
 	int ret;
 
-	platform->component.dapm_ptr = &platform->dapm;
-
 	ret = snd_soc_component_initialize(&platform->component,
 			&platform_drv->component_driver, dev);
 	if (ret)
@@ -4150,8 +4149,8 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 
 	platform->dev = dev;
 	platform->driver = platform_drv;
-	platform->dapm.platform = platform;
-	platform->dapm.stream_event = platform_drv->stream_event;
+	platform->component.dapm.platform = platform;
+	platform->component.dapm.stream_event = platform_drv->stream_event;
 	if (platform_drv->write)
 		platform->component.write = snd_soc_platform_drv_write;
 	if (platform_drv->read)
-- 
1.8.0

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

* [PATCH v2 08/11] ASoC: Add component level stream_event() and seq_notifier() support
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (6 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 07/11] ASoC: Use component DAPM context for platforms Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:35   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 09/11] ASoC: Add component level set_bias_level() support Lars-Peter Clausen
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

This patch adds stream_event() and seq_notifier() callbacks similar to those
found in the snd_soc_codec_driver and snd_soc_platform driver struct to the
snd_soc_component_driver struct. This is meant to unify the handling of these
callbacks across different types of components and will eventually allow their
removal from the CODEC and platfrom driver structs.

The new callbacks are slightly different from the old ones in that they take a
snd_soc_component as a parameter rather than a snd_soc_dapm_context. This was
done since otherwise casting from the DAPM context to the component would
typically be the first thing to do in the callback. And the interface becomes
slightly cleaner by passing a snd_soc_component to all callbacks in the
snd_soc_component_driver struct.

The patch also already removes the stream_event() callback from the
snd_soc_codec_driver and snd_soc_platform_driver structs as it is currently
unused.

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

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 84ebc07..9a5b4f6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -677,6 +677,9 @@ struct snd_soc_component_driver {
 	int (*of_xlate_dai_name)(struct snd_soc_component *component,
 				 struct of_phandle_args *args,
 				 const char **dai_name);
+	void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
+		int subseq);
+	int (*stream_event)(struct snd_soc_component *, int event);
 };
 
 struct snd_soc_component {
@@ -792,9 +795,6 @@ struct snd_soc_codec_driver {
 	void (*seq_notifier)(struct snd_soc_dapm_context *,
 			     enum snd_soc_dapm_type, int);
 
-	/* codec stream completion event */
-	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
-
 	bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
 
 	/* probe ordering - for components with runtime dependencies */
@@ -836,9 +836,6 @@ struct snd_soc_platform_driver {
 	/* platform stream compress ops */
 	const struct snd_compr_ops *compr_ops;
 
-	/* platform stream completion event */
-	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
-
 	/* probe ordering - for components with runtime dependencies */
 	int probe_order;
 	int remove_order;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 711e99c..5fe732f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3995,6 +3995,22 @@ err:
 	return ret;
 }
 
+static void snd_soc_component_seq_notifier(struct snd_soc_dapm_context *dapm,
+	enum snd_soc_dapm_type type, int subseq)
+{
+	struct snd_soc_component *component = dapm->component;
+
+	component->driver->seq_notifier(component, type, subseq);
+}
+
+static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
+	int event)
+{
+	struct snd_soc_component *component = dapm->component;
+
+	return component->driver->stream_event(component, event);
+}
+
 static int snd_soc_component_initialize(struct snd_soc_component *component,
 	const struct snd_soc_component_driver *driver, struct device *dev)
 {
@@ -4016,6 +4032,10 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	dapm->dev = dev;
 	dapm->component = component;
 	dapm->bias_level = SND_SOC_BIAS_OFF;
+	if (driver->seq_notifier)
+		dapm->seq_notifier = snd_soc_component_seq_notifier;
+	if (driver->stream_event)
+		dapm->stream_event = snd_soc_component_stream_event;
 
 	INIT_LIST_HEAD(&component->dai_list);
 	mutex_init(&component->io_mutex);
@@ -4150,7 +4170,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 	platform->dev = dev;
 	platform->driver = platform_drv;
 	platform->component.dapm.platform = platform;
-	platform->component.dapm.stream_event = platform_drv->stream_event;
 	if (platform_drv->write)
 		platform->component.write = snd_soc_platform_drv_write;
 	if (platform_drv->read)
@@ -4336,8 +4355,8 @@ int snd_soc_register_codec(struct device *dev,
 		codec->component.read = snd_soc_codec_drv_read;
 	codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
 	codec->dapm.codec = codec;
-	codec->dapm.seq_notifier = codec_drv->seq_notifier;
-	codec->dapm.stream_event = codec_drv->stream_event;
+	if (codec_drv->seq_notifier)
+		codec->dapm.seq_notifier = codec_drv->seq_notifier;
 	if (codec_drv->set_bias_level)
 		codec->dapm.set_bias_level = snd_soc_codec_set_bias_level;
 	codec->dev = dev;
-- 
1.8.0

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

* [PATCH v2 09/11] ASoC: Add component level set_bias_level() support
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (7 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 08/11] ASoC: Add component level stream_event() and seq_notifier() support Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:38   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 10/11] ASoC: dapm: Remove DAI DAPM context Lars-Peter Clausen
  2014-06-16 16:13 ` [PATCH v2 11/11] ASoC: dapm: Remove platform field from widget and dapm context struct Lars-Peter Clausen
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

This patch adds a set_bias_level() callback to the snd_soc_component_driver
struct similar to that found in the snd_soc_codec_driver struct. This will allow
any component type and not just CODECs to implement such a callback.

The semantics of the component driver and CODEC driver set_bias_level()
callbacks slightly differ. While the CODEC driver callback only takes the target
bias level, the component driver callback takes both the current and the target
bias level. Also for the component driver callback the current bias level will
be automatically updated to the target bias level if the callback does not
return an error, whereas with the CODEC bias level callback this has to be done
in every callback by hand. The change in semantics was implement because the new
semantics more closly match what drivers need. Most drivers are interested in
both the current and the target bias level and all drivers update the current to
the target bias level in case there is no error.

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

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 9a5b4f6..e560b6f 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -680,6 +680,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);
+	int (*set_bias_level)(struct snd_soc_component *component,
+		enum snd_soc_bias_level current_level,
+		enum snd_soc_bias_level target_level);
+	bool idle_bias_off;
 };
 
 struct snd_soc_component {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 5fe732f..a414689 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4011,6 +4011,20 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
 	return component->driver->stream_event(component, event);
 }
 
+static int snd_soc_component_set_bias_level(struct snd_soc_dapm_context *dapm,
+	enum snd_soc_bias_level target_level)
+{
+	struct snd_soc_component *component = dapm->component;
+	int ret;
+
+	ret = component->driver->set_bias_level(component, dapm->bias_level,
+		target_level);
+	if (ret == 0)
+		dapm->bias_level = target_level;
+
+	return ret;
+}
+
 static int snd_soc_component_initialize(struct snd_soc_component *component,
 	const struct snd_soc_component_driver *driver, struct device *dev)
 {
@@ -4032,10 +4046,13 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	dapm->dev = dev;
 	dapm->component = component;
 	dapm->bias_level = SND_SOC_BIAS_OFF;
+	dapm->idle_bias_off = driver->idle_bias_off;
 	if (driver->seq_notifier)
 		dapm->seq_notifier = snd_soc_component_seq_notifier;
 	if (driver->stream_event)
 		dapm->stream_event = snd_soc_component_stream_event;
+	if (driver->set_bias_level)
+		dapm->set_bias_level = snd_soc_component_set_bias_level;
 
 	INIT_LIST_HEAD(&component->dai_list);
 	mutex_init(&component->io_mutex);
-- 
1.8.0

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

* [PATCH v2 10/11] ASoC: dapm: Remove DAI DAPM context
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (8 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 09/11] ASoC: Add component level set_bias_level() support Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:36   ` Mark Brown
  2014-06-16 16:13 ` [PATCH v2 11/11] ASoC: dapm: Remove platform field from widget and dapm context struct Lars-Peter Clausen
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

The DAI DAPM context was added in commit be09ad90 ("ASoC: core: Add platform DAI
widget mapping") and the only user was removed again in commit ae10e7e8f ("ASoC:
core: Only add platform DAI widgets once."). Now that we have a per component
DAPM context it is unlikely that we'll need the DAI DAPM context again.

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

diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 688f2ba..031be2a 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -257,7 +257,6 @@ struct snd_soc_dai {
 
 	struct snd_soc_dapm_widget *playback_widget;
 	struct snd_soc_dapm_widget *capture_widget;
-	struct snd_soc_dapm_context dapm;
 
 	/* DAI DMA data */
 	void *playback_dma_data;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a414689..19dfa80 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1048,11 +1048,8 @@ 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) {
-			snd_soc_dapm_free(&cpu_dai->dapm);
+		if (!cpu_dai->codec)
 			module_put(cpu_dai->dev->driver->owner);
-		}
 	}
 }
 
@@ -1510,11 +1507,8 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
 	if (!cpu_dai->probed &&
 			cpu_dai->driver->probe_order == order) {
 		if (!cpu_dai->codec) {
-			cpu_dai->dapm.card = card;
 			if (!try_module_get(cpu_dai->dev->driver->owner))
 				return -ENODEV;
-
-			list_add(&cpu_dai->dapm.list, &card->dapm_list);
 		}
 
 		if (cpu_dai->driver->probe) {
@@ -3975,13 +3969,9 @@ static int snd_soc_register_dais(struct snd_soc_component *component,
 		dai->component = component;
 		dai->dev = dev;
 		dai->driver = &dai_drv[i];
-		dai->dapm.dev = dev;
 		if (!dai->driver->ops)
 			dai->driver->ops = &null_dai_ops;
 
-		if (!dai->codec)
-			dai->dapm.idle_bias_off = 1;
-
 		list_add(&dai->list, &component->dai_list);
 
 		dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
-- 
1.8.0

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

* [PATCH v2 11/11] ASoC: dapm: Remove platform field from widget and dapm context struct
  2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
                   ` (9 preceding siblings ...)
  2014-06-16 16:13 ` [PATCH v2 10/11] ASoC: dapm: Remove DAI DAPM context Lars-Peter Clausen
@ 2014-06-16 16:13 ` Lars-Peter Clausen
  2014-06-21 20:36   ` Mark Brown
  10 siblings, 1 reply; 28+ messages in thread
From: Lars-Peter Clausen @ 2014-06-16 16:13 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Lars-Peter Clausen

The platform field in the snd_soc_dapm_widget and snd_soc_dapm_context structs
is now unused can be removed. New code that wants to get the platform for a
widget or dapm context should use snd_soc_dapm_to_platform(w->dapm) or
snd_soc_dapm_to_platform(dapm).

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

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index e292683..aac04ff 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -526,7 +526,6 @@ struct snd_soc_dapm_widget {
 	const char *name;		/* widget name */
 	const char *sname;	/* stream name */
 	struct snd_soc_codec *codec;
-	struct snd_soc_platform *platform;
 	struct list_head list;
 	struct snd_soc_dapm_context *dapm;
 
@@ -595,7 +594,6 @@ struct snd_soc_dapm_context {
 	struct device *dev; /* from parent - for debug */
 	struct snd_soc_component *component; /* parent component */
 	struct snd_soc_codec *codec; /* parent codec */
-	struct snd_soc_platform *platform; /* parent platform */
 	struct snd_soc_card *card; /* parent card */
 
 	/* used during DAPM updates */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 19dfa80..7ad4838 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4176,7 +4176,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 
 	platform->dev = dev;
 	platform->driver = platform_drv;
-	platform->component.dapm.platform = platform;
 	if (platform_drv->write)
 		platform->component.write = snd_soc_platform_drv_write;
 	if (platform_drv->read)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 4702b92..4bf08cf 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3097,7 +3097,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 
 	w->dapm = dapm;
 	w->codec = dapm->codec;
-	w->platform = dapm->platform;
 	INIT_LIST_HEAD(&w->sources);
 	INIT_LIST_HEAD(&w->sinks);
 	INIT_LIST_HEAD(&w->list);
-- 
1.8.0

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

* Re: [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component
  2014-06-16 16:13 ` [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component Lars-Peter Clausen
@ 2014-06-21 20:03   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:03 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:01PM +0200, Lars-Peter Clausen wrote:
> Move the name_prefix from the CODEC struct to the component struct. This will
> eventually allow to specify prefixes for all types of components. It is also
> necessary to make the DAPM code component type independent (i.e. a DAPM context
> does not need to know whether it belongs to a CODEC or a platform or something
> else).

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 02/11] ASoC: Move name and id from CODEC/platform to component
  2014-06-16 16:13 ` [PATCH v2 02/11] ASoC: Move name and id from CODEC/platform " Lars-Peter Clausen
@ 2014-06-21 20:04   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:04 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:02PM +0200, Lars-Peter Clausen wrote:
> The component struct already has a name and id field which are initialized to
> the same values as the same fields in the CODEC and platform structs. So remove
> them from the CODEC and platform structs and used the ones from the component
> struct instead.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 03/11] ASoC: Split component registration into two steps
  2014-06-16 16:13 ` [PATCH v2 03/11] ASoC: Split component registration into two steps Lars-Peter Clausen
@ 2014-06-21 20:05   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:05 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:03PM +0200, Lars-Peter Clausen wrote:
> Split snd_soc_component_register() into snd_soc_component_initialize() and
> snd_soc_component_add(). Using a 2-stage registration approach has the advantage
> that it is possible to modify the component after it has been initialized, but
> before it is made visible to the system. This e.g. allows CODECs or platforms to
> overwrite some of the default settings made in snd_soc_component_initialize().

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 04/11] ASoC: Auto disconnect pins from all DAPM contexts
  2014-06-16 16:13 ` [PATCH v2 04/11] ASoC: Auto disconnect pins from all DAPM contexts Lars-Peter Clausen
@ 2014-06-21 20:07   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:07 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:04PM +0200, Lars-Peter Clausen wrote:
> Currently only pins in CODEC DAPM contexts are automatically marked as
> non-connected if the card has the fully_routed flag set. This makes sense since
> widgets which qualify for auto-disconnection are only found in CODEC DAPM
> contexts. But with componentisation this is going to change, so consider all
> widgets for auto-disconnection.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-16 16:13 ` [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct Lars-Peter Clausen
@ 2014-06-21 20:14   ` Mark Brown
  2014-06-22  5:26     ` Vinod Koul
  2014-06-21 20:34   ` Mark Brown
  1 sibling, 1 reply; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:14 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:05PM +0200, Lars-Peter Clausen wrote:

> CODEC specific set_bias_level callback(). Not looking directly at the CODEC
> driver struct will allow non CODEC DAPM contexts to implement a set_bias_level()
> callback.

It will indeed, but do we want them to?  set_bias_level() is partly
legacy and partly there for the benefit of analogue devices which can
have more complex needs than digital ones which can mostly just use
runtime PM.  On the other hand there's a consistency thing going on
here, but that applies both within ASoC and throughout the kernel.

[-- 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] 28+ messages in thread

* Re: [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-16 16:13 ` [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct Lars-Peter Clausen
  2014-06-21 20:14   ` Mark Brown
@ 2014-06-21 20:34   ` Mark Brown
  1 sibling, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:34 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:05PM +0200, Lars-Peter Clausen wrote:
> Currently the DAPM code directly looks at the CODEC driver struct to get a
> handle to the set_bias_level() callback. This patch adds a new set_bias_level()
> callback to the DAPM context struct. The DAPM code will use this new callback
> instead of the CODEC callback. For CODECs the new callback is set up to call the
> CODEC specific set_bias_level callback(). Not looking directly at the CODEC
> driver struct will allow non CODEC DAPM contexts to implement a set_bias_level()
> callback.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 06/11] ASoC: Add DAPM support at the component level
  2014-06-16 16:13 ` [PATCH v2 06/11] ASoC: Add DAPM support at the component level Lars-Peter Clausen
@ 2014-06-21 20:34   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:34 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:06PM +0200, Lars-Peter Clausen wrote:
> This patch adds full DAPM support at the component level. Previously there was
> only full DAPM support for CODECs and partial DAPM support (e.g. no Mixers nor
> MUXs) for platforms. Having DAPM support at the component level will allow all
> types of components to use DAPM and also help in consolidating the DAPM support
> between CODECs and platforms.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 07/11] ASoC: Use component DAPM context for platforms
  2014-06-16 16:13 ` [PATCH v2 07/11] ASoC: Use component DAPM context for platforms Lars-Peter Clausen
@ 2014-06-21 20:34   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:34 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:07PM +0200, Lars-Peter Clausen wrote:
> The snd_soc_platform dapm field is not accessed outside of the ASoC core. Switch
> it over to using the snd_soc_component DAPM context.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 08/11] ASoC: Add component level stream_event() and seq_notifier() support
  2014-06-16 16:13 ` [PATCH v2 08/11] ASoC: Add component level stream_event() and seq_notifier() support Lars-Peter Clausen
@ 2014-06-21 20:35   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:35 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:08PM +0200, Lars-Peter Clausen wrote:
> This patch adds stream_event() and seq_notifier() callbacks similar to those
> found in the snd_soc_codec_driver and snd_soc_platform driver struct to the
> snd_soc_component_driver struct. This is meant to unify the handling of these
> callbacks across different types of components and will eventually allow their
> removal from the CODEC and platfrom driver structs.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 10/11] ASoC: dapm: Remove DAI DAPM context
  2014-06-16 16:13 ` [PATCH v2 10/11] ASoC: dapm: Remove DAI DAPM context Lars-Peter Clausen
@ 2014-06-21 20:36   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:36 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:10PM +0200, Lars-Peter Clausen wrote:
> The DAI DAPM context was added in commit be09ad90 ("ASoC: core: Add platform DAI
> widget mapping") and the only user was removed again in commit ae10e7e8f ("ASoC:
> core: Only add platform DAI widgets once."). Now that we have a per component
> DAPM context it is unlikely that we'll need the DAI DAPM context again.

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 11/11] ASoC: dapm: Remove platform field from widget and dapm context struct
  2014-06-16 16:13 ` [PATCH v2 11/11] ASoC: dapm: Remove platform field from widget and dapm context struct Lars-Peter Clausen
@ 2014-06-21 20:36   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:36 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:11PM +0200, Lars-Peter Clausen wrote:
> The platform field in the snd_soc_dapm_widget and snd_soc_dapm_context structs
> is now unused can be removed. New code that wants to get the platform for a
> widget or dapm context should use snd_soc_dapm_to_platform(w->dapm) or
> snd_soc_dapm_to_platform(dapm).

Applied, 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] 28+ messages in thread

* Re: [PATCH v2 09/11] ASoC: Add component level set_bias_level() support
  2014-06-16 16:13 ` [PATCH v2 09/11] ASoC: Add component level set_bias_level() support Lars-Peter Clausen
@ 2014-06-21 20:38   ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-21 20:38 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Vinod Koul, alsa-devel, Liam Girdwood


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

On Mon, Jun 16, 2014 at 06:13:09PM +0200, Lars-Peter Clausen wrote:
> This patch adds a set_bias_level() callback to the snd_soc_component_driver
> struct similar to that found in the snd_soc_codec_driver struct. This will allow
> any component type and not just CODECs to implement such a callback.

So, as I said on the previous patch I'm not 100% sure about this one.
On balance I think the symmetry argument wins out so it should go in
even if people ought not to be using it but I want to think it over a
little more.

[-- 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] 28+ messages in thread

* Re: [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-21 20:14   ` Mark Brown
@ 2014-06-22  5:26     ` Vinod Koul
  2014-06-22 10:12       ` Mark Brown
  0 siblings, 1 reply; 28+ messages in thread
From: Vinod Koul @ 2014-06-22  5:26 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Lars-Peter Clausen, Liam Girdwood


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

On Sat, Jun 21, 2014 at 09:14:37PM +0100, Mark Brown wrote:
> On Mon, Jun 16, 2014 at 06:13:05PM +0200, Lars-Peter Clausen wrote:
> 
> > CODEC specific set_bias_level callback(). Not looking directly at the CODEC
> > driver struct will allow non CODEC DAPM contexts to implement a set_bias_level()
> > callback.
> 
> It will indeed, but do we want them to?  set_bias_level() is partly
> legacy and partly there for the benefit of analogue devices which can
> have more complex needs than digital ones which can mostly just use
> runtime PM.  On the other hand there's a consistency thing going on
> here, but that applies both within ASoC and throughout the kernel.
I think it would help :)

Even on DSPs loading firmware and power sequencing the DSP can get some help
using these functions

I think I might find some use of this for my work!

-- 
~Vinod

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

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



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

* Re: [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-22  5:26     ` Vinod Koul
@ 2014-06-22 10:12       ` Mark Brown
  2014-06-23  4:34         ` Vinod Koul
  0 siblings, 1 reply; 28+ messages in thread
From: Mark Brown @ 2014-06-22 10:12 UTC (permalink / raw)
  To: Vinod Koul; +Cc: alsa-devel, Lars-Peter Clausen, Liam Girdwood


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

On Sun, Jun 22, 2014 at 10:56:00AM +0530, Vinod Koul wrote:

> Even on DSPs loading firmware and power sequencing the DSP can get some help
> using these functions

> I think I might find some use of this for my work!

Please be more specific about this - what do they offer that runtime PM
and widgets don't offer?

[-- 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] 28+ messages in thread

* Re: [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-22 10:12       ` Mark Brown
@ 2014-06-23  4:34         ` Vinod Koul
  2014-06-23 10:08           ` Mark Brown
  0 siblings, 1 reply; 28+ messages in thread
From: Vinod Koul @ 2014-06-23  4:34 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Lars-Peter Clausen, Liam Girdwood


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

On Sun, Jun 22, 2014 at 11:12:36AM +0100, Mark Brown wrote:
> On Sun, Jun 22, 2014 at 10:56:00AM +0530, Vinod Koul wrote:
> 
> > Even on DSPs loading firmware and power sequencing the DSP can get some help
> > using these functions
> 
> > I think I might find some use of this for my work!
> 
> Please be more specific about this - what do they offer that runtime PM
> and widgets don't offer?
Well you are assuming that folks writing DSP FW will not have some wiered
sequence!

Neverthless, i can think of two scenarios to control fw loading and sequences:

1. DMICs attached to DSP doing record but data getting consumed by DSP. No data
goes to host cpu. No PCM/parameters here, so we can do a simple Input-Output
loop. Somthing reverse of what we can do with Codec vibra. Widgets will not tell
me when to load DSP FW. Since no device handle, no runtime here!

2. SoC DSP generating clock for codec and audio ICs even when no data is
generated by SoC. This is not true for I2S but for other bus prtocols like
Slimbus.

Thanks
-- 
~Vinod

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

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



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

* Re: [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct
  2014-06-23  4:34         ` Vinod Koul
@ 2014-06-23 10:08           ` Mark Brown
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Brown @ 2014-06-23 10:08 UTC (permalink / raw)
  To: Vinod Koul; +Cc: alsa-devel, Lars-Peter Clausen, Liam Girdwood


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

On Mon, Jun 23, 2014 at 10:04:05AM +0530, Vinod Koul wrote:
> On Sun, Jun 22, 2014 at 11:12:36AM +0100, Mark Brown wrote:

> > Please be more specific about this - what do they offer that runtime PM
> > and widgets don't offer?

> Well you are assuming that folks writing DSP FW will not have some wiered
> sequence!

> Neverthless, i can think of two scenarios to control fw loading and sequences:

> 1. DMICs attached to DSP doing record but data getting consumed by DSP. No data
> goes to host cpu. No PCM/parameters here, so we can do a simple Input-Output
> loop. Somthing reverse of what we can do with Codec vibra. Widgets will not tell
> me when to load DSP FW. Since no device handle, no runtime here!

Why not?  If there's a DAPM context there must be a struct device for
it and if there's an audio path there should be widgets on it.

> 2. SoC DSP generating clock for codec and audio ICs even when no data is
> generated by SoC. This is not true for I2S but for other bus prtocols like
> Slimbus.

This sounds like something runtime PM would work fine for?

[-- 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] 28+ messages in thread

end of thread, other threads:[~2014-06-23 10:08 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-16 16:13 [PATCH v2 00/11] ASoC: Add support for DAPM at the component level Lars-Peter Clausen
2014-06-16 16:13 ` [PATCH v2 01/11] ASoC: Move name_prefix from CODEC to component Lars-Peter Clausen
2014-06-21 20:03   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 02/11] ASoC: Move name and id from CODEC/platform " Lars-Peter Clausen
2014-06-21 20:04   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 03/11] ASoC: Split component registration into two steps Lars-Peter Clausen
2014-06-21 20:05   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 04/11] ASoC: Auto disconnect pins from all DAPM contexts Lars-Peter Clausen
2014-06-21 20:07   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 05/11] ASoC: Add a set_bias_level() callback to the DAPM context struct Lars-Peter Clausen
2014-06-21 20:14   ` Mark Brown
2014-06-22  5:26     ` Vinod Koul
2014-06-22 10:12       ` Mark Brown
2014-06-23  4:34         ` Vinod Koul
2014-06-23 10:08           ` Mark Brown
2014-06-21 20:34   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 06/11] ASoC: Add DAPM support at the component level Lars-Peter Clausen
2014-06-21 20:34   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 07/11] ASoC: Use component DAPM context for platforms Lars-Peter Clausen
2014-06-21 20:34   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 08/11] ASoC: Add component level stream_event() and seq_notifier() support Lars-Peter Clausen
2014-06-21 20:35   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 09/11] ASoC: Add component level set_bias_level() support Lars-Peter Clausen
2014-06-21 20:38   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 10/11] ASoC: dapm: Remove DAI DAPM context Lars-Peter Clausen
2014-06-21 20:36   ` Mark Brown
2014-06-16 16:13 ` [PATCH v2 11/11] ASoC: dapm: Remove platform field from widget and dapm context struct Lars-Peter Clausen
2014-06-21 20:36   ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.