return 0;
}
+static void update_aamix_paths(struct hda_codec *codec, bool do_mix,
+ int nomix_path_idx, int mix_path_idx,
+ int out_type);
+
static int indep_hp_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
}
if (spec->indep_hp_enabled != select) {
+ hda_nid_t *dacp;
+ if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
+ dacp = &spec->private_dac_nids[0];
+ else
+ dacp = &spec->multiout.hp_out_nid[0];
+
+ /* update HP aamix paths in case it conflicts with indep HP */
+ if (spec->have_aamix_ctl) {
+ if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
+ update_aamix_paths(codec, spec->aamix_mode,
+ spec->out_paths[0],
+ spec->aamix_out_paths[0],
+ spec->autocfg.line_out_type);
+ else
+ update_aamix_paths(codec, spec->aamix_mode,
+ spec->hp_paths[0],
+ spec->aamix_out_paths[1],
+ AUTO_PIN_HP_OUT);
+ }
+
spec->indep_hp_enabled = select;
if (spec->indep_hp_enabled)
- spec->multiout.hp_out_nid[0] = 0;
+ *dacp = 0;
else
- spec->multiout.hp_out_nid[0] = spec->alt_dac_nid;
+ *dacp = spec->alt_dac_nid;
ret = 1;
}
unlock:
static int create_indep_hp_ctls(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;
+ hda_nid_t dac;
if (!spec->indep_hp)
return 0;
- if (!spec->multiout.hp_out_nid[0]) {
+ if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
+ dac = spec->multiout.dac_nids[0];
+ else
+ dac = spec->multiout.hp_out_nid[0];
+ if (!dac) {
spec->indep_hp = 0;
return 0;
}
spec->indep_hp_enabled = false;
- spec->alt_dac_nid = spec->multiout.hp_out_nid[0];
+ spec->alt_dac_nid = dac;
if (!snd_hda_gen_add_kctl(spec, NULL, &indep_hp_ctl))
return -ENOMEM;
return 0;
}
static void update_aamix_paths(struct hda_codec *codec, bool do_mix,
- int nomix_path_idx, int mix_path_idx)
+ int nomix_path_idx, int mix_path_idx,
+ int out_type)
{
+ struct hda_gen_spec *spec = codec->spec;
struct nid_path *nomix_path, *mix_path;
nomix_path = snd_hda_get_path_from_idx(codec, nomix_path_idx);
mix_path = snd_hda_get_path_from_idx(codec, mix_path_idx);
if (!nomix_path || !mix_path)
return;
+
+ /* if HP aamix path is driven from a different DAC and the
+ * independent HP mode is ON, can't turn on aamix path
+ */
+ if (out_type == AUTO_PIN_HP_OUT && spec->indep_hp_enabled &&
+ mix_path->path[0] != spec->alt_dac_nid)
+ do_mix = false;
+
if (do_mix) {
snd_hda_activate_path(codec, nomix_path, false, true);
snd_hda_activate_path(codec, mix_path, true, true);
return 0;
spec->aamix_mode = val;
update_aamix_paths(codec, val, spec->out_paths[0],
- spec->aamix_out_paths[0]);
+ spec->aamix_out_paths[0],
+ spec->autocfg.line_out_type);
update_aamix_paths(codec, val, spec->hp_paths[0],
- spec->aamix_out_paths[1]);
+ spec->aamix_out_paths[1],
+ AUTO_PIN_HP_OUT);
update_aamix_paths(codec, val, spec->speaker_paths[0],
- spec->aamix_out_paths[2]);
+ spec->aamix_out_paths[2],
+ AUTO_PIN_SPEAKER_OUT);
return 1;
}
return 0;
if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum))
return -ENOMEM;
+ spec->have_aamix_ctl = 1;
return 0;
}