diff options
Diffstat (limited to 'sound/pci/emu10k1/emumixer.c')
| -rw-r--r-- | sound/pci/emu10k1/emumixer.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 54a2034d8edd..ccacd7b890e8 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
| @@ -58,6 +58,9 @@ static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol, | |||
| 58 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 58 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
| 59 | unsigned long flags; | 59 | unsigned long flags; |
| 60 | 60 | ||
| 61 | /* Limit: emu->spdif_bits */ | ||
| 62 | if (idx >= 3) | ||
| 63 | return -EINVAL; | ||
| 61 | spin_lock_irqsave(&emu->reg_lock, flags); | 64 | spin_lock_irqsave(&emu->reg_lock, flags); |
| 62 | ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; | 65 | ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; |
| 63 | ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; | 66 | ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; |
| @@ -272,9 +275,12 @@ static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, | |||
| 272 | struct snd_ctl_elem_value *ucontrol) | 275 | struct snd_ctl_elem_value *ucontrol) |
| 273 | { | 276 | { |
| 274 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 277 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
| 275 | int channel; | 278 | unsigned int channel; |
| 276 | 279 | ||
| 277 | channel = (kcontrol->private_value) & 0xff; | 280 | channel = (kcontrol->private_value) & 0xff; |
| 281 | /* Limit: emu1010_output_dst, emu->emu1010.output_source */ | ||
| 282 | if (channel >= 24) | ||
| 283 | return -EINVAL; | ||
| 278 | ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel]; | 284 | ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel]; |
| 279 | return 0; | 285 | return 0; |
| 280 | } | 286 | } |
| @@ -285,11 +291,17 @@ static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol, | |||
| 285 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 291 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
| 286 | int change = 0; | 292 | int change = 0; |
| 287 | unsigned int val; | 293 | unsigned int val; |
| 288 | int channel; | 294 | unsigned int channel; |
| 289 | 295 | ||
| 296 | val = ucontrol->value.enumerated.item[0]; | ||
| 297 | if (val >= 53) | ||
| 298 | return -EINVAL; | ||
| 290 | channel = (kcontrol->private_value) & 0xff; | 299 | channel = (kcontrol->private_value) & 0xff; |
| 291 | if (emu->emu1010.output_source[channel] != ucontrol->value.enumerated.item[0]) { | 300 | /* Limit: emu1010_output_dst, emu->emu1010.output_source */ |
| 292 | val = emu->emu1010.output_source[channel] = ucontrol->value.enumerated.item[0]; | 301 | if (channel >= 24) |
| 302 | return -EINVAL; | ||
| 303 | if (emu->emu1010.output_source[channel] != val) { | ||
| 304 | emu->emu1010.output_source[channel] = val; | ||
| 293 | change = 1; | 305 | change = 1; |
| 294 | snd_emu1010_fpga_link_dst_src_write(emu, | 306 | snd_emu1010_fpga_link_dst_src_write(emu, |
| 295 | emu1010_output_dst[channel], emu1010_src_regs[val]); | 307 | emu1010_output_dst[channel], emu1010_src_regs[val]); |
| @@ -301,9 +313,12 @@ static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol, | |||
| 301 | struct snd_ctl_elem_value *ucontrol) | 313 | struct snd_ctl_elem_value *ucontrol) |
| 302 | { | 314 | { |
| 303 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 315 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
| 304 | int channel; | 316 | unsigned int channel; |
| 305 | 317 | ||
| 306 | channel = (kcontrol->private_value) & 0xff; | 318 | channel = (kcontrol->private_value) & 0xff; |
| 319 | /* Limit: emu1010_input_dst, emu->emu1010.input_source */ | ||
| 320 | if (channel >= 22) | ||
| 321 | return -EINVAL; | ||
| 307 | ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel]; | 322 | ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel]; |
| 308 | return 0; | 323 | return 0; |
| 309 | } | 324 | } |
| @@ -314,11 +329,17 @@ static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol, | |||
| 314 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 329 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
| 315 | int change = 0; | 330 | int change = 0; |
| 316 | unsigned int val; | 331 | unsigned int val; |
| 317 | int channel; | 332 | unsigned int channel; |
| 318 | 333 | ||
| 334 | val = ucontrol->value.enumerated.item[0]; | ||
| 335 | if (val >= 53) | ||
| 336 | return -EINVAL; | ||
| 319 | channel = (kcontrol->private_value) & 0xff; | 337 | channel = (kcontrol->private_value) & 0xff; |
| 320 | if (emu->emu1010.input_source[channel] != ucontrol->value.enumerated.item[0]) { | 338 | /* Limit: emu1010_input_dst, emu->emu1010.input_source */ |
| 321 | val = emu->emu1010.input_source[channel] = ucontrol->value.enumerated.item[0]; | 339 | if (channel >= 22) |
| 340 | return -EINVAL; | ||
| 341 | if (emu->emu1010.input_source[channel] != val) { | ||
| 342 | emu->emu1010.input_source[channel] = val; | ||
| 322 | change = 1; | 343 | change = 1; |
| 323 | snd_emu1010_fpga_link_dst_src_write(emu, | 344 | snd_emu1010_fpga_link_dst_src_write(emu, |
| 324 | emu1010_input_dst[channel], emu1010_src_regs[val]); | 345 | emu1010_input_dst[channel], emu1010_src_regs[val]); |
| @@ -533,6 +554,9 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol, | |||
| 533 | int change = 0; | 554 | int change = 0; |
| 534 | 555 | ||
| 535 | val = ucontrol->value.enumerated.item[0] ; | 556 | val = ucontrol->value.enumerated.item[0] ; |
| 557 | /* Limit: uinfo->value.enumerated.items = 4; */ | ||
| 558 | if (val >= 4) | ||
| 559 | return -EINVAL; | ||
| 536 | change = (emu->emu1010.internal_clock != val); | 560 | change = (emu->emu1010.internal_clock != val); |
| 537 | if (change) { | 561 | if (change) { |
| 538 | emu->emu1010.internal_clock = val; | 562 | emu->emu1010.internal_clock = val; |
| @@ -669,7 +693,11 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, | |||
| 669 | * update the capture volume from the cached value | 693 | * update the capture volume from the cached value |
| 670 | * for the particular source. | 694 | * for the particular source. |
| 671 | */ | 695 | */ |
| 672 | source_id = ucontrol->value.enumerated.item[0]; /* Use 2 and 3 */ | 696 | source_id = ucontrol->value.enumerated.item[0]; |
| 697 | /* Limit: uinfo->value.enumerated.items = 2; */ | ||
| 698 | /* emu->i2c_capture_volume */ | ||
| 699 | if (source_id >= 2) | ||
| 700 | return -EINVAL; | ||
| 673 | change = (emu->i2c_capture_source != source_id); | 701 | change = (emu->i2c_capture_source != source_id); |
| 674 | if (change) { | 702 | if (change) { |
| 675 | snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */ | 703 | snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */ |
| @@ -720,9 +748,13 @@ static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol, | |||
| 720 | struct snd_ctl_elem_value *ucontrol) | 748 | struct snd_ctl_elem_value *ucontrol) |
| 721 | { | 749 | { |
| 722 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 750 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
| 723 | int source_id; | 751 | unsigned int source_id; |
| 724 | 752 | ||
| 725 | source_id = kcontrol->private_value; | 753 | source_id = kcontrol->private_value; |
| 754 | /* Limit: emu->i2c_capture_volume */ | ||
| 755 | /* capture_source: uinfo->value.enumerated.items = 2 */ | ||
| 756 | if (source_id >= 2) | ||
| 757 | return -EINVAL; | ||
| 726 | 758 | ||
| 727 | ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0]; | 759 | ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0]; |
| 728 | ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1]; | 760 | ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1]; |
| @@ -735,10 +767,14 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, | |||
| 735 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 767 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
| 736 | unsigned int ogain; | 768 | unsigned int ogain; |
| 737 | unsigned int ngain; | 769 | unsigned int ngain; |
| 738 | int source_id; | 770 | unsigned int source_id; |
| 739 | int change = 0; | 771 | int change = 0; |
| 740 | 772 | ||
| 741 | source_id = kcontrol->private_value; | 773 | source_id = kcontrol->private_value; |
| 774 | /* Limit: emu->i2c_capture_volume */ | ||
| 775 | /* capture_source: uinfo->value.enumerated.items = 2 */ | ||
| 776 | if (source_id >= 2) | ||
| 777 | return -EINVAL; | ||
| 742 | ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ | 778 | ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ |
| 743 | ngain = ucontrol->value.integer.value[0]; | 779 | ngain = ucontrol->value.integer.value[0]; |
| 744 | if (ngain > 0xff) | 780 | if (ngain > 0xff) |
| @@ -746,7 +782,7 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, | |||
| 746 | if (ogain != ngain) { | 782 | if (ogain != ngain) { |
| 747 | if (emu->i2c_capture_source == source_id) | 783 | if (emu->i2c_capture_source == source_id) |
| 748 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); | 784 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); |
| 749 | emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0]; | 785 | emu->i2c_capture_volume[source_id][0] = ngain; |
| 750 | change = 1; | 786 | change = 1; |
| 751 | } | 787 | } |
| 752 | ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ | 788 | ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ |
| @@ -756,7 +792,7 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, | |||
| 756 | if (ogain != ngain) { | 792 | if (ogain != ngain) { |
| 757 | if (emu->i2c_capture_source == source_id) | 793 | if (emu->i2c_capture_source == source_id) |
| 758 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); | 794 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); |
| 759 | emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1]; | 795 | emu->i2c_capture_volume[source_id][1] = ngain; |
| 760 | change = 1; | 796 | change = 1; |
| 761 | } | 797 | } |
| 762 | 798 | ||
| @@ -877,6 +913,9 @@ static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol, | |||
| 877 | unsigned int val; | 913 | unsigned int val; |
| 878 | unsigned long flags; | 914 | unsigned long flags; |
| 879 | 915 | ||
| 916 | /* Limit: emu->spdif_bits */ | ||
| 917 | if (idx >= 3) | ||
| 918 | return -EINVAL; | ||
| 880 | val = (ucontrol->value.iec958.status[0] << 0) | | 919 | val = (ucontrol->value.iec958.status[0] << 0) | |
| 881 | (ucontrol->value.iec958.status[1] << 8) | | 920 | (ucontrol->value.iec958.status[1] << 8) | |
| 882 | (ucontrol->value.iec958.status[2] << 16) | | 921 | (ucontrol->value.iec958.status[2] << 16) | |
