Skip to content

Commit

Permalink
ASoC: core: Support for limiting the volume
Browse files Browse the repository at this point in the history
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@nokia.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Peter Ujfalusi authored and Mark Brown committed May 7, 2010
1 parent 3057876 commit 637d384
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,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
Expand Down

0 comments on commit 637d384

Please sign in to comment.