[alsa-devel] [RFC v2 1/3] ASoC: core: DAPM widget flag for reversed power up sequence

Peter Ujfalusi peter.ujfalusi at nokia.com
Fri Dec 3 14:31:11 CET 2010


New flag indicating, that the DAPM widget needs different
power up sequence.
Certain codecs can generate pop noise, when for example enabling the bypass
path.
The route cause in these codecs are the DAPM update power and register write
sequence:
1. User enable the bypass
2. DAPM power up sequence takes place
2.1 codec DAPM widgets got powered on, codec is enabled
2.2 External speaker enabled
3. The bit enabling the bypass got changed.

Step 3 can cause audible pop on the speaker.

By introducing new flag for the widget (route_change_before_powerup),
reordered power up sequence can be requesetd, which will look like this:

1. User enable the bypass
2. The bit enabling the bypass got changed.
3. DAPM power up sequence takes place
3.1 codec DAPM widgets got powered on, codec is enabled
3.2 External speaker enabled

The pop noise going to be filtered out, since the speaker going to be enabled
after the bit change taken place.

With the flag only the power up sequence can be changed, the power down
sequence remains the same.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at nokia.com>
---
 include/sound/soc-dapm.h |    1 +
 sound/soc/soc-dapm.c     |   17 +++++++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 041e98b..e5a3c74 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -447,6 +447,7 @@ struct snd_soc_dapm_widget {
 	unsigned char ext:1;			/* has external widgets */
 	unsigned char force:1;			/* force state */
 	unsigned char ignore_suspend:1;         /* kept enabled over suspend */
+	unsigned char route_change_before_powerup:1;	/* reveresed power up */
 
 	int (*power_check)(struct snd_soc_dapm_widget *w);
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 6a29d59..7fae969 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1626,8 +1626,9 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned int val, val2, val_mask;
+	unsigned int update_power_first = 1;
 	int connect;
-	int ret;
+	int ret = 0;
 
 	val = (ucontrol->value.integer.value[0] & mask);
 
@@ -1653,9 +1654,16 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 		else
 			/* old connection must be powered down */
 			connect = invert ? 1:0;
+	} else {
+		goto out;
+	}
+
+	if (widget->route_change_before_powerup && connect)
+		/* Reordering the power up sequence  */
+		update_power_first = 0;
 
+	if (update_power_first)
 		dapm_mixer_update_power(widget, kcontrol, connect);
-	}
 
 	if (widget->event) {
 		if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
@@ -1673,6 +1681,11 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	} else
 		ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
 
+	if (ret < 0)
+		goto out;
+
+	if (!update_power_first)
+		dapm_mixer_update_power(widget, kcontrol, connect);
 out:
 	mutex_unlock(&widget->codec->mutex);
 	return ret;
-- 
1.7.3.2



More information about the Alsa-devel mailing list