aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-10 13:31:26 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-21 14:34:48 -0500
commit71d08516b80638a69d5efea4e8cb832c053f9dd9 (patch)
tree5f3c1497024c4669a1443fd30263ed81b591aa15
parent2b4bdee2920fb3894f9116f76343f8b31f9e4da8 (diff)
ASoC: core: Add SND_SOC_BYTES control for coefficient blocks
Allow devices to export blocks of registers to the application layer, intended for use for reading and writing coefficient data which can't usefully be worked with by the kernel at runtime (for example, due to requiring complex and expensive calculations or being the results of callibration procedures). Currently drivers are using platform data to provide configurations for coefficient blocks which isn't at all convenient for runtime management or configuration development. Currently only devices using regmap are supported, an error will be generated for any attempt to work with a byte control on a non-regmap device. There's no fundamental block to other devices so support could be added if required. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@ti.com>
-rw-r--r--include/sound/soc.h18
-rw-r--r--sound/soc/soc-core.c49
2 files changed, 67 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 1e16d6e3f2a8..3e9cae001eab 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -185,6 +185,12 @@
185 .rreg = xreg_right, .shift = xshift, \ 185 .rreg = xreg_right, .shift = xshift, \
186 .min = xmin, .max = xmax} } 186 .min = xmin, .max = xmax} }
187 187
188#define SND_SOC_BYTES(xname, xbase, xregs) \
189{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
190 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
191 .put = snd_soc_bytes_put, .private_value = \
192 ((unsigned long)&(struct soc_bytes) \
193 {.base = xbase, .num_regs = xregs }) }
188 194
189/* 195/*
190 * Simplified versions of above macros, declaring a struct and calculating 196 * Simplified versions of above macros, declaring a struct and calculating
@@ -413,6 +419,13 @@ int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol); 419 struct snd_ctl_elem_value *ucontrol);
414int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol, 420int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
415 struct snd_ctl_elem_value *ucontrol); 421 struct snd_ctl_elem_value *ucontrol);
422int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_info *uinfo);
424int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
425 struct snd_ctl_elem_value *ucontrol);
426int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
427 struct snd_ctl_elem_value *ucontrol);
428
416 429
417/** 430/**
418 * struct snd_soc_reg_access - Describes whether a given register is 431 * struct snd_soc_reg_access - Describes whether a given register is
@@ -888,6 +901,11 @@ struct soc_mixer_control {
888 unsigned int reg, rreg, shift, rshift, invert; 901 unsigned int reg, rreg, shift, rshift, invert;
889}; 902};
890 903
904struct soc_bytes {
905 int base;
906 int num_regs;
907};
908
891/* enumerated kcontrol */ 909/* enumerated kcontrol */
892struct soc_enum { 910struct soc_enum {
893 unsigned short reg; 911 unsigned short reg;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 3ca70594e242..a9786ab70504 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2736,6 +2736,55 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2736} 2736}
2737EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx); 2737EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2738 2738
2739int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
2740 struct snd_ctl_elem_info *uinfo)
2741{
2742 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2743 struct soc_bytes *params = (void *)kcontrol->private_value;
2744
2745 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2746 uinfo->count = params->num_regs * codec->val_bytes;
2747
2748 return 0;
2749}
2750EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
2751
2752int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2754{
2755 struct soc_bytes *params = (void *)kcontrol->private_value;
2756 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2757 int ret;
2758
2759 if (codec->using_regmap)
2760 ret = regmap_raw_read(codec->control_data, params->base,
2761 ucontrol->value.bytes.data,
2762 params->num_regs * codec->val_bytes);
2763 else
2764 ret = -EINVAL;
2765
2766 return ret;
2767}
2768EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
2769
2770int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
2771 struct snd_ctl_elem_value *ucontrol)
2772{
2773 struct soc_bytes *params = (void *)kcontrol->private_value;
2774 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2775 int ret;
2776
2777 if (codec->using_regmap)
2778 ret = regmap_raw_write(codec->control_data, params->base,
2779 ucontrol->value.bytes.data,
2780 params->num_regs * codec->val_bytes);
2781 else
2782 ret = -EINVAL;
2783
2784 return ret;
2785}
2786EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
2787
2739/** 2788/**
2740 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2789 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2741 * @dai: DAI 2790 * @dai: DAI