Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 485e3e0c authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
parent a4e7a121
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -2661,7 +2661,7 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
}

/* 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];
	const int *tlv = NULL;
@@ -2681,6 +2681,12 @@ static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
		step &= ~TLV_DB_SCALE_MUTE;
		if (!step)
			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;
	}
	return val;
@@ -2703,7 +2709,7 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
/* initialize the slave volume with 0dB */
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)
		put_kctl_with_value(slave, offset);
	return 0;
@@ -2764,9 +2770,11 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,

	/* init with master mute & zero volume */
	put_kctl_with_value(kctl, 0);
	if (init_slave_vol)
	if (init_slave_vol) {
		int step = 0;
		map_slaves(codec, slaves, suffix,
			   tlv ? init_slave_0dB : init_slave_unmute, kctl);
			   tlv ? init_slave_0dB : init_slave_unmute, &step);
	}

	if (ctl_ret)
		*ctl_ret = kctl;