]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization
authorTakashi Iwai <tiwai@suse.de>
Wed, 22 Nov 2017 11:34:56 +0000 (12:34 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 22 Nov 2017 11:34:56 +0000 (12:34 +0100)
The previous fix for addressing the breakage in vmaster slave
initialization, commit a91d66129fb9 ("ALSA: hda - Fix incorrect TLV
callback check introduced during set_fs() removal"), introduced a new
helper to process over each slave kctl.  However, this helper passes
only the original kctl, not the virtual slave kctl.  As a result,
HD-audio driver (which is the only user so far) couldn't initialize
the slave correctly because it's trying to update the value directly
with the original kctl, not with the mapped kctl.

This patch fixes the situation again by passing both the mapped slaved
and original slave kctls to the function.  Luckily there is a single
caller as of now, so changing the call signature is no big matter.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197959
Fixes: a91d66129fb9 ("ALSA: hda - Fix incorrect TLV callback check introduced during set_fs() removal")
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/control.h
sound/core/vmaster.c
sound/pci/hda/hda_codec.c

index a1f1152bc687613b87d7d4a1f73a3d139ef9f354..ca13a44ae9d44e971a977e489244b831ac83040c 100644 (file)
@@ -249,7 +249,9 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
 void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
 #define snd_ctl_sync_vmaster_hook(kctl)        snd_ctl_sync_vmaster(kctl, true)
 int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
-                                int (*func)(struct snd_kcontrol *, void *),
+                                int (*func)(struct snd_kcontrol *vslave,
+                                            struct snd_kcontrol *slave,
+                                            void *arg),
                                 void *arg);
 
 /*
index e43af18d43836367e263356eb2377cc4e08e8368..8632301489fa66e9973b40330ac28a75026c20af 100644 (file)
@@ -495,7 +495,9 @@ EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
  * Returns 0 if successful, or a negative error code.
  */
 int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
-                                int (*func)(struct snd_kcontrol *, void *),
+                                int (*func)(struct snd_kcontrol *vslave,
+                                            struct snd_kcontrol *slave,
+                                            void *arg),
                                 void *arg)
 {
        struct link_master *master;
@@ -507,7 +509,7 @@ int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
        if (err < 0)
                return err;
        list_for_each_entry(slave, &master->slaves, list) {
-               err = func(&slave->slave, arg);
+               err = func(slave->kctl, &slave->slave, arg);
                if (err < 0)
                        return err;
        }
index c1f8e5479bf31b204e2224a8d3b1dcece12e365b..e018ecbf78a8f88e801990f1603218faaebba5f4 100644 (file)
@@ -1823,7 +1823,9 @@ struct slave_init_arg {
 };
 
 /* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */
-static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
+static int init_slave_0dB(struct snd_kcontrol *slave,
+                         struct snd_kcontrol *kctl,
+                         void *_arg)
 {
        struct slave_init_arg *arg = _arg;
        int _tlv[4];
@@ -1860,7 +1862,7 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
        arg->step = step;
        val = -tlv[2] / step;
        if (val > 0) {
-               put_kctl_with_value(kctl, val);
+               put_kctl_with_value(slave, val);
                return val;
        }
 
@@ -1868,7 +1870,9 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
 }
 
 /* unmute the slave via snd_ctl_apply_vmaster_slaves() */
-static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg)
+static int init_slave_unmute(struct snd_kcontrol *slave,
+                            struct snd_kcontrol *kctl,
+                            void *_arg)
 {
        return put_kctl_with_value(slave, 1);
 }