From: Lars-Peter Clausen <lars@metafoo.de>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>,
Liam Girdwood <lrg@ti.com>
Cc: uclinux-dist-devel@blackfin.uclinux.org,
alsa-devel@alsa-project.org, Lars-Peter Clausen <lars@metafoo.de>
Subject: [PATCH 2/8] ASoC: Add support for virtual switch controls
Date: Thu, 10 Jan 2013 17:06:11 +0100 [thread overview]
Message-ID: <1357833977-3682-2-git-send-email-lars@metafoo.de> (raw)
In-Reply-To: <1357833977-3682-1-git-send-email-lars@metafoo.de>
Virtual switches are similar to virtual MUX controls. It does not have a
representation in the actual hardware but allows to control the DAPM routing by
enabling or disabling a input path into the mixer. This is useful if we want to
present a way to the user to for example mute a path despite the absence of a
separate mute control in hardware.
More specific this will be used by the ADAU1361 driver where the hardware has
a mute control for each of the DAC output paths, but we have to make sure that
the path is muted whenever the DAC is disabled. So the mute switches needs
to be controlled by DAPM so it can disable them before disabling the DAC. On the
other hand we still want to be to mute individual paths. This will be
accomplished by using virtual switch controls.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
include/sound/soc-dapm.h | 10 +++++++
sound/soc/soc-dapm.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 87 insertions(+), 1 deletion(-)
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index e1ef63d..c3d0371 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -257,6 +257,12 @@ 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) }
+#define SOC_DAPM_SINGLE_VIRT(xname, shift, max) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_info_volsw, \
+ .get = snd_soc_dapm_get_volsw_virt, \
+ .put = snd_soc_dapm_put_volsw_virt, \
+ .private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, shift, 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, \
@@ -344,6 +350,10 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_put_volsw_virt(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_get_volsw_virt(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1e36bc8..c3a0f43 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -347,7 +347,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- val = soc_widget_read(w, reg);
+ if (reg >= 0)
+ val = soc_widget_read(w, reg);
+ else
+ val = 0;
val = (val >> shift) & mask;
if (invert)
val = max - val;
@@ -2697,6 +2700,79 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
/**
+ * snd_soc_dapm_get_volsw_virt - virtual dapm mixer get callback
+ * @kcontrol: mixer control
+ * @ucontrol: control element information
+ *
+ * Callback to get the value of a virtual dapm mixer control.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_dapm_get_volsw_virt(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int shift = mc->shift;
+ unsigned int mask = (1 << fls(mc->max)) - 1;
+
+ ucontrol->value.integer.value[0] = (widget->value >> shift) & mask;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw_virt);
+
+/**
+ * snd_soc_dapm_put_volsw_virt - virtual dapm mixer set callback
+ * @kcontrol: mixer control
+ * @ucontrol: control element information
+ *
+ * Callback to set the value of a virutal dapm mixer control.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_dapm_put_volsw_virt(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct snd_soc_card *card = widget->codec->card;
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int mask = (1 << fls(mc->max)) - 1;
+ unsigned int shift = mc->shift;
+ unsigned int val, connect;
+ int wi;
+
+ val = ucontrol->value.integer.value[0] & mask;
+
+ mask = mask << shift;
+ val = val << shift;
+
+ if (val)
+ connect = 1;
+ else
+ connect = 0;
+
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+
+ if (val != (widget->value & mask)) {
+ widget->value &= ~mask;
+ widget->value |= val;
+ for (wi = 0; wi < wlist->num_widgets; wi++) {
+ widget = wlist->widgets[wi];
+ soc_dapm_mixer_update_power(widget, kcontrol, connect);
+ }
+ }
+
+ mutex_unlock(&card->dapm_mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw_virt);
+
+/**
* snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
* @kcontrol: mixer control
* @ucontrol: control element information
--
1.8.0
next prev parent reply other threads:[~2013-01-10 16:05 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-10 16:06 [PATCH 1/8] regmap: Add support for 24 bit wide register addresses Lars-Peter Clausen
2013-01-10 16:06 ` Lars-Peter Clausen [this message]
[not found] ` <1357833977-3682-2-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2013-01-11 12:19 ` [PATCH 2/8] ASoC: Add support for virtual switch controls Mark Brown
2013-01-11 12:38 ` Lars-Peter Clausen
2013-01-11 12:45 ` Mark Brown
[not found] ` <20130111124535.GZ20956-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2013-01-11 12:56 ` Lars-Peter Clausen
2013-01-11 13:57 ` Mark Brown
2013-01-11 15:05 ` Lars-Peter Clausen
[not found] ` <50F02A51.3010108-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2013-01-11 15:08 ` [alsa-devel] " Lars-Peter Clausen
2013-01-11 15:22 ` Mark Brown
2013-01-11 16:24 ` Mark Brown
[not found] ` <1357833977-3682-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2013-01-10 16:06 ` [PATCH 3/8] ASoC: Add ADAU1X61 and ADAU1X81 CODECs common code Lars-Peter Clausen
2013-01-10 16:06 ` [PATCH 4/8] ASoC: Add ADAU1361/ADAU1761 CODEC support Lars-Peter Clausen
2013-01-10 16:06 ` [PATCH 5/8] ASoC: Add ADAU1381/ADAU1781 " Lars-Peter Clausen
2013-01-10 16:06 ` [PATCH 6/8] ASoC: Constify ops and compr_ops fields of snd_soc_dai_link Lars-Peter Clausen
2013-01-13 22:55 ` Mark Brown
2013-01-10 16:06 ` [PATCH 7/8] ASoC: Blackfin: ADAU1X61 eval board support Lars-Peter Clausen
2013-01-10 16:06 ` [PATCH 8/8] ASoC: Blackfin: ADAU1X81 " Lars-Peter Clausen
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=1357833977-3682-2-git-send-email-lars@metafoo.de \
--to=lars@metafoo.de \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=lrg@ti.com \
--cc=uclinux-dist-devel@blackfin.uclinux.org \
/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;
as well as URLs for NNTP newsgroup(s).