Commit 5fe619f9 authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[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: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 7eba5c9d
...@@ -86,7 +86,7 @@ static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol, ...@@ -86,7 +86,7 @@ static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
{ {
struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
ucontrol->value.enumerated.item[0] = emu->spdif_enable; ucontrol->value.integer.value[0] = emu->spdif_enable;
return 0; return 0;
} }
...@@ -98,11 +98,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol, ...@@ -98,11 +98,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
int change = 0; int change = 0;
u32 mask; u32 mask;
val = ucontrol->value.enumerated.item[0] ; val = !!ucontrol->value.integer.value[0];
change = (emu->spdif_enable != val); change = (emu->spdif_enable != val);
if (change) { if (change) {
emu->spdif_enable = val; emu->spdif_enable = val;
if (val == 1) { if (val) {
/* Digital */ /* Digital */
snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000); 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,6 +159,8 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
u32 source; u32 source;
val = ucontrol->value.enumerated.item[0] ; val = ucontrol->value.enumerated.item[0] ;
if (val >= 6)
return -EINVAL;
change = (emu->capture_source != val); change = (emu->capture_source != val);
if (change) { if (change) {
emu->capture_source = val; emu->capture_source = val;
...@@ -207,6 +209,8 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, ...@@ -207,6 +209,8 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
* for the particular source. * for the particular source.
*/ */
source_id = ucontrol->value.enumerated.item[0] ; source_id = ucontrol->value.enumerated.item[0] ;
if (source_id >= 4)
return -EINVAL;
change = (emu->i2c_capture_source != source_id); change = (emu->i2c_capture_source != source_id);
if (change) { if (change) {
snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ 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,6 +275,8 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
u32 tmp; u32 tmp;
val = ucontrol->value.enumerated.item[0] ; val = ucontrol->value.enumerated.item[0] ;
if (val > 1)
return -EINVAL;
change = (emu->capture_mic_line_in != val); change = (emu->capture_mic_line_in != val);
if (change) { if (change) {
emu->capture_mic_line_in = val; emu->capture_mic_line_in = val;
...@@ -443,7 +449,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol, ...@@ -443,7 +449,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
ngain = ucontrol->value.integer.value[0]; ngain = ucontrol->value.integer.value[0];
if (ngain > 0xff) if (ngain > 0xff)
return 0; return -EINVAL;
if (ogain != ngain) { if (ogain != ngain) {
if (emu->i2c_capture_source == source_id) if (emu->i2c_capture_source == source_id)
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); 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,7 +459,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
ngain = ucontrol->value.integer.value[1]; ngain = ucontrol->value.integer.value[1];
if (ngain > 0xff) if (ngain > 0xff)
return 0; return -EINVAL;
if (ogain != ngain) { if (ogain != ngain) {
if (emu->i2c_capture_source == source_id) if (emu->i2c_capture_source == source_id)
snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
...@@ -497,7 +503,7 @@ static int spi_mute_put(struct snd_kcontrol *kcontrol, ...@@ -497,7 +503,7 @@ static int spi_mute_put(struct snd_kcontrol *kcontrol,
} }
ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]); ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
return ret ? -1 : 1; return ret ? -EINVAL : 1;
} }
#define CA_VOLUME(xname,chid,reg) \ #define CA_VOLUME(xname,chid,reg) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment