From: Takashi Iwai <tiwai@xxxxxxx> commit 242d990c158d5b1dabd166516e21992baef5f26a upstream. The generic parser accepts the preferred_dacs[] pairs as a hint for assigning a DAC to each pin, but this hint doesn't work always effectively. Currently it's merely a secondary choice after the trial with the path index failed. This made sometimes it difficult to assign DACs without mimicking the connection list and/or the badness table. This patch adds a new flag, obey_preferred_dacs, that changes the behavior of the parser. As its name stands, the parser obeys the given preferred_dacs[] pairs by skipping the path index matching and giving a high penalty if no DAC is assigned by the pairs. This mode will help for assigning the fixed DACs forcibly from the codec driver. Cc: <stable@xxxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/20201127141104.11041-1-tiwai@xxxxxxx Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- sound/pci/hda/hda_generic.c | 12 ++++++++---- sound/pci/hda/hda_generic.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1374,16 +1374,20 @@ static int try_assign_dacs(struct hda_co struct nid_path *path; hda_nid_t pin = pins[i]; - path = snd_hda_get_path_from_idx(codec, path_idx[i]); - if (path) { - badness += assign_out_path_ctls(codec, path); - continue; + if (!spec->obey_preferred_dacs) { + path = snd_hda_get_path_from_idx(codec, path_idx[i]); + if (path) { + badness += assign_out_path_ctls(codec, path); + continue; + } } dacs[i] = get_preferred_dac(codec, pin); if (dacs[i]) { if (is_dac_already_used(codec, dacs[i])) badness += bad->shared_primary; + } else if (spec->obey_preferred_dacs) { + badness += BAD_NO_PRIMARY_DAC; } if (!dacs[i]) --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -230,6 +230,7 @@ struct hda_gen_spec { unsigned int power_down_unused:1; /* power down unused widgets */ unsigned int dac_min_mute:1; /* minimal = mute for DACs */ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */ + unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */ /* other internal flags */ unsigned int no_analog:1; /* digital I/O only */