diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-11-15 08:42:34 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-11-19 12:41:30 -0500 |
commit | 5fe619f983d6c7c0a578fcaabf80edd30e7ce46c (patch) | |
tree | 58b1737a4ae7db6ba93288fd9cc1775d8945e7c0 /sound/pci/ca0106/ca0106_mixer.c | |
parent | 7eba5c9dc3735b14e3df7366671adc15e0c8a048 (diff) |
[ALSA] ca0106 - Check value range in ctl callbacks
Check the value ranges in ctl put callbacks properly.
Some callbacks may access a wrong pointer depending on the value passed.
Also, fixed the access to the wrong field for enum values, and fixed
some callbacks to return the proper error code.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/ca0106/ca0106_mixer.c')
-rw-r--r-- | sound/pci/ca0106/ca0106_mixer.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index be519a17dfa..3f9b5c56003 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
@@ -86,7 +86,7 @@ static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol, | |||
86 | { | 86 | { |
87 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 87 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
88 | 88 | ||
89 | ucontrol->value.enumerated.item[0] = emu->spdif_enable; | 89 | ucontrol->value.integer.value[0] = emu->spdif_enable; |
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
@@ -98,11 +98,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol, | |||
98 | int change = 0; | 98 | int change = 0; |
99 | u32 mask; | 99 | u32 mask; |
100 | 100 | ||
101 | val = ucontrol->value.enumerated.item[0] ; | 101 | val = !!ucontrol->value.integer.value[0]; |
102 | change = (emu->spdif_enable != val); | 102 | change = (emu->spdif_enable != val); |
103 | if (change) { | 103 | if (change) { |
104 | emu->spdif_enable = val; | 104 | emu->spdif_enable = val; |
105 | if (val == 1) { | 105 | if (val) { |
106 | /* Digital */ | 106 | /* Digital */ |
107 | snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); | 107 | snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); |
108 | snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000); | 108 | snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000); |
@@ -159,6 +159,8 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol, | |||
159 | u32 source; | 159 | u32 source; |
160 | 160 | ||
161 | val = ucontrol->value.enumerated.item[0] ; | 161 | val = ucontrol->value.enumerated.item[0] ; |
162 | if (val >= 6) | ||
163 | return -EINVAL; | ||
162 | change = (emu->capture_source != val); | 164 | change = (emu->capture_source != val); |
163 | if (change) { | 165 | if (change) { |
164 | emu->capture_source = val; | 166 | emu->capture_source = val; |
@@ -207,6 +209,8 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, | |||
207 | * for the particular source. | 209 | * for the particular source. |
208 | */ | 210 | */ |
209 | source_id = ucontrol->value.enumerated.item[0] ; | 211 | source_id = ucontrol->value.enumerated.item[0] ; |
212 | if (source_id >= 4) | ||
213 | return -EINVAL; | ||
210 | change = (emu->i2c_capture_source != source_id); | 214 | change = (emu->i2c_capture_source != source_id); |
211 | if (change) { | 215 | if (change) { |
212 | snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ | 216 | snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ |
@@ -271,6 +275,8 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol, | |||
271 | u32 tmp; | 275 | u32 tmp; |
272 | 276 | ||
273 | val = ucontrol->value.enumerated.item[0] ; | 277 | val = ucontrol->value.enumerated.item[0] ; |
278 | if (val > 1) | ||
279 | return -EINVAL; | ||
274 | change = (emu->capture_mic_line_in != val); | 280 | change = (emu->capture_mic_line_in != val); |
275 | if (change) { | 281 | if (change) { |
276 | emu->capture_mic_line_in = val; | 282 | emu->capture_mic_line_in = val; |
@@ -443,7 +449,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol, | |||
443 | ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ | 449 | ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ |
444 | ngain = ucontrol->value.integer.value[0]; | 450 | ngain = ucontrol->value.integer.value[0]; |
445 | if (ngain > 0xff) | 451 | if (ngain > 0xff) |
446 | return 0; | 452 | return -EINVAL; |
447 | if (ogain != ngain) { | 453 | if (ogain != ngain) { |
448 | if (emu->i2c_capture_source == source_id) | 454 | if (emu->i2c_capture_source == source_id) |
449 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); | 455 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); |
@@ -453,7 +459,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol, | |||
453 | ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ | 459 | ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ |
454 | ngain = ucontrol->value.integer.value[1]; | 460 | ngain = ucontrol->value.integer.value[1]; |
455 | if (ngain > 0xff) | 461 | if (ngain > 0xff) |
456 | return 0; | 462 | return -EINVAL; |
457 | if (ogain != ngain) { | 463 | if (ogain != ngain) { |
458 | if (emu->i2c_capture_source == source_id) | 464 | if (emu->i2c_capture_source == source_id) |
459 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); | 465 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); |
@@ -497,7 +503,7 @@ static int spi_mute_put(struct snd_kcontrol *kcontrol, | |||
497 | } | 503 | } |
498 | 504 | ||
499 | ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]); | 505 | ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]); |
500 | return ret ? -1 : 1; | 506 | return ret ? -EINVAL : 1; |
501 | } | 507 | } |
502 | 508 | ||
503 | #define CA_VOLUME(xname,chid,reg) \ | 509 | #define CA_VOLUME(xname,chid,reg) \ |