diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-11-15 09:56:07 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:24 -0500 |
commit | 9cd17cd2409ddbe9853575569cfd97561fa86b14 (patch) | |
tree | e41f734ccf669f6360fe1155be42e262e44a9552 /sound/pci/ice1712/aureon.c | |
parent | 68ea7b2f2d8c1effd662fded04e9a589cb640da6 (diff) |
[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.c | 33 |
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, | |||
205 | struct snd_ctl_elem_value *ucontrol) | 205 | struct snd_ctl_elem_value *ucontrol) |
206 | { | 206 | { |
207 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 207 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
208 | ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out; | 208 | ucontrol->value.enumerated.item[0] = ice->spec.aureon.pca9554_out; |
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
@@ -216,10 +216,11 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol, | |||
216 | unsigned char oval, nval; | 216 | unsigned char oval, nval; |
217 | int change; | 217 | int change; |
218 | 218 | ||
219 | nval = ucontrol->value.enumerated.item[0]; | ||
220 | if (nval >= 3) | ||
221 | return -EINVAL; | ||
219 | snd_ice1712_save_gpio_status(ice); | 222 | snd_ice1712_save_gpio_status(ice); |
220 | |||
221 | oval = ice->spec.aureon.pca9554_out; | 223 | oval = ice->spec.aureon.pca9554_out; |
222 | nval = ucontrol->value.integer.value[0]; | ||
223 | if ((change = (oval != nval))) { | 224 | if ((change = (oval != nval))) { |
224 | aureon_pca9554_write(ice, PCA9554_OUT, nval); | 225 | aureon_pca9554_write(ice, PCA9554_OUT, nval); |
225 | ice->spec.aureon.pca9554_out = nval; | 226 | ice->spec.aureon.pca9554_out = nval; |
@@ -757,10 +758,13 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
757 | 758 | ||
758 | snd_ice1712_save_gpio_status(ice); | 759 | snd_ice1712_save_gpio_status(ice); |
759 | for (ch = 0; ch < 2; ch++) { | 760 | for (ch = 0; ch < 2; ch++) { |
760 | if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) { | 761 | unsigned int vol = ucontrol->value.integer.value[ch]; |
762 | if (vol > WM_VOL_MAX) | ||
763 | continue; | ||
764 | vol |= ice->spec.aureon.master[ch] & WM_VOL_MUTE; | ||
765 | if (vol != ice->spec.aureon.master[ch]) { | ||
761 | int dac; | 766 | int dac; |
762 | ice->spec.aureon.master[ch] &= WM_VOL_MUTE; | 767 | ice->spec.aureon.master[ch] = vol; |
763 | ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch]; | ||
764 | for (dac = 0; dac < ice->num_total_dacs; dac += 2) | 768 | for (dac = 0; dac < ice->num_total_dacs; dac += 2) |
765 | wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, | 769 | wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, |
766 | ice->spec.aureon.vol[dac + ch], | 770 | ice->spec.aureon.vol[dac + ch], |
@@ -807,10 +811,13 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * | |||
807 | ofs = kcontrol->private_value & 0xff; | 811 | ofs = kcontrol->private_value & 0xff; |
808 | snd_ice1712_save_gpio_status(ice); | 812 | snd_ice1712_save_gpio_status(ice); |
809 | for (i = 0; i < voices; i++) { | 813 | for (i = 0; i < voices; i++) { |
810 | idx = WM_DAC_ATTEN + ofs + i; | 814 | unsigned int vol = ucontrol->value.integer.value[i]; |
811 | if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) { | 815 | if (vol > 0x7f) |
812 | ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE; | 816 | continue; |
813 | ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i]; | 817 | vol |= ice->spec.aureon.vol[ofs+i]; |
818 | if (vol != ice->spec.aureon.vol[ofs+i]) { | ||
819 | ice->spec.aureon.vol[ofs+i] = vol; | ||
820 | idx = WM_DAC_ATTEN + ofs + i; | ||
814 | wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i], | 821 | wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i], |
815 | ice->spec.aureon.master[i]); | 822 | ice->spec.aureon.master[i]); |
816 | change = 1; | 823 | change = 1; |
@@ -940,8 +947,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
940 | unsigned short ovol, nvol; | 947 | unsigned short ovol, nvol; |
941 | int change = 0; | 948 | int change = 0; |
942 | 949 | ||
943 | snd_ice1712_save_gpio_status(ice); | ||
944 | nvol = ucontrol->value.integer.value[0]; | 950 | nvol = ucontrol->value.integer.value[0]; |
951 | if (nvol > PCM_RES) | ||
952 | return -EINVAL; | ||
953 | snd_ice1712_save_gpio_status(ice); | ||
945 | nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; | 954 | nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; |
946 | ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; | 955 | ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; |
947 | if (ovol != nvol) { | 956 | if (ovol != nvol) { |
@@ -1031,7 +1040,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
1031 | snd_ice1712_save_gpio_status(ice); | 1040 | snd_ice1712_save_gpio_status(ice); |
1032 | for (i = 0; i < 2; i++) { | 1041 | for (i = 0; i < 2; i++) { |
1033 | idx = WM_ADC_GAIN + i; | 1042 | idx = WM_ADC_GAIN + i; |
1034 | nvol = ucontrol->value.integer.value[i]; | 1043 | nvol = ucontrol->value.integer.value[i] & 0x1f; |
1035 | ovol = wm_get(ice, idx); | 1044 | ovol = wm_get(ice, idx); |
1036 | if ((ovol & 0x1f) != nvol) { | 1045 | if ((ovol & 0x1f) != nvol) { |
1037 | wm_put(ice, idx, nvol | (ovol & ~0x1f)); | 1046 | wm_put(ice, idx, nvol | (ovol & ~0x1f)); |