[alsa-devel] [PATCH 03/16] ASoC: core: Add range of reg control accessors

Ola Lilja ola.o.lilja at stericsson.com
Tue Mar 13 16:11:30 CET 2012


From: Kristoffer KARLSSON <kristoffer.karlsson at stericsson.com>

Added get/put accessors for controls that maps a range of
consecutive registers exposed as a multiple value control.

This is specifically useful for hardware that exposes for instance
a range of filter parameters as a range of registers that with
this could be written and read back in one single ioctl operation.

snd_soc_get_m1r_sx
snd_soc_put_m1r_sx

Signed-off-by: Kristoffer KARLSSON <kristoffer.karlsson at stericsson.com>
---
 include/sound/soc.h  |    4 +++
 sound/soc/soc-core.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index d2e1d07..66953a6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -436,6 +436,10 @@ 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);
+int snd_soc_get_m1r_sx(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_m1r_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 b72f238..bacc465 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2726,6 +2726,78 @@ int snd_soc_put_xr8_sx(struct snd_kcontrol *kcontrol,
 EXPORT_SYMBOL_GPL(snd_soc_put_xr8_sx);
 
 /**
+ * snd_soc_get_m1r_sx - multiple register get callback
+ * @kcontrol: mreg control
+ * @ucontrol: control element information
+ *
+ * Callback to get the all values of a control
+ * from a chunk of registers.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_get_m1r_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 count = mc->count;
+	unsigned int invert = mc->invert;
+	unsigned int idx;
+	long value;
+
+	for (idx = 0; idx < count; idx++) {
+		value = snd_soc_read(codec, reg + idx);
+		if (invert)
+			value = ~value;
+		ucontrol->value.integer.value[idx] = value;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_get_m1r_sx);
+
+/**
+ * snd_soc_put_m1r_sx - multiple register get callback
+ * @kcontrol: mreg control
+ * @ucontrol: control element information
+ *
+ * Callback to set the all values of a control
+ * from a chunk of registers.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_put_m1r_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 count = mc->count;
+	long min = mc->min;
+	long max = mc->max;
+	unsigned int invert = mc->invert;
+	unsigned int idx;
+	long value;
+
+	for (idx = 0; idx < count; idx++) {
+		value = ucontrol->value.integer.value[idx];
+		if (value > max)
+			value = max;
+		else if (value < min)
+			value = min;
+		if (invert)
+			value = ~value;
+		snd_soc_write(codec, reg + idx, value);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_put_m1r_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