alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] ASoC: dapm: Add support for virtual mixer controls
@ 2013-10-06 11:43 Lars-Peter Clausen
  2013-10-06 11:43 ` [PATCH 2/3] ASoC: twl4030: Use virtual DAPM " Lars-Peter Clausen
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Lars-Peter Clausen @ 2013-10-06 11:43 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood, Peter Ujfalusi; +Cc: alsa-devel, Lars-Peter Clausen

This patch adds support for virtual DAPM mixer controls. They are similar to
virtual DAPM enums. There is no hardware register backing the control, so
changing the control's value wont have any direct effect on the hardware. But it
still influences the DAPM graph by causing the path it sits on to be connected
or disconnected. This in turn can cause power changes for some of the widgets on
the DAPM graph, which will then modify the hardware state.

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

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 27a72d5..2037c45 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -286,6 +286,8 @@ struct device;
 	.info = snd_soc_info_volsw, \
 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
 	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
+#define SOC_DAPM_SINGLE_VIRT(xname, max) \
+	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0)
 #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 	.info = snd_soc_info_volsw, \
@@ -300,6 +302,8 @@ struct device;
 	.tlv.p = (tlv_array), \
 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
 	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
+#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \
+	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array)
 #define SOC_DAPM_ENUM(xname, xenum) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 	.info = snd_soc_info_enum_double, \
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6dd329a..af1678c 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1049,7 +1049,8 @@ struct snd_soc_pcm_runtime {
 /* mixer control */
 struct soc_mixer_control {
 	int min, max, platform_max;
-	unsigned int reg, rreg, shift, rshift;
+	int reg, rreg;
+	unsigned int shift, rshift;
 	unsigned int invert:1;
 	unsigned int autodisable:1;
 };
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index c17c14c..25b9554 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -499,18 +499,22 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
 		int val;
 		struct soc_mixer_control *mc = (struct soc_mixer_control *)
 			w->kcontrol_news[i].private_value;
-		unsigned int reg = mc->reg;
+		int reg = mc->reg;
 		unsigned int shift = mc->shift;
 		int max = mc->max;
 		unsigned int mask = (1 << fls(max)) - 1;
 		unsigned int invert = mc->invert;
 
-		val = soc_widget_read(w, reg);
-		val = (val >> shift) & mask;
-		if (invert)
-			val = max - val;
+		if (reg != SND_SOC_NOPM) {
+			val = soc_widget_read(w, reg);
+			val = (val >> shift) & mask;
+			if (invert)
+				val = max - val;
+			p->connect = !!val;
+		} else {
+			p->connect = 0;
+		}
 
-		p->connect = !!val;
 	}
 	break;
 	case snd_soc_dapm_mux: {
@@ -2791,7 +2795,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_soc_card *card = codec->card;
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	unsigned int reg = mc->reg;
+	int reg = mc->reg;
 	unsigned int shift = mc->shift;
 	int max = mc->max;
 	unsigned int mask = (1 << fls(max)) - 1;
@@ -2804,7 +2808,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
 			 kcontrol->id.name);
 
 	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
-	if (dapm_kcontrol_is_powered(kcontrol))
+	if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM)
 		val = (snd_soc_read(codec, reg) >> shift) & mask;
 	else
 		val = dapm_kcontrol_get_value(kcontrol);
@@ -2835,7 +2839,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_soc_card *card = codec->card;
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
-	unsigned int reg = mc->reg;
+	int reg = mc->reg;
 	unsigned int shift = mc->shift;
 	int max = mc->max;
 	unsigned int mask = (1 << fls(max)) - 1;
@@ -2857,19 +2861,24 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 
 	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
 
-	dapm_kcontrol_set_value(kcontrol, val);
+	change = dapm_kcontrol_set_value(kcontrol, val);
 
-	mask = mask << shift;
-	val = val << shift;
+	if (reg != SND_SOC_NOPM) {
+		mask = mask << shift;
+		val = val << shift;
+
+		change = snd_soc_test_bits(codec, reg, mask, val);
+	}
 
-	change = snd_soc_test_bits(codec, reg, mask, val);
 	if (change) {
-		update.kcontrol = kcontrol;
-		update.reg = reg;
-		update.mask = mask;
-		update.val = val;
+		if (reg != SND_SOC_NOPM) {
+			update.kcontrol = kcontrol;
+			update.reg = reg;
+			update.mask = mask;
+			update.val = val;
 
-		card->update = &update;
+			card->update = &update;
+		}
 
 		soc_dapm_mixer_update_power(card, kcontrol, connect);
 
-- 
1.8.0

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

end of thread, other threads:[~2013-10-07 10:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-06 11:43 [PATCH 1/3] ASoC: dapm: Add support for virtual mixer controls Lars-Peter Clausen
2013-10-06 11:43 ` [PATCH 2/3] ASoC: twl4030: Use virtual DAPM " Lars-Peter Clausen
2013-10-07  9:07   ` Peter Ujfalusi
2013-10-07  9:09     ` Peter Ujfalusi
2013-10-07 10:50   ` Mark Brown
2013-10-06 11:43 ` [PATCH 3/3] ASoC: twl6040: " Lars-Peter Clausen
2013-10-07  9:07   ` Peter Ujfalusi
2013-10-07  9:11     ` Peter Ujfalusi
2013-10-07 10:49   ` Mark Brown
2013-10-07  9:10 ` [PATCH 1/3] ASoC: dapm: Add support for virtual " Peter Ujfalusi
2013-10-07 10:45 ` Mark Brown

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