* [PATCH 2/8] ASoC: core: Add strobe control
@ 2012-04-20 9:32 Ola Lilja
2012-04-23 19:13 ` Mark Brown
0 siblings, 1 reply; 2+ messages in thread
From: Ola Lilja @ 2012-04-20 9:32 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, alsa-devel; +Cc: Linus Walleij, Kristoffer KARLSSON
From: Kristoffer KARLSSON <kristoffer.karlsson@stericsson.com>
Added support for a control that strobes a bit in
a register to high then back to low (or the inverse).
This is typically useful for hardware that requires
strobing a singe bit to trigger some functionality
and where exposing the bit in a normal single control
would require the user to first manually set then
again unset the bit again for the strobe to trigger.
Added convenience macro.
SOC_SINGLE_STROBE
Added accessor implementations.
snd_soc_get_strobe
snd_soc_put_strobe
Signed-off-by: Kristoffer KARLSSON <kristoffer.karlsson@stericsson.com>
---
include/sound/soc.h | 8 ++++++
sound/soc/soc-core.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 8888adc..bda0cd2 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -209,6 +209,10 @@
{.regbase = xregbase, .regcount = xregcount, .nbits = xnbits, \
.invert = xinvert, .min = xmin, .max = xmax} }
+#define SOC_SINGLE_STROBE(xname, xreg, xshift, xinvert) \
+ SOC_SINGLE_EXT(xname, xreg, xshift, 1, xinvert, \
+ snd_soc_get_strobe, snd_soc_put_strobe)
+
/*
* Simplified versions of above macros, declaring a struct and calculating
* ARRAY_SIZE internally
@@ -448,6 +452,10 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
/**
* struct snd_soc_reg_access - Describes whether a given register is
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 7fc7294b..e9c5850 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2966,6 +2966,69 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx);
/**
+ * snd_soc_get_strobe - strobe get callback
+ * @kcontrol: mixer control
+ * @ucontrol: control element information
+ *
+ * Callback get the value of a strobe mixer control.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int reg = mc->reg;
+ unsigned int shift = mc->shift;
+ unsigned int mask = 1 << shift;
+ unsigned int invert = mc->invert != 0;
+ unsigned int val = snd_soc_read(codec, reg) & mask;
+
+ if (shift != 0 && val != 0)
+ val = val >> shift;
+ ucontrol->value.enumerated.item[0] = val ^ invert;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_get_strobe);
+
+/**
+ * snd_soc_put_strobe - strobe put callback
+ * @kcontrol: mixer control
+ * @ucontrol: control element information
+ *
+ * Callback strobe a register bit to high then low (or the inverse)
+ * in one pass of a single mixer enum control.
+ *
+ * Returns 1 for success.
+ */
+int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int reg = mc->reg;
+ unsigned int shift = mc->shift;
+ unsigned int mask = 1 << shift;
+ unsigned int invert = mc->invert != 0;
+ unsigned int strobe = ucontrol->value.enumerated.item[0] != 0;
+ unsigned int val1 = (strobe ^ invert) ? mask : 0;
+ unsigned int val2 = (strobe ^ invert) ? 0 : mask;
+ int err;
+
+ err = snd_soc_update_bits_locked(codec, reg, mask, val1);
+ if (err < 0)
+ return err;
+
+ err = snd_soc_update_bits_locked(codec, reg, mask, val2);
+ return err;
+}
+EXPORT_SYMBOL_GPL(snd_soc_put_strobe);
+
+/**
* snd_soc_dai_set_sysclk - configure DAI system or master clock.
* @dai: DAI
* @clk_id: DAI specific clock ID
--
1.7.8.3
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH 2/8] ASoC: core: Add strobe control
2012-04-20 9:32 [PATCH 2/8] ASoC: core: Add strobe control Ola Lilja
@ 2012-04-23 19:13 ` Mark Brown
0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2012-04-23 19:13 UTC (permalink / raw)
To: Ola Lilja; +Cc: alsa-devel, Kristoffer KARLSSON, Liam Girdwood, Linus Walleij
[-- Attachment #1.1: Type: text/plain, Size: 677 bytes --]
On Fri, Apr 20, 2012 at 11:32:44AM +0200, Ola Lilja wrote:
> From: Kristoffer KARLSSON <kristoffer.karlsson@stericsson.com>
>
> Added support for a control that strobes a bit in
> a register to high then back to low (or the inverse).
I've applied this but...
> + unsigned int val = snd_soc_read(codec, reg) & mask;
> +
> + if (shift != 0 && val != 0)
> + val = val >> shift;
> + ucontrol->value.enumerated.item[0] = val ^ invert;
...it seems weird that the code actually reads back the enumeration
status, even if we're in the middle of strobing it should be a very
brief, transitory, status which it isn't really worth going to the
effort of reporting.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-04-23 19:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-20 9:32 [PATCH 2/8] ASoC: core: Add strobe control Ola Lilja
2012-04-23 19:13 ` 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).