summaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712/aureon.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-11-15 15:56:07 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:24 +0100
commit9cd17cd2409ddbe9853575569cfd97561fa86b14 (patch)
treee41f734ccf669f6360fe1155be42e262e44a9552 /sound/pci/ice1712/aureon.c
parent68ea7b2f2d8c1effd662fded04e9a589cb640da6 (diff)
downloadlinux-9cd17cd2409ddbe9853575569cfd97561fa86b14.tar.bz2
[ALSA] ice1724 - Check value ranges in ctl callbacks
Check the value ranges in ctl put callbacks properly. Also fixed the wrong access type to enum elements in aureon.c. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/ice1712/aureon.c')
-rw-r--r--sound/pci/ice1712/aureon.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index ec0699c89952..f83ec2f565cf 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -205,7 +205,7 @@ static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out;
+ ucontrol->value.enumerated.item[0] = ice->spec.aureon.pca9554_out;
return 0;
}
@@ -216,10 +216,11 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
unsigned char oval, nval;
int change;
+ nval = ucontrol->value.enumerated.item[0];
+ if (nval >= 3)
+ return -EINVAL;
snd_ice1712_save_gpio_status(ice);
-
oval = ice->spec.aureon.pca9554_out;
- nval = ucontrol->value.integer.value[0];
if ((change = (oval != nval))) {
aureon_pca9554_write(ice, PCA9554_OUT, nval);
ice->spec.aureon.pca9554_out = nval;
@@ -757,10 +758,13 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
snd_ice1712_save_gpio_status(ice);
for (ch = 0; ch < 2; ch++) {
- if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
+ unsigned int vol = ucontrol->value.integer.value[ch];
+ if (vol > WM_VOL_MAX)
+ continue;
+ vol |= ice->spec.aureon.master[ch] & WM_VOL_MUTE;
+ if (vol != ice->spec.aureon.master[ch]) {
int dac;
- ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
- ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
+ ice->spec.aureon.master[ch] = vol;
for (dac = 0; dac < ice->num_total_dacs; dac += 2)
wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
ice->spec.aureon.vol[dac + ch],
@@ -807,10 +811,13 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
ofs = kcontrol->private_value & 0xff;
snd_ice1712_save_gpio_status(ice);
for (i = 0; i < voices; i++) {
- idx = WM_DAC_ATTEN + ofs + i;
- if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
- ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
- ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
+ unsigned int vol = ucontrol->value.integer.value[i];
+ if (vol > 0x7f)
+ continue;
+ vol |= ice->spec.aureon.vol[ofs+i];
+ if (vol != ice->spec.aureon.vol[ofs+i]) {
+ ice->spec.aureon.vol[ofs+i] = vol;
+ idx = WM_DAC_ATTEN + ofs + i;
wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
ice->spec.aureon.master[i]);
change = 1;
@@ -940,8 +947,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
unsigned short ovol, nvol;
int change = 0;
- snd_ice1712_save_gpio_status(ice);
nvol = ucontrol->value.integer.value[0];
+ if (nvol > PCM_RES)
+ return -EINVAL;
+ snd_ice1712_save_gpio_status(ice);
nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
if (ovol != nvol) {
@@ -1031,7 +1040,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
snd_ice1712_save_gpio_status(ice);
for (i = 0; i < 2; i++) {
idx = WM_ADC_GAIN + i;
- nvol = ucontrol->value.integer.value[i];
+ nvol = ucontrol->value.integer.value[i] & 0x1f;
ovol = wm_get(ice, idx);
if ((ovol & 0x1f) != nvol) {
wm_put(ice, idx, nvol | (ovol & ~0x1f));