diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-07-21 15:45:56 +0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-21 15:55:10 +0400 |
commit | 020066d1ecc95d74da9be6beb436ac575af01271 (patch) | |
tree | 706657b35946c4f4ff7606af44a27aefa35f5057 /sound | |
parent | 737c265bb8399b97231e5b10b5b2375914206427 (diff) | |
download | linux-020066d1ecc95d74da9be6beb436ac575af01271.tar.xz |
ALSA: hda - Fix indep-HP path (de-)activation for VT1708* codecs
This patch fixes non-working indep-HP control on VT1708* codecs.
The problems are that via_independent_hp_put() wasn't fixed to follow
the recent change of three HP paths, and hp_indep_path didn't contain
the amp nids of mixer elements.
Together with the fixes, a few code clean-ups are done.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_via.c | 92 |
1 files changed, 52 insertions, 40 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 5b0342635ebe..761339a0694d 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -566,31 +566,44 @@ static void via_auto_init_multi_out(struct hda_codec *codec) } } -static void via_auto_init_hp_out(struct hda_codec *codec) +/* deactivate the inactive headphone-paths */ +static void deactivate_hp_paths(struct hda_codec *codec) { struct via_spec *spec = codec->spec; int shared = spec->hp_indep_shared; - if (!spec->hp_path.depth) { - via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true); - return; - } if (spec->hp_independent_mode) { activate_output_path(codec, &spec->hp_path, false, false); activate_output_path(codec, &spec->hp_mix_path, false, false); if (shared) activate_output_path(codec, &spec->out_path[shared], false, false); - via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP, true); - } else if (spec->aamix_mode) { + } else if (spec->aamix_mode || !spec->hp_path.depth) { + activate_output_path(codec, &spec->hp_indep_path, false, false); activate_output_path(codec, &spec->hp_path, false, false); - via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true); } else { + activate_output_path(codec, &spec->hp_indep_path, false, false); activate_output_path(codec, &spec->hp_mix_path, false, false); - via_auto_init_output(codec, &spec->hp_path, PIN_HP, true); } } +static void via_auto_init_hp_out(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + + if (!spec->hp_path.depth) { + via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true); + return; + } + deactivate_hp_paths(codec); + if (spec->hp_independent_mode) + via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP, true); + else if (spec->aamix_mode) + via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true); + else + via_auto_init_output(codec, &spec->hp_path, PIN_HP, true); +} + static void via_auto_init_speaker_out(struct hda_codec *codec) { struct via_spec *spec = codec->spec; @@ -847,18 +860,19 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, } spec->hp_independent_mode = cur; shared = spec->hp_indep_shared; - if (cur) { - activate_output_path(codec, &spec->hp_mix_path, false, false); - if (shared) - activate_output_path(codec, &spec->out_path[shared], - false, false); - activate_output_path(codec, &spec->hp_path, true, false); - } else { - activate_output_path(codec, &spec->hp_path, false, false); + deactivate_hp_paths(codec); + if (cur) + activate_output_path(codec, &spec->hp_indep_path, true, false); + else { if (shared) activate_output_path(codec, &spec->out_path[shared], true, false); - activate_output_path(codec, &spec->hp_mix_path, true, false); + if (spec->aamix_mode || !spec->hp_path.depth) + activate_output_path(codec, &spec->hp_mix_path, + true, false); + else + activate_output_path(codec, &spec->hp_path, + true, false); } switch_indep_hp_dacs(codec); @@ -1928,6 +1942,12 @@ static void mangle_smart51(struct hda_codec *codec) } } +static void copy_path_mixer_ctls(struct nid_path *dst, struct nid_path *src) +{ + dst->vol_ctl = src->vol_ctl; + dst->mute_ctl = src->mute_ctl; +} + /* add playback controls from the parsed DAC table */ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) { @@ -1976,14 +1996,10 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) if (err < 0) return err; } - if (path != spec->out_path + i) { - spec->out_path[i].vol_ctl = path->vol_ctl; - spec->out_path[i].mute_ctl = path->mute_ctl; - } - if (path == spec->out_path && spec->out_mix_path.depth) { - spec->out_mix_path.vol_ctl = path->vol_ctl; - spec->out_mix_path.mute_ctl = path->mute_ctl; - } + if (path != spec->out_path + i) + copy_path_mixer_ctls(&spec->out_path[i], path); + if (path == spec->out_path && spec->out_mix_path.depth) + copy_path_mixer_ctls(&spec->out_mix_path, path); } idx = get_connection_index(codec, spec->aa_mix_nid, @@ -2058,13 +2074,12 @@ static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) err = create_ch_ctls(codec, "Headphone", 3, check_dac, path); if (err < 0) return err; - if (check_dac) { - spec->hp_mix_path.vol_ctl = path->vol_ctl; - spec->hp_mix_path.mute_ctl = path->mute_ctl; - } else { - spec->hp_path.vol_ctl = path->vol_ctl; - spec->hp_path.mute_ctl = path->mute_ctl; - } + if (check_dac) + copy_path_mixer_ctls(&spec->hp_mix_path, path); + else + copy_path_mixer_ctls(&spec->hp_path, path); + if (spec->hp_indep_path.depth) + copy_path_mixer_ctls(&spec->hp_indep_path, path); return 0; } @@ -2106,13 +2121,10 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec) err = create_ch_ctls(codec, "Speaker", 3, check_dac, path); if (err < 0) return err; - if (check_dac) { - spec->speaker_mix_path.vol_ctl = path->vol_ctl; - spec->speaker_mix_path.mute_ctl = path->mute_ctl; - } else { - spec->speaker_path.vol_ctl = path->vol_ctl; - spec->speaker_path.mute_ctl = path->mute_ctl; - } + if (check_dac) + copy_path_mixer_ctls(&spec->speaker_mix_path, path); + else + copy_path_mixer_ctls(&spec->speaker_path, path); return 0; } |