aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-11-22 06:34:56 -0500
committerTakashi Iwai <tiwai@suse.de>2017-11-22 06:34:56 -0500
commitd6c0615f510bc1ee26cfb2b9a3343ac99b9c46fb (patch)
tree79ffddb58976eb188fa15564b3d51db9772f5187
parent0a62d6c966956d77397c32836a5bbfe3af786fc1 (diff)
ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization
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>
-rw-r--r--include/sound/control.h4
-rw-r--r--sound/core/vmaster.c6
-rw-r--r--sound/pci/hda/hda_codec.c10
3 files changed, 14 insertions, 6 deletions
diff --git a/include/sound/control.h b/include/sound/control.h
index a1f1152bc687..ca13a44ae9d4 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -249,7 +249,9 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
249void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only); 249void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
250#define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true) 250#define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
251int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, 251int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
252 int (*func)(struct snd_kcontrol *, void *), 252 int (*func)(struct snd_kcontrol *vslave,
253 struct snd_kcontrol *slave,
254 void *arg),
253 void *arg); 255 void *arg);
254 256
255/* 257/*
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index e43af18d4383..8632301489fa 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -495,7 +495,9 @@ EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
495 * Returns 0 if successful, or a negative error code. 495 * Returns 0 if successful, or a negative error code.
496 */ 496 */
497int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, 497int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
498 int (*func)(struct snd_kcontrol *, void *), 498 int (*func)(struct snd_kcontrol *vslave,
499 struct snd_kcontrol *slave,
500 void *arg),
499 void *arg) 501 void *arg)
500{ 502{
501 struct link_master *master; 503 struct link_master *master;
@@ -507,7 +509,7 @@ int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
507 if (err < 0) 509 if (err < 0)
508 return err; 510 return err;
509 list_for_each_entry(slave, &master->slaves, list) { 511 list_for_each_entry(slave, &master->slaves, list) {
510 err = func(&slave->slave, arg); 512 err = func(slave->kctl, &slave->slave, arg);
511 if (err < 0) 513 if (err < 0)
512 return err; 514 return err;
513 } 515 }
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c1f8e5479bf3..e018ecbf78a8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1823,7 +1823,9 @@ struct slave_init_arg {
1823}; 1823};
1824 1824
1825/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */ 1825/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */
1826static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) 1826static int init_slave_0dB(struct snd_kcontrol *slave,
1827 struct snd_kcontrol *kctl,
1828 void *_arg)
1827{ 1829{
1828 struct slave_init_arg *arg = _arg; 1830 struct slave_init_arg *arg = _arg;
1829 int _tlv[4]; 1831 int _tlv[4];
@@ -1860,7 +1862,7 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
1860 arg->step = step; 1862 arg->step = step;
1861 val = -tlv[2] / step; 1863 val = -tlv[2] / step;
1862 if (val > 0) { 1864 if (val > 0) {
1863 put_kctl_with_value(kctl, val); 1865 put_kctl_with_value(slave, val);
1864 return val; 1866 return val;
1865 } 1867 }
1866 1868
@@ -1868,7 +1870,9 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
1868} 1870}
1869 1871
1870/* unmute the slave via snd_ctl_apply_vmaster_slaves() */ 1872/* unmute the slave via snd_ctl_apply_vmaster_slaves() */
1871static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg) 1873static int init_slave_unmute(struct snd_kcontrol *slave,
1874 struct snd_kcontrol *kctl,
1875 void *_arg)
1872{ 1876{
1873 return put_kctl_with_value(slave, 1); 1877 return put_kctl_with_value(slave, 1);
1874} 1878}