ALSA: hda - Revisit output_path parsing in patch_via.c
Change the order of the output-path list in a way from the DAC to the target pin. Also now the list include the target pin, too. Together with this format change, simplify the arguments of parse_output_path() function, and fix the initialization in via_auto_init_output(). Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
30f7c5d491
commit
8e3679dca2
|
@ -81,10 +81,12 @@ enum VIA_HDA_CODEC {
|
||||||
(spec)->codec_type == VT1812 ||\
|
(spec)->codec_type == VT1812 ||\
|
||||||
(spec)->codec_type == VT1802)
|
(spec)->codec_type == VT1802)
|
||||||
|
|
||||||
|
#define MAX_NID_PATH_DEPTH 5
|
||||||
|
|
||||||
struct nid_path {
|
struct nid_path {
|
||||||
int depth;
|
int depth;
|
||||||
hda_nid_t path[5];
|
hda_nid_t path[MAX_NID_PATH_DEPTH];
|
||||||
short idx[5];
|
short idx[MAX_NID_PATH_DEPTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct via_spec {
|
struct via_spec {
|
||||||
|
@ -415,15 +417,22 @@ static void unmute_and_select(struct hda_codec *codec, hda_nid_t nid,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* select the route explicitly when multiple connections exist */
|
/* select the route explicitly when multiple connections exist */
|
||||||
if (num_conns > 1)
|
if (num_conns > 1 &&
|
||||||
|
get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
|
||||||
snd_hda_codec_write(codec, nid, 0,
|
snd_hda_codec_write(codec, nid, 0,
|
||||||
AC_VERB_SET_CONNECT_SEL, idx);
|
AC_VERB_SET_CONNECT_SEL, idx);
|
||||||
|
|
||||||
/* unmute if the input amp is present */
|
/* unmute if the input amp is present */
|
||||||
if (!(query_amp_caps(codec, nid, HDA_INPUT) &
|
if (query_amp_caps(codec, nid, HDA_INPUT) &
|
||||||
(AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE)))
|
(AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
|
||||||
return;
|
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
AMP_IN_UNMUTE(idx));
|
||||||
AMP_IN_UNMUTE(idx));
|
|
||||||
|
/* unmute the src output */
|
||||||
|
if (query_amp_caps(codec, src, HDA_OUTPUT) &
|
||||||
|
(AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
|
||||||
|
snd_hda_codec_write(codec, src, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||||
|
AMP_OUT_UNMUTE);
|
||||||
|
|
||||||
/* unmute AA-path if present */
|
/* unmute AA-path if present */
|
||||||
if (!mix)
|
if (!mix)
|
||||||
|
@ -469,15 +478,9 @@ static void via_auto_init_output(struct hda_codec *codec, hda_nid_t pin,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the output path */
|
/* initialize the output path */
|
||||||
nid = pin;
|
for (i = path->depth - 1; i > 0; i--) {
|
||||||
for (i = 0; i < path->depth; i++) {
|
nid = path->path[i - 1];
|
||||||
unmute_and_select(codec, nid, path->idx[i], spec->aa_mix_nid);
|
unmute_and_select(codec, path->path[i], nid, spec->aa_mix_nid);
|
||||||
nid = path->path[i];
|
|
||||||
if (query_amp_caps(codec, nid, HDA_OUTPUT) &
|
|
||||||
(AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
|
|
||||||
snd_hda_codec_write(codec, nid, 0,
|
|
||||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
|
||||||
AMP_OUT_UNMUTE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,7 +1547,7 @@ static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
|
static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
|
||||||
hda_nid_t target_dac, struct nid_path *path,
|
hda_nid_t target_dac, struct nid_path *path,
|
||||||
int depth, int wid_type)
|
int depth, int wid_type)
|
||||||
{
|
{
|
||||||
|
@ -1556,13 +1559,13 @@ static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
|
||||||
if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
|
if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
|
||||||
continue;
|
continue;
|
||||||
if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
|
if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
|
||||||
path->path[depth] = conn[i];
|
path->path[0] = conn[i];
|
||||||
path->idx[depth] = i;
|
path->idx[0] = i;
|
||||||
path->depth = ++depth;
|
path->depth = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (depth > 4)
|
if (depth >= MAX_NID_PATH_DEPTH)
|
||||||
return false;
|
return false;
|
||||||
for (i = 0; i < nums; i++) {
|
for (i = 0; i < nums; i++) {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
@ -1570,16 +1573,28 @@ static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
|
||||||
if (type == AC_WID_AUD_OUT ||
|
if (type == AC_WID_AUD_OUT ||
|
||||||
(wid_type != -1 && type != wid_type))
|
(wid_type != -1 && type != wid_type))
|
||||||
continue;
|
continue;
|
||||||
if (parse_output_path(codec, conn[i], target_dac,
|
if (__parse_output_path(codec, conn[i], target_dac,
|
||||||
path, depth + 1, AC_WID_AUD_SEL)) {
|
path, depth + 1, AC_WID_AUD_SEL)) {
|
||||||
path->path[depth] = conn[i];
|
path->path[path->depth] = conn[i];
|
||||||
path->idx[depth] = i;
|
path->idx[path->depth] = i;
|
||||||
|
path->depth++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
|
||||||
|
hda_nid_t target_dac, struct nid_path *path)
|
||||||
|
{
|
||||||
|
if (__parse_output_path(codec, nid, target_dac, path, 1, -1)) {
|
||||||
|
path->path[path->depth] = nid;
|
||||||
|
path->depth++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int via_auto_fill_dac_nids(struct hda_codec *codec)
|
static int via_auto_fill_dac_nids(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct via_spec *spec = codec->spec;
|
struct via_spec *spec = codec->spec;
|
||||||
|
@ -1593,9 +1608,8 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
|
||||||
nid = cfg->line_out_pins[i];
|
nid = cfg->line_out_pins[i];
|
||||||
if (!nid)
|
if (!nid)
|
||||||
continue;
|
continue;
|
||||||
if (parse_output_path(codec, nid, 0, &spec->out_path[i], 0, -1))
|
if (parse_output_path(codec, nid, 0, &spec->out_path[i]))
|
||||||
spec->private_dac_nids[i] =
|
spec->private_dac_nids[i] = spec->out_path[i].path[0];
|
||||||
spec->out_path[i].path[spec->out_path[i].depth - 1];
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1748,15 +1762,14 @@ static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
|
||||||
if (!pin)
|
if (!pin)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (parse_output_path(codec, pin, 0, &spec->hp_path, 0, -1)) {
|
if (parse_output_path(codec, pin, 0, &spec->hp_path)) {
|
||||||
spec->hp_dac_nid = spec->hp_path.path[spec->hp_path.depth - 1];
|
spec->hp_dac_nid = spec->hp_path.path[0];
|
||||||
spec->hp_independent_mode_index =
|
spec->hp_independent_mode_index = spec->hp_path.idx[0];
|
||||||
spec->hp_path.idx[spec->hp_path.depth - 1];
|
|
||||||
create_hp_imux(spec);
|
create_hp_imux(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
|
if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
|
||||||
&spec->hp_dep_path, 0, -1) &&
|
&spec->hp_dep_path) &&
|
||||||
!spec->hp_dac_nid)
|
!spec->hp_dac_nid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1777,14 +1790,14 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec)
|
||||||
if (!spec->autocfg.speaker_outs || !pin)
|
if (!spec->autocfg.speaker_outs || !pin)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (parse_output_path(codec, pin, 0, &spec->speaker_path, 0, -1)) {
|
if (parse_output_path(codec, pin, 0, &spec->speaker_path)) {
|
||||||
dac = spec->speaker_path.path[spec->speaker_path.depth - 1];
|
dac = spec->speaker_path.path[0];
|
||||||
spec->multiout.extra_out_nid[0] = dac;
|
spec->multiout.extra_out_nid[0] = dac;
|
||||||
return create_ch_ctls(codec, "Speaker", pin, dac, 3);
|
return create_ch_ctls(codec, "Speaker", pin, dac, 3);
|
||||||
}
|
}
|
||||||
if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
|
if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
|
||||||
&spec->speaker_path, 0, -1))
|
&spec->speaker_path))
|
||||||
return create_ch_ctls(codec, "Headphone", pin, 0, 3);
|
return create_ch_ctls(codec, "Speaker", pin, 0, 3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue