mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-18 06:50:08 +00:00
ALSA: hda - Fix VIA output-path init for VT2002P/1802/1812
For VT2002P, VT1802 and VT1812 codecs, the original activate_output_path() function can't initialize output and hp path correctly, since mixers connected to output pin widgets are not considered. So modify the activate_output_path() function to satisify this kind of codec. Signed-off-by: Lydia Wang <lydiawang@viatech.com.cn> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
1d045db96a
commit
d69607b3c3
@ -438,11 +438,62 @@ static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
|
||||
#define have_mute(codec, nid, dir) \
|
||||
check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
|
||||
|
||||
static bool is_node_in_path(struct nid_path *path, hda_nid_t nid)
|
||||
{
|
||||
int i;
|
||||
if (!nid)
|
||||
return false;
|
||||
for (i = 0; i < path->depth; i++) {
|
||||
if (path->path[i] == nid)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* enable/disable the output-route mixers */
|
||||
static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
|
||||
hda_nid_t mix_nid, int aa_mix_idx, bool enable)
|
||||
{
|
||||
int i, num, val;
|
||||
bool hp_path, front_path;
|
||||
struct via_spec *spec = codec->spec;
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
num = snd_hda_get_conn_list(codec, mix_nid, NULL);
|
||||
hp_path = is_node_in_path(path, spec->hp_dac_nid);
|
||||
front_path = is_node_in_path(path, spec->multiout.dac_nids[0]);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (i == aa_mix_idx) {
|
||||
if (hp_path)
|
||||
val = enable ? AMP_IN_MUTE(i) :
|
||||
AMP_IN_UNMUTE(i);
|
||||
else if (front_path)
|
||||
val = AMP_IN_UNMUTE(i);
|
||||
else
|
||||
val = AMP_IN_MUTE(i);
|
||||
} else {
|
||||
if (hp_path)
|
||||
val = enable ? AMP_IN_UNMUTE(i) :
|
||||
AMP_IN_MUTE(i);
|
||||
else if (front_path)
|
||||
val = AMP_IN_MUTE(i);
|
||||
else
|
||||
val = AMP_IN_UNMUTE(i);
|
||||
}
|
||||
snd_hda_codec_write(codec, mix_nid, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, val);
|
||||
}
|
||||
}
|
||||
|
||||
/* enable/disable the output-route */
|
||||
static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
|
||||
bool enable, bool force)
|
||||
{
|
||||
int i;
|
||||
int i, val;
|
||||
struct via_spec *spec = codec->spec;
|
||||
hda_nid_t aa_mix_nid = spec->aa_mix_nid;
|
||||
for (i = 0; i < path->depth; i++) {
|
||||
hda_nid_t src, dst;
|
||||
int idx = path->idx[i];
|
||||
@ -459,10 +510,19 @@ static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
|
||||
&& get_wcaps_type(get_wcaps(codec, dst)) == AC_WID_AUD_MIX)
|
||||
continue;
|
||||
if (have_mute(codec, dst, HDA_INPUT)) {
|
||||
int val = enable ? AMP_IN_UNMUTE(idx) :
|
||||
AMP_IN_MUTE(idx);
|
||||
snd_hda_codec_write(codec, dst, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, val);
|
||||
if (dst == aa_mix_nid) {
|
||||
val = enable ? AMP_IN_UNMUTE(idx) :
|
||||
AMP_IN_MUTE(idx);
|
||||
snd_hda_codec_write(codec, dst, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, val);
|
||||
} else {
|
||||
idx = get_connection_index(codec, dst,
|
||||
aa_mix_nid);
|
||||
if (idx >= 0) {
|
||||
activate_output_mix(codec, path,
|
||||
dst, idx, enable);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!force && (src == path->vol_ctl || src == path->mute_ctl))
|
||||
continue;
|
||||
@ -493,8 +553,7 @@ static void via_auto_init_output(struct hda_codec *codec,
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
unsigned int caps;
|
||||
hda_nid_t pin, nid, pre_nid;
|
||||
int i, idx, j, num;
|
||||
hda_nid_t pin;
|
||||
|
||||
if (!path->depth)
|
||||
return;
|
||||
@ -509,39 +568,10 @@ static void via_auto_init_output(struct hda_codec *codec,
|
||||
AMP_OUT_MUTE | val);
|
||||
}
|
||||
|
||||
activate_output_path(codec, path, true, force);
|
||||
|
||||
/* initialize the AA-path */
|
||||
if (!spec->aa_mix_nid)
|
||||
return;
|
||||
for (i = path->depth - 1; i > 0; i--) {
|
||||
nid = path->path[i];
|
||||
pre_nid = path->path[i - 1];
|
||||
idx = get_connection_index(codec, nid, spec->aa_mix_nid);
|
||||
if (idx >= 0) {
|
||||
if (have_mute(codec, nid, HDA_INPUT)) {
|
||||
unsigned int mute = with_aa_mix ?
|
||||
AMP_IN_UNMUTE(idx) : AMP_IN_MUTE(idx);
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
mute);
|
||||
/* exclusively via aa-mix for front */
|
||||
if (pre_nid == spec->multiout.dac_nids[0]) {
|
||||
num = snd_hda_get_conn_list(codec, nid,
|
||||
NULL);
|
||||
for (j = 0; j < num; j++) {
|
||||
if (j == idx)
|
||||
continue;
|
||||
snd_hda_codec_write(codec,
|
||||
nid, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AMP_IN_MUTE(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
activate_output_path(codec, path, true, force);
|
||||
}
|
||||
|
||||
static void via_auto_init_multi_out(struct hda_codec *codec)
|
||||
|
Loading…
Reference in New Issue
Block a user