summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEero Nurkkala <ext-eero.nurkkala@nokia.com>2009-02-06 12:01:04 +0200
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-02-06 11:39:28 +0000
commit4453dba54de7e517b0cd6f5e4a3f4af3b34f9e79 (patch)
treeb095287959af1a472aee299ae0276633601fb622
parent64ca0404eed57f6c92290d55e949a7f46cbe4bf4 (diff)
downloadlinux-stable-4453dba54de7e517b0cd6f5e4a3f4af3b34f9e79.tar.gz
linux-stable-4453dba54de7e517b0cd6f5e4a3f4af3b34f9e79.tar.bz2
linux-stable-4453dba54de7e517b0cd6f5e4a3f4af3b34f9e79.zip
ASoC: TLV320AIC3X: Fix kcontrol's private value use in put callback
Function snd_soc_dapm_put_volsw_aic3x misuses the kcontrol's private value by still accessing it as bitfields even SOC_SINGLE_VALUE constructs it as a pointer into struct soc_mixer_control after the commit 4eaa9819dc08d7bfd1065ce530e31b18a119dcaf. This was causing arbitrary register writes when touching the controls defined with SOC_DAPM_SINGLE_AIC3X. Signed-off-by: Eero Nurkkala <ext-eero.nurkkala@nokia.com> Acked-by: Jarkko Nikula <jarkko.nikula@nokia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/tlv320aic3x.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index b47a749c5ea2..aea0cb72d80a 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -165,10 +165,13 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0x01;
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int reg = mc->reg;
+ unsigned int shift = mc->shift;
+ int max = mc->max;
+ unsigned int mask = (1 << fls(max)) - 1;
+ unsigned int invert = mc->invert;
unsigned short val, val_mask;
int ret;
struct snd_soc_dapm_path *path;