ALSA: hda - Fix aamix activation with loopback control on VIA codecs
When we have a loopback mixer control, this should manage the state whether the output paths include the aamix or not. But the current code blindly initializes the output paths with aamix = true, thus the aamix is enabled unless the loopback mixer control is changed. Also, update_aamix_paths() called by the loopback mixer control put callback invokes snd_hda_activate_path() with aamix = true even for disabling the mixing. This leaves the aamix path even though the loopback control is turned off. This patch fixes these issues: - Introduced aamix_default() helper to indicate whether with_aamix is true or false as default - Fix the argument in update_aamix_paths() for disabling loopback Reported-by: Lydia Wang <LydiaWang@viatech.com.cn> Cc: <stable@vger.kernel.org> [v3.9+] Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
ae03bbb8f9
commit
65033cc8d5
|
@ -2082,6 +2082,14 @@ get_multiio_path(struct hda_codec *codec, int idx)
|
|||
|
||||
static void update_automute_all(struct hda_codec *codec);
|
||||
|
||||
/* Default value to be passed as aamix argument for snd_hda_activate_path();
|
||||
* used for output paths
|
||||
*/
|
||||
static bool aamix_default(struct hda_gen_spec *spec)
|
||||
{
|
||||
return !spec->have_aamix_ctl || spec->aamix_mode;
|
||||
}
|
||||
|
||||
static int set_multi_io(struct hda_codec *codec, int idx, bool output)
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
|
@ -2097,11 +2105,11 @@ static int set_multi_io(struct hda_codec *codec, int idx, bool output)
|
|||
|
||||
if (output) {
|
||||
set_pin_target(codec, nid, PIN_OUT, true);
|
||||
snd_hda_activate_path(codec, path, true, true);
|
||||
snd_hda_activate_path(codec, path, true, aamix_default(spec));
|
||||
set_pin_eapd(codec, nid, true);
|
||||
} else {
|
||||
set_pin_eapd(codec, nid, false);
|
||||
snd_hda_activate_path(codec, path, false, true);
|
||||
snd_hda_activate_path(codec, path, false, aamix_default(spec));
|
||||
set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true);
|
||||
path_power_down_sync(codec, path);
|
||||
}
|
||||
|
@ -2192,8 +2200,8 @@ static void update_aamix_paths(struct hda_codec *codec, bool do_mix,
|
|||
snd_hda_activate_path(codec, mix_path, true, true);
|
||||
path_power_down_sync(codec, nomix_path);
|
||||
} else {
|
||||
snd_hda_activate_path(codec, mix_path, false, true);
|
||||
snd_hda_activate_path(codec, nomix_path, true, true);
|
||||
snd_hda_activate_path(codec, mix_path, false, false);
|
||||
snd_hda_activate_path(codec, nomix_path, true, false);
|
||||
path_power_down_sync(codec, mix_path);
|
||||
}
|
||||
}
|
||||
|
@ -4923,7 +4931,8 @@ static void set_output_and_unmute(struct hda_codec *codec, int path_idx)
|
|||
return;
|
||||
pin = path->path[path->depth - 1];
|
||||
restore_pin_ctl(codec, pin);
|
||||
snd_hda_activate_path(codec, path, path->active, true);
|
||||
snd_hda_activate_path(codec, path, path->active,
|
||||
aamix_default(codec->spec));
|
||||
set_pin_eapd(codec, pin, path->active);
|
||||
}
|
||||
|
||||
|
@ -4973,7 +4982,8 @@ static void init_multi_io(struct hda_codec *codec)
|
|||
if (!spec->multi_io[i].ctl_in)
|
||||
spec->multi_io[i].ctl_in =
|
||||
snd_hda_codec_get_pin_target(codec, pin);
|
||||
snd_hda_activate_path(codec, path, path->active, true);
|
||||
snd_hda_activate_path(codec, path, path->active,
|
||||
aamix_default(spec));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue