ALSA: hda - Add sanity check of vmaster slave dB steps
Check whether all vmaster slaves have the same dB steps. Otherwise the behavior would become inconsistent. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
a4e7a12168
commit
485e3e0cdf
1 changed files with 12 additions and 4 deletions
|
@ -2661,7 +2661,7 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* guess the value corresponding to 0dB */
|
/* guess the value corresponding to 0dB */
|
||||||
static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
|
static int get_kctl_0dB_offset(struct snd_kcontrol *kctl, int *step_to_check)
|
||||||
{
|
{
|
||||||
int _tlv[4];
|
int _tlv[4];
|
||||||
const int *tlv = NULL;
|
const int *tlv = NULL;
|
||||||
|
@ -2681,6 +2681,12 @@ static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
|
||||||
step &= ~TLV_DB_SCALE_MUTE;
|
step &= ~TLV_DB_SCALE_MUTE;
|
||||||
if (!step)
|
if (!step)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (*step_to_check && *step_to_check != step) {
|
||||||
|
snd_printk(KERN_ERR "hda_codec: Mismatching dB step for vmaster slave (%d!=%d)\n",
|
||||||
|
*step_to_check, step);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*step_to_check = step;
|
||||||
val = -tlv[2] / step;
|
val = -tlv[2] / step;
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
|
@ -2703,7 +2709,7 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
|
||||||
/* initialize the slave volume with 0dB */
|
/* initialize the slave volume with 0dB */
|
||||||
static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
|
static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
|
||||||
{
|
{
|
||||||
int offset = get_kctl_0dB_offset(slave);
|
int offset = get_kctl_0dB_offset(slave, data);
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
put_kctl_with_value(slave, offset);
|
put_kctl_with_value(slave, offset);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2764,9 +2770,11 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||||
|
|
||||||
/* init with master mute & zero volume */
|
/* init with master mute & zero volume */
|
||||||
put_kctl_with_value(kctl, 0);
|
put_kctl_with_value(kctl, 0);
|
||||||
if (init_slave_vol)
|
if (init_slave_vol) {
|
||||||
|
int step = 0;
|
||||||
map_slaves(codec, slaves, suffix,
|
map_slaves(codec, slaves, suffix,
|
||||||
tlv ? init_slave_0dB : init_slave_unmute, kctl);
|
tlv ? init_slave_0dB : init_slave_unmute, &step);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctl_ret)
|
if (ctl_ret)
|
||||||
*ctl_ret = kctl;
|
*ctl_ret = kctl;
|
||||||
|
|
Loading…
Add table
Reference in a new issue