summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-21 13:45:56 +0200
committerTakashi Iwai <tiwai@suse.de>2011-07-21 13:55:10 +0200
commit020066d1ecc95d74da9be6beb436ac575af01271 (patch)
tree706657b35946c4f4ff7606af44a27aefa35f5057
parentALSA: hda - Add documentation for codec-specific mixer controls (diff)
downloadlinux-020066d1ecc95d74da9be6beb436ac575af01271.tar.xz
linux-020066d1ecc95d74da9be6beb436ac575af01271.zip
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>
-rw-r--r--sound/pci/hda/patch_via.c92
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;
}