All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
To: alsa-devel@alsa-project.org
Cc: Takashi Iwai <tiwai@suse.de>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	Liam Girdwood <lrg@ti.com>
Subject: [RFC/PATCH] ASoC: dapm: Fix/add support for stereo widgets
Date: Mon, 2 Jul 2012 13:46:42 +0200 (CEST)	[thread overview]
Message-ID: <134211720.502545.1341229602023.JavaMail.root@advansee.com> (raw)
In-Reply-To: <20120630182446.GA28922@opensource.wolfsonmicro.com>

This patch:
* adds a choice in snd_soc_dapm_get_volsw_mut() for stereo between 1 and 2
  registers, like in snd_soc_get_volsw().
* fixes the missing stereo in other parts of dapm.
* removes the unused saved_value from struct snd_soc_dapm_widget.

Cc: Liam Girdwood <lrg@ti.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: <alsa-devel@alsa-project.org>
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
---
 .../include/sound/soc-dapm.h                       |   10 +--
 .../sound/soc/soc-dapm.c                           |   92 ++++++++++++++++----
 2 files changed, 82 insertions(+), 20 deletions(-)

diff --git linux-next-HEAD-d1d2d3a.orig/include/sound/soc-dapm.h linux-next-HEAD-d1d2d3a/include/sound/soc-dapm.h
index 05559e5..b5d38b9 100644
--- linux-next-HEAD-d1d2d3a.orig/include/sound/soc-dapm.h
+++ linux-next-HEAD-d1d2d3a/include/sound/soc-dapm.h
@@ -508,8 +508,8 @@ struct snd_soc_dapm_widget {
 	/* dapm control */
 	int reg;				/* negative reg = no direct dapm */
 	unsigned char shift;			/* bits to shift */
-	unsigned int saved_value;		/* widget saved value */
-	unsigned int value;				/* widget current value */
+	unsigned int value;			/* widget current value */
+	unsigned int rvalue;			/* widget current value of right channel */
 	unsigned int mask;			/* non-shifted mask */
 	unsigned int on_val;			/* on state value */
 	unsigned int off_val;			/* off state value */
@@ -552,9 +552,9 @@ struct snd_soc_dapm_widget {
 struct snd_soc_dapm_update {
 	struct snd_soc_dapm_widget *widget;
 	struct snd_kcontrol *kcontrol;
-	int reg;
-	int mask;
-	int val;
+	int reg, rreg;
+	int mask, rmask;
+	int val, rval;
 };
 
 /* DAPM context */
diff --git linux-next-HEAD-d1d2d3a.orig/sound/soc/soc-dapm.c linux-next-HEAD-d1d2d3a/sound/soc/soc-dapm.c
index 7f2a4bb..341dade 100644
--- linux-next-HEAD-d1d2d3a.orig/sound/soc/soc-dapm.c
+++ linux-next-HEAD-d1d2d3a/sound/soc/soc-dapm.c
@@ -313,11 +313,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
 	case snd_soc_dapm_switch:
 	case snd_soc_dapm_mixer:
 	case snd_soc_dapm_mixer_named_ctl: {
-		int val;
+		int val, val2 = 0;
 		struct soc_mixer_control *mc = (struct soc_mixer_control *)
 			w->kcontrol_news[i].private_value;
 		unsigned int reg = mc->reg;
+		unsigned int reg2 = mc->rreg;
 		unsigned int shift = mc->shift;
+		unsigned int rshift = mc->rshift;
 		int max = mc->max;
 		unsigned int mask = (1 << fls(max)) - 1;
 		unsigned int invert = mc->invert;
@@ -327,7 +329,19 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
 		if (invert)
 			val = max - val;
 
-		p->connect = !!val;
+		if (snd_soc_volsw_is_stereo(mc)) {
+			if (reg == reg2) {
+				val2 = soc_widget_read(w, reg);
+				val2 = (val2 >> rshift) & mask;
+			} else {
+				val2 = soc_widget_read(w, reg2);
+				val2 = (val2 >> shift) & mask;
+			}
+			if (invert)
+				val2 = max - val2;
+		}
+
+		p->connect = val || val2;
 	}
 	break;
 	case snd_soc_dapm_mux: {
@@ -1397,6 +1411,14 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
 	if (ret < 0)
 		pr_err("%s DAPM update failed: %d\n", w->name, ret);
 
+	if (update->rmask) {
+		ret = soc_widget_update_bits_locked(w, update->rreg,
+					  update->rmask, update->rval);
+		if (ret < 0)
+			pr_err("%s DAPM right channel update failed: %d\n",
+			       w->name, ret);
+	}
+
 	if (w->event &&
 	    (w->event_flags & SND_SOC_DAPM_POST_REG)) {
 		ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
@@ -2462,21 +2484,29 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int reg = mc->reg;
+	unsigned int reg2 = mc->rreg;
 	unsigned int shift = mc->shift;
 	unsigned int rshift = mc->rshift;
 	int max = mc->max;
-	unsigned int invert = mc->invert;
 	unsigned int mask = (1 << fls(max)) - 1;
+	unsigned int invert = mc->invert;
 
 	ucontrol->value.integer.value[0] =
 		(snd_soc_read(widget->codec, reg) >> shift) & mask;
-	if (shift != rshift)
-		ucontrol->value.integer.value[1] =
-			(snd_soc_read(widget->codec, reg) >> rshift) & mask;
-	if (invert) {
+	if (invert)
 		ucontrol->value.integer.value[0] =
 			max - ucontrol->value.integer.value[0];
-		if (shift != rshift)
+
+	if (snd_soc_volsw_is_stereo(mc)) {
+		if (reg == reg2)
+			ucontrol->value.integer.value[1] =
+				(snd_soc_read(widget->codec, reg) >> rshift) &
+						mask;
+		else
+			ucontrol->value.integer.value[1] =
+				(snd_soc_read(widget->codec, reg2) >> shift) &
+						mask;
+		if (invert)
 			ucontrol->value.integer.value[1] =
 				max - ucontrol->value.integer.value[1];
 	}
@@ -2504,11 +2534,15 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	unsigned int reg = mc->reg;
+	unsigned int reg2 = mc->rreg;
 	unsigned int shift = mc->shift;
+	unsigned int rshift = mc->rshift;
 	int max = mc->max;
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
-	unsigned int val;
+	bool type_2r = 0;
+	unsigned int val2 = 0;
+	unsigned int val, val_mask;
 	int connect, change;
 	struct snd_soc_dapm_update update;
 	int wi;
@@ -2518,27 +2552,53 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 
 	if (invert)
 		val = max - val;
-	mask = mask << shift;
+	val_mask = mask << shift;
 	val = val << shift;
 
+	if (snd_soc_volsw_is_stereo(mc)) {
+		val2 = (ucontrol->value.integer.value[1] & mask);
+		connect |= !!val2;
+
+		if (invert)
+			val2 = max - val2;
+		if (reg == reg2) {
+			val_mask |= mask << rshift;
+			val |= val2 << rshift;
+		} else {
+			val2 = val2 << shift;
+			type_2r = 1;
+		}
+	}
+
 	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
 
-	change = snd_soc_test_bits(widget->codec, reg, mask, val);
+	change = snd_soc_test_bits(widget->codec, reg, val_mask, val);
+	if (type_2r)
+		change |= snd_soc_test_bits(widget->codec,
+					    reg2, val_mask, val2);
+
 	if (change) {
 		for (wi = 0; wi < wlist->num_widgets; wi++) {
 			widget = wlist->widgets[wi];
 
 			widget->value = val;
-
 			update.kcontrol = kcontrol;
 			update.widget = widget;
 			update.reg = reg;
-			update.mask = mask;
+			update.mask = val_mask;
 			update.val = val;
-			widget->dapm->update = &update;
 
-			soc_dapm_mixer_update_power(widget, kcontrol, connect);
+			if (type_2r) {
+				widget->rvalue = val2;
+				update.rreg = reg2;
+				update.rmask = val_mask;
+				update.rval = val2;
+			} else {
+				update.rmask = 0;
+			}
 
+			widget->dapm->update = &update;
+			soc_dapm_mixer_update_power(widget, kcontrol, connect);
 			widget->dapm->update = NULL;
 		}
 	}
@@ -2627,6 +2687,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
 			update.reg = e->reg;
 			update.mask = mask;
 			update.val = val;
+			update.rmask = 0;
 			widget->dapm->update = &update;
 
 			soc_dapm_mux_update_power(widget, kcontrol, mux, e);
@@ -2793,6 +2854,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
 			update.reg = e->reg;
 			update.mask = mask;
 			update.val = val;
+			update.rmask = 0;
 			widget->dapm->update = &update;
 
 			soc_dapm_mux_update_power(widget, kcontrol, mux, e);
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

  reply	other threads:[~2012-07-02 11:42 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-18 20:41 [PATCH] ASoC: dapm: Fix snd_soc_dapm_put_volsw() connect Benoît Thébaudeau
2012-06-19 11:36 ` Mark Brown
2012-06-29  6:25 ` Takashi Iwai
2012-06-29  7:23   ` Mark Brown
2012-06-29  7:26     ` Takashi Iwai
2012-06-29 11:53   ` Benoît Thébaudeau
2012-06-29 12:03     ` Takashi Iwai
2012-06-29 14:29       ` Benoît Thébaudeau
2012-06-29 15:43         ` Takashi Iwai
2012-06-29 15:44           ` Takashi Iwai
2012-06-29 16:09             ` Benoît Thébaudeau
2012-06-29 16:22               ` Takashi Iwai
2012-06-29 19:09                 ` Benoît Thébaudeau
2012-06-29 20:18                   ` Benoît Thébaudeau
2012-06-30 11:39                     ` Mark Brown
2012-06-30 13:03                       ` Benoît Thébaudeau
2012-06-30 18:24                         ` Mark Brown
2012-07-02 11:46                           ` Benoît Thébaudeau [this message]
2012-07-02 12:27                             ` [RFC/PATCH] ASoC: dapm: Fix/add support for stereo widgets Mark Brown
2012-07-03  6:57                           ` [PATCH] ASoC: dapm: Fix snd_soc_dapm_put_volsw() connect Takashi Iwai
2012-06-30 11:38                 ` Mark Brown
2012-06-29 16:05           ` Benoît Thébaudeau
2012-06-29 16:11             ` Takashi Iwai
2012-06-30 11:54             ` Mark Brown
2012-06-30 13:03               ` Benoît Thébaudeau
2012-07-02 11:45                 ` [PATCH] ASoC: dapm: Fix dapm_set_path_status() connect Benoît Thébaudeau
2012-07-03 19:08                   ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=134211720.502545.1341229602023.JavaMail.root@advansee.com \
    --to=benoit.thebaudeau@advansee.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=lrg@ti.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.