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
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox