[alsa-devel] [PATCH] ASoC: core: Support for limiting the volume
Peter Ujfalusi
peter.ujfalusi at nokia.com
Fri May 7 13:05:49 CEST 2010
Add support for the core to limit the maximum volume on an
existing control.
The function will modify the soc_mixer_control.max value
of the given control.
The new value must be lower than the original one (chip maximum)
If there is a need for limiting a gain on a given control,
than machine drivers can do the following in their
snd_soc_dai_link.init function:
snd_soc_limit_volume(codec, "TPA6140A2 Headphone Playback Volume", 21);
This will modify the original 31 (chip maximum) to 21, so user
space will not be able to set the gain higher than this.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi at nokia.com>
---
include/sound/soc.h | 2 ++
sound/soc/soc-core.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 01e9c66..9f306f0 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -326,6 +326,8 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+int snd_soc_limit_volume(struct snd_soc_codec *codec,
+ const char *name, int max);
/**
* struct snd_soc_jack_pin - Describes a pin to update based on jack detection
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d59076e..4079223 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2238,6 +2238,45 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
/**
+ * snd_soc_limit_volume - Set new limit to an existing volume control.
+ *
+ * @codec: where to look for the control
+ * @name: Name of the control
+ * @max: new maximum limit
+ *
+ * Return 0 for success, else error.
+ */
+int snd_soc_limit_volume(struct snd_soc_codec *codec,
+ const char *name, int max)
+{
+ struct snd_card *card = codec->card;
+ struct snd_kcontrol *kctl;
+ struct soc_mixer_control *mc;
+ int found = 0;
+ int ret = -EINVAL;
+
+ /* Sanity check for name and max */
+ if (unlikely(!name || max <= 0))
+ return -EINVAL;
+
+ list_for_each_entry(kctl, &card->controls, list) {
+ if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ mc = (struct soc_mixer_control *)kctl->private_value;
+ if (max <= mc->max) {
+ mc->max = max;
+ ret = 0;
+ }
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
+
+/**
* snd_soc_dai_set_sysclk - configure DAI system or master clock.
* @dai: DAI
* @clk_id: DAI specific clock ID
--
1.7.1
More information about the Alsa-devel
mailing list