aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106/ca0106_mixer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-11-15 08:42:34 -0500
committerJaroslav Kysela <perex@perex.cz>2007-11-19 12:41:30 -0500
commit5fe619f983d6c7c0a578fcaabf80edd30e7ce46c (patch)
tree58b1737a4ae7db6ba93288fd9cc1775d8945e7c0 /sound/pci/ca0106/ca0106_mixer.c
parent7eba5c9dc3735b14e3df7366671adc15e0c8a048 (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.c18
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) \