[alsa-devel] [PATCH 02/16] ASoC: core: Add 8bit multi reg control accessors
Ola Lilja
ola.o.lilja at stericsson.com
Tue Mar 13 16:11:29 CET 2012
From: Kristoffer KARLSSON <kristoffer.karlsson at stericsson.com>
Added get/put accessors for controls that span multiple 8bit registers
which together forms a single signed value in a MSB/LSB manner.
snd_soc_get_xr8_sx
snd_soc_put_xr8_sx
Signed-off-by: Kristoffer KARLSSON <kristoffer.karlsson at stericsson.com>
---
include/sound/soc.h | 4 ++
sound/soc/soc-core.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index dac20e0..d2e1d07 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -432,6 +432,10 @@ int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+int snd_soc_get_xr8_sx(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_xr8_sx(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 b5ecf6d..b72f238 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2641,6 +2641,91 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
/**
+ * snd_soc_get_xr8_sx - signed multi register get callback
+ * @kcontrol: mreg control
+ * @ucontrol: control element information
+ *
+ * Callback to get the value of a control that can
+ * span multiple 8bit codec registers which together
+ * forms a single signed value in a MSB/LSB manner.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_get_xr8_sx(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mreg_control *mc =
+ (struct soc_mreg_control *)kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int *reg = mc->reg;
+ unsigned int rcount = mc->rcount;
+ long min = mc->min;
+ long max = mc->max;
+ unsigned int invert = mc->invert;
+ unsigned long mask = abs(min) | abs(max);
+ long value = 0;
+ int i, rvalue;
+
+ for (i = 0; i < rcount; i++) {
+ rvalue = snd_soc_read(codec, reg[i]) & 0xff;
+ value |= rvalue << (8 * (rcount - i - 1));
+ }
+ value &= mask;
+ if (min < 0 && value > max)
+ value |= ~mask;
+ if (invert)
+ value = ~value;
+ ucontrol->value.integer.value[0] = value;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_get_xr8_sx);
+
+/**
+ * snd_soc_put_xr8_sx - signed multi register get callback
+ * @kcontrol: mreg control
+ * @ucontrol: control element information
+ *
+ * Callback to set the value of a control that can
+ * span multiple 8bit codec registers which together
+ * forms a single signed value in a MSB/LSB manner.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_put_xr8_sx(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mreg_control *mc =
+ (struct soc_mreg_control *)kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int *reg = mc->reg;
+ unsigned int rcount = mc->rcount;
+ long min = mc->min;
+ long max = mc->max;
+ unsigned int invert = mc->invert;
+ unsigned long mask = abs(min) | abs(max);
+ long value = ucontrol->value.integer.value[0];
+ int i, rvalue, err;
+
+ if (invert)
+ value = ~value;
+ if (value > max)
+ value = max;
+ else if (value < min)
+ value = min;
+ value &= mask;
+ for (i = 0; i < rcount; i++) {
+ rvalue = (value >> (8 * (rcount - i - 1))) & 0xff;
+ err = snd_soc_write(codec, reg[i], rvalue);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_put_xr8_sx);
+
+/**
* snd_soc_dai_set_sysclk - configure DAI system or master clock.
* @dai: DAI
* @clk_id: DAI specific clock ID
--
1.7.8.3
More information about the Alsa-devel
mailing list