[alsa-devel] [PATCH 7/7] ASoC: Instantiate all DAPM widgets at once

Lars-Peter Clausen lars at metafoo.de
Thu Apr 28 18:46:13 CEST 2011


Currently after each codec or auxdev has been probed its DAPM widgets are
instantiated.

Since widgets are kept in a per card list and routes can interconnect between
widgets from different DAPM contexts on the same card it is possible that
snd_soc_dapm_new_widgets is run on an incomplete DAPM configuration which might
cause unnecessary register writes and/or cause audible problems.

This patch addresses the issue by instantiating all widgets from all DAPM contexts
after all components of the card have been initialized.

Signed-off-by: Lars-Peter Clausen <lars at metafoo.de>
---
 include/sound/soc-dapm.h |   16 +++++++++++++++-
 sound/soc/soc-core.c     |    5 ++---
 sound/soc/soc-dapm.c     |   29 ++++++++++++++---------------
 3 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 9679c18..5666c3e 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -344,7 +344,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
 	int num);
 
 /* dapm path setup */
-int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_card_new_widgets(struct snd_soc_card *card);
 void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
 int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
 			    const struct snd_soc_dapm_route *route, int num);
@@ -515,4 +515,18 @@ struct snd_soc_dapm_context {
 #endif
 };
 
+/*
+ * snd_soc_dapm_new_widgets - add new dapm widgets
+ * @dapm: DAPM context
+ *
+ * Checks the DAPM context's card for any new dapm widgets and creates them if
+ * found.
+ *
+ * Returns 0 for success.
+ */
+static inline int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
+{
+	return snd_soc_dapm_card_new_widgets(dapm->card);
+}
+
 #endif
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c30fa9d..ea38e0a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1567,9 +1567,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
 	}
 	codec->name_prefix = temp;
 
-	/* Make sure all DAPM widgets are instantiated */
-	snd_soc_dapm_new_widgets(&codec->dapm);
-
 	/* register the rtd device */
 	rtd->codec = codec;
 	rtd->dev.parent = card->dev;
@@ -1935,6 +1932,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 			goto probe_aux_dev_err;
 		}
 	}
+	/* Make sure all DAPM widgets are instantiated */
+	snd_soc_dapm_card_new_widgets(card);
 
 	ret = snd_card_register(card->snd_card);
 	if (ret < 0) {
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index e3c5d36..46e396c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -323,9 +323,9 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
 }
 
 /* create new dapm mixer control */
-static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
-	struct snd_soc_dapm_widget *w)
+static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
 {
+	struct snd_soc_dapm_context *dapm = w->dapm;
 	int i, ret = 0;
 	size_t name_len, prefix_len;
 	struct snd_soc_dapm_path *path;
@@ -404,9 +404,9 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
 }
 
 /* create new dapm mux control */
-static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
-	struct snd_soc_dapm_widget *w)
+static int dapm_new_mux(struct snd_soc_dapm_widget *w)
 {
+	struct snd_soc_dapm_context *dapm = w->dapm;
 	struct snd_soc_dapm_path *path = NULL;
 	struct snd_kcontrol *kcontrol;
 	struct snd_card *card = dapm->card->snd_card;
@@ -451,8 +451,7 @@ err:
 }
 
 /* create new dapm volume control */
-static int dapm_new_pga(struct snd_soc_dapm_context *dapm,
-	struct snd_soc_dapm_widget *w)
+static int dapm_new_pga(struct snd_soc_dapm_widget *w)
 {
 	if (w->num_kcontrols)
 		dev_err(w->dapm->dev,
@@ -1679,19 +1678,19 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
 EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
 
 /**
- * snd_soc_dapm_new_widgets - add new dapm widgets
- * @dapm: DAPM context
+ * snd_soc_dapm_card_new_widgets - add new dapm widgets
+ * @card: Card to check for new widgets
  *
- * Checks the codec for any new dapm widgets and creates them if found.
+ * Checks the card for any new dapm widgets and creates them if found.
  *
  * Returns 0 for success.
  */
-int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
+int snd_soc_dapm_card_new_widgets(struct snd_soc_card *card)
 {
 	struct snd_soc_dapm_widget *w;
 	unsigned int val;
 
-	list_for_each_entry(w, &dapm->card->widgets, list)
+	list_for_each_entry(w, &card->widgets, list)
 	{
 		if (w->new)
 			continue;
@@ -1701,13 +1700,13 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
 		case snd_soc_dapm_mixer:
 		case snd_soc_dapm_mixer_named_ctl:
 			w->power_check = dapm_generic_check_power;
-			dapm_new_mixer(dapm, w);
+			dapm_new_mixer(w);
 			break;
 		case snd_soc_dapm_mux:
 		case snd_soc_dapm_virt_mux:
 		case snd_soc_dapm_value_mux:
 			w->power_check = dapm_generic_check_power;
-			dapm_new_mux(dapm, w);
+			dapm_new_mux(w);
 			break;
 		case snd_soc_dapm_adc:
 		case snd_soc_dapm_aif_out:
@@ -1720,7 +1719,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
 		case snd_soc_dapm_pga:
 		case snd_soc_dapm_out_drv:
 			w->power_check = dapm_generic_check_power;
-			dapm_new_pga(dapm, w);
+			dapm_new_pga(w);
 			break;
 		case snd_soc_dapm_input:
 		case snd_soc_dapm_output:
@@ -1755,7 +1754,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
 		dapm_debugfs_add_widget(w);
 	}
 
-	dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP, NULL);
+	dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, NULL);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
-- 
1.7.2.5



More information about the Alsa-devel mailing list