diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-04-16 06:31:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-16 06:38:38 -0400 |
commit | 65033cc8d5ffd9b754e04da4be9cd1e8b61eeaff (patch) | |
tree | a7fe7008769a45b453145d1e5a4e72672c2c52d2 | |
parent | ae03bbb8f93b9e2c85a58e7476b87f7fb1c063ab (diff) |
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>
-rw-r--r-- | sound/pci/hda/hda_generic.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index c7b59ddc4bce..b964e09cdec6 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -2082,6 +2082,14 @@ get_multiio_path(struct hda_codec *codec, int idx) | |||
2082 | 2082 | ||
2083 | static void update_automute_all(struct hda_codec *codec); | 2083 | static void update_automute_all(struct hda_codec *codec); |
2084 | 2084 | ||
2085 | /* Default value to be passed as aamix argument for snd_hda_activate_path(); | ||
2086 | * used for output paths | ||
2087 | */ | ||
2088 | static bool aamix_default(struct hda_gen_spec *spec) | ||
2089 | { | ||
2090 | return !spec->have_aamix_ctl || spec->aamix_mode; | ||
2091 | } | ||
2092 | |||
2085 | static int set_multi_io(struct hda_codec *codec, int idx, bool output) | 2093 | static int set_multi_io(struct hda_codec *codec, int idx, bool output) |
2086 | { | 2094 | { |
2087 | struct hda_gen_spec *spec = codec->spec; | 2095 | struct hda_gen_spec *spec = codec->spec; |
@@ -2097,11 +2105,11 @@ static int set_multi_io(struct hda_codec *codec, int idx, bool output) | |||
2097 | 2105 | ||
2098 | if (output) { | 2106 | if (output) { |
2099 | set_pin_target(codec, nid, PIN_OUT, true); | 2107 | set_pin_target(codec, nid, PIN_OUT, true); |
2100 | snd_hda_activate_path(codec, path, true, true); | 2108 | snd_hda_activate_path(codec, path, true, aamix_default(spec)); |
2101 | set_pin_eapd(codec, nid, true); | 2109 | set_pin_eapd(codec, nid, true); |
2102 | } else { | 2110 | } else { |
2103 | set_pin_eapd(codec, nid, false); | 2111 | set_pin_eapd(codec, nid, false); |
2104 | snd_hda_activate_path(codec, path, false, true); | 2112 | snd_hda_activate_path(codec, path, false, aamix_default(spec)); |
2105 | set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true); | 2113 | set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true); |
2106 | path_power_down_sync(codec, path); | 2114 | path_power_down_sync(codec, path); |
2107 | } | 2115 | } |
@@ -2192,8 +2200,8 @@ static void update_aamix_paths(struct hda_codec *codec, bool do_mix, | |||
2192 | snd_hda_activate_path(codec, mix_path, true, true); | 2200 | snd_hda_activate_path(codec, mix_path, true, true); |
2193 | path_power_down_sync(codec, nomix_path); | 2201 | path_power_down_sync(codec, nomix_path); |
2194 | } else { | 2202 | } else { |
2195 | snd_hda_activate_path(codec, mix_path, false, true); | 2203 | snd_hda_activate_path(codec, mix_path, false, false); |
2196 | snd_hda_activate_path(codec, nomix_path, true, true); | 2204 | snd_hda_activate_path(codec, nomix_path, true, false); |
2197 | path_power_down_sync(codec, mix_path); | 2205 | path_power_down_sync(codec, mix_path); |
2198 | } | 2206 | } |
2199 | } | 2207 | } |
@@ -4923,7 +4931,8 @@ static void set_output_and_unmute(struct hda_codec *codec, int path_idx) | |||
4923 | return; | 4931 | return; |
4924 | pin = path->path[path->depth - 1]; | 4932 | pin = path->path[path->depth - 1]; |
4925 | restore_pin_ctl(codec, pin); | 4933 | restore_pin_ctl(codec, pin); |
4926 | snd_hda_activate_path(codec, path, path->active, true); | 4934 | snd_hda_activate_path(codec, path, path->active, |
4935 | aamix_default(codec->spec)); | ||
4927 | set_pin_eapd(codec, pin, path->active); | 4936 | set_pin_eapd(codec, pin, path->active); |
4928 | } | 4937 | } |
4929 | 4938 | ||
@@ -4973,7 +4982,8 @@ static void init_multi_io(struct hda_codec *codec) | |||
4973 | if (!spec->multi_io[i].ctl_in) | 4982 | if (!spec->multi_io[i].ctl_in) |
4974 | spec->multi_io[i].ctl_in = | 4983 | spec->multi_io[i].ctl_in = |
4975 | snd_hda_codec_get_pin_target(codec, pin); | 4984 | snd_hda_codec_get_pin_target(codec, pin); |
4976 | snd_hda_activate_path(codec, path, path->active, true); | 4985 | snd_hda_activate_path(codec, path, path->active, |
4986 | aamix_default(spec)); | ||
4977 | } | 4987 | } |
4978 | } | 4988 | } |
4979 | 4989 | ||