diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/vmaster.c | 8 | ||||
-rw-r--r-- | sound/usb/usbmixer.c | 13 |
2 files changed, 17 insertions, 4 deletions
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 257624bd1997..3b9b550109cb 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c | |||
@@ -353,7 +353,8 @@ static void master_free(struct snd_kcontrol *kcontrol) | |||
353 | * | 353 | * |
354 | * The optional argument @tlv can be used to specify the TLV information | 354 | * The optional argument @tlv can be used to specify the TLV information |
355 | * for dB scale of the master control. It should be a single element | 355 | * for dB scale of the master control. It should be a single element |
356 | * with #SNDRV_CTL_TLVT_DB_SCALE type, and should be the max 0dB. | 356 | * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or |
357 | * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB. | ||
357 | */ | 358 | */ |
358 | struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, | 359 | struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, |
359 | const unsigned int *tlv) | 360 | const unsigned int *tlv) |
@@ -384,7 +385,10 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, | |||
384 | kctl->private_free = master_free; | 385 | kctl->private_free = master_free; |
385 | 386 | ||
386 | /* additional (constant) TLV read */ | 387 | /* additional (constant) TLV read */ |
387 | if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { | 388 | if (tlv && |
389 | (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE || | ||
390 | tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX || | ||
391 | tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) { | ||
388 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | 392 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; |
389 | memcpy(master->tlv, tlv, sizeof(master->tlv)); | 393 | memcpy(master->tlv, tlv, sizeof(master->tlv)); |
390 | kctl->tlv.p = master->tlv; | 394 | kctl->tlv.p = master->tlv; |
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index ec9cdf986928..df8969188d15 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -461,7 +461,7 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
461 | unsigned int size, unsigned int __user *_tlv) | 461 | unsigned int size, unsigned int __user *_tlv) |
462 | { | 462 | { |
463 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 463 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
464 | DECLARE_TLV_DB_SCALE(scale, 0, 0, 0); | 464 | DECLARE_TLV_DB_MINMAX(scale, 0, 0); |
465 | 465 | ||
466 | if (size < sizeof(scale)) | 466 | if (size < sizeof(scale)) |
467 | return -ENOMEM; | 467 | return -ENOMEM; |
@@ -469,7 +469,16 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
469 | * while ALSA TLV contains in 1/100 dB unit | 469 | * while ALSA TLV contains in 1/100 dB unit |
470 | */ | 470 | */ |
471 | scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256; | 471 | scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256; |
472 | scale[3] = (convert_signed_value(cval, cval->res) * 100) / 256; | 472 | scale[3] = (convert_signed_value(cval, cval->max) * 100) / 256; |
473 | if (scale[3] <= scale[2]) { | ||
474 | /* something is wrong; assume it's either from/to 0dB */ | ||
475 | if (scale[2] < 0) | ||
476 | scale[3] = 0; | ||
477 | else if (scale[2] > 0) | ||
478 | scale[2] = 0; | ||
479 | else /* totally crap, return an error */ | ||
480 | return -EINVAL; | ||
481 | } | ||
473 | if (copy_to_user(_tlv, scale, sizeof(scale))) | 482 | if (copy_to_user(_tlv, scale, sizeof(scale))) |
474 | return -EFAULT; | 483 | return -EFAULT; |
475 | return 0; | 484 | return 0; |