mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
ALSA: hda/realtek - Refactor the DAC filler function
Refactor the DAC filling function to be used for both the primary line outputs and extra outputs using the individual badness tables. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
f02aab5d7f
commit
dc31b58dbc
@ -2969,6 +2969,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
|
|||||||
hda_nid_t srcs[5];
|
hda_nid_t srcs[5];
|
||||||
int i, num;
|
int i, num;
|
||||||
|
|
||||||
|
if (!pin || !dac)
|
||||||
|
return false;
|
||||||
pin = alc_go_down_to_selector(codec, pin);
|
pin = alc_go_down_to_selector(codec, pin);
|
||||||
num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
|
num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
@ -3087,60 +3089,88 @@ static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
|
|||||||
return badness;
|
return badness;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to assign DACs to extra pins and return the resultant badness */
|
struct badness_table {
|
||||||
static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
|
int no_primary_dac; /* no primary DAC */
|
||||||
const hda_nid_t *pins, hda_nid_t *dacs)
|
int no_dac; /* no secondary DACs */
|
||||||
|
int shared_primary; /* primary DAC is shared with main output */
|
||||||
|
int shared_surr; /* secondary DAC shared with main or primary */
|
||||||
|
int shared_clfe; /* third DAC shared with main or primary */
|
||||||
|
int shared_surr_main; /* secondary DAC sahred with main/DAC0 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct badness_table main_out_badness = {
|
||||||
|
.no_primary_dac = BAD_NO_PRIMARY_DAC,
|
||||||
|
.no_dac = BAD_NO_DAC,
|
||||||
|
.shared_primary = BAD_NO_PRIMARY_DAC,
|
||||||
|
.shared_surr = BAD_SHARED_SURROUND,
|
||||||
|
.shared_clfe = BAD_SHARED_CLFE,
|
||||||
|
.shared_surr_main = BAD_SHARED_SURROUND,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct badness_table extra_out_badness = {
|
||||||
|
.no_primary_dac = BAD_NO_DAC,
|
||||||
|
.no_dac = BAD_NO_DAC,
|
||||||
|
.shared_primary = BAD_NO_EXTRA_DAC,
|
||||||
|
.shared_surr = BAD_SHARED_EXTRA_SURROUND,
|
||||||
|
.shared_clfe = BAD_SHARED_EXTRA_SURROUND,
|
||||||
|
.shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* try to assign DACs to pins and return the resultant badness */
|
||||||
|
static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
|
||||||
|
const hda_nid_t *pins, hda_nid_t *dacs,
|
||||||
|
const struct badness_table *bad)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
int i;
|
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
|
int i, j;
|
||||||
int badness = 0;
|
int badness = 0;
|
||||||
hda_nid_t dac;
|
hda_nid_t dac;
|
||||||
|
|
||||||
if (!num_outs)
|
if (!num_outs)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!dacs[0])
|
for (i = 0; i < num_outs; i++) {
|
||||||
dacs[0] = alc_auto_look_for_dac(codec, pins[0]);
|
hda_nid_t pin = pins[i];
|
||||||
if (!dacs[0]) {
|
if (!dacs[i])
|
||||||
for (i = 1; i < num_outs; i++) {
|
dacs[i] = alc_auto_look_for_dac(codec, pin);
|
||||||
dac = dacs[i];
|
if (!dacs[i] && !i) {
|
||||||
if (dac && alc_auto_is_dac_reachable(codec, pins[0], dac)) {
|
for (j = 1; j < num_outs; j++) {
|
||||||
dacs[0] = dac;
|
if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
|
||||||
dacs[i] = 0;
|
dacs[0] = dacs[j];
|
||||||
break;
|
dacs[j] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
dac = dacs[0];
|
|
||||||
if (!dac) {
|
|
||||||
dac = spec->private_dac_nids[0];
|
|
||||||
if (!alc_auto_is_dac_reachable(codec, pins[0], dac))
|
|
||||||
return BAD_NO_DAC;
|
|
||||||
badness += BAD_NO_EXTRA_DAC;
|
|
||||||
}
|
|
||||||
if (dac)
|
|
||||||
badness += eval_shared_vol_badness(codec, pins[0], dac);
|
|
||||||
|
|
||||||
for (i = 1; i < num_outs; i++)
|
|
||||||
dacs[i] = get_dac_if_single(codec, pins[i]);
|
|
||||||
for (i = 1; i < num_outs; i++) {
|
|
||||||
dac = dacs[i];
|
dac = dacs[i];
|
||||||
if (!dac)
|
|
||||||
dac = dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
|
|
||||||
if (!dac) {
|
if (!dac) {
|
||||||
if (alc_auto_is_dac_reachable(codec, pins[i], dacs[0])) {
|
if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
|
||||||
dac = dacs[0];
|
dac = dacs[0];
|
||||||
badness += BAD_SHARED_EXTRA_SURROUND;
|
else if (cfg->line_outs > i &&
|
||||||
} else if (alc_auto_is_dac_reachable(codec, pins[i],
|
alc_auto_is_dac_reachable(codec, pin,
|
||||||
|
spec->private_dac_nids[i]))
|
||||||
|
dac = spec->private_dac_nids[i];
|
||||||
|
if (dac) {
|
||||||
|
if (!i)
|
||||||
|
badness += bad->shared_primary;
|
||||||
|
else if (i == 1)
|
||||||
|
badness += bad->shared_surr;
|
||||||
|
else
|
||||||
|
badness += bad->shared_clfe;
|
||||||
|
} else if (alc_auto_is_dac_reachable(codec, pin,
|
||||||
spec->private_dac_nids[0])) {
|
spec->private_dac_nids[0])) {
|
||||||
dac = spec->private_dac_nids[0];
|
dac = spec->private_dac_nids[0];
|
||||||
badness += BAD_NO_EXTRA_SURR_DAC;
|
badness += bad->shared_surr_main;
|
||||||
} else
|
} else if (!i)
|
||||||
badness += BAD_NO_DAC;
|
badness += bad->no_primary_dac;
|
||||||
|
else
|
||||||
|
badness += bad->no_dac;
|
||||||
}
|
}
|
||||||
if (dac)
|
if (dac)
|
||||||
badness += eval_shared_vol_badness(codec, pins[i], dac);
|
badness += eval_shared_vol_badness(codec, pin, dac);
|
||||||
}
|
}
|
||||||
|
|
||||||
return badness;
|
return badness;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3170,7 +3200,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
|
|||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
struct auto_pin_cfg *cfg = &spec->autocfg;
|
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
int i, j, err, badness;
|
int i, err, badness;
|
||||||
|
|
||||||
/* set num_dacs once to full for alc_auto_look_for_dac() */
|
/* set num_dacs once to full for alc_auto_look_for_dac() */
|
||||||
spec->multiout.num_dacs = cfg->line_outs;
|
spec->multiout.num_dacs = cfg->line_outs;
|
||||||
@ -3204,40 +3234,9 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
|
|||||||
} while (mapped);
|
} while (mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < cfg->line_outs; i++) {
|
badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
|
||||||
hda_nid_t pin = cfg->line_out_pins[i];
|
spec->private_dac_nids,
|
||||||
hda_nid_t dac;
|
&main_out_badness);
|
||||||
if (!spec->private_dac_nids[i])
|
|
||||||
spec->private_dac_nids[i] =
|
|
||||||
alc_auto_look_for_dac(codec, pin);
|
|
||||||
dac = spec->private_dac_nids[i];
|
|
||||||
if (!dac && !i) {
|
|
||||||
for (j = 1; j < cfg->line_outs; j++) {
|
|
||||||
hda_nid_t dac2 = spec->private_dac_nids[j];
|
|
||||||
if (dac2 &&
|
|
||||||
alc_auto_is_dac_reachable(codec, pin, dac2)) {
|
|
||||||
dac = spec->private_dac_nids[0] = dac2;
|
|
||||||
spec->private_dac_nids[j] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!dac) {
|
|
||||||
if (!i)
|
|
||||||
badness += BAD_NO_PRIMARY_DAC;
|
|
||||||
else if (alc_auto_is_dac_reachable(codec, pin,
|
|
||||||
spec->private_dac_nids[0])) {
|
|
||||||
if (i == 1)
|
|
||||||
badness += BAD_SHARED_SURROUND;
|
|
||||||
else
|
|
||||||
badness += BAD_SHARED_CLFE;
|
|
||||||
dac = spec->private_dac_nids[0];
|
|
||||||
} else
|
|
||||||
badness += BAD_NO_DAC;
|
|
||||||
}
|
|
||||||
if (dac)
|
|
||||||
badness += eval_shared_vol_badness(codec, pin, dac);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* re-count num_dacs and squash invalid entries */
|
/* re-count num_dacs and squash invalid entries */
|
||||||
spec->multiout.num_dacs = 0;
|
spec->multiout.num_dacs = 0;
|
||||||
@ -3262,17 +3261,18 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
|
if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
|
||||||
err = alc_auto_fill_extra_dacs(codec, cfg->hp_outs,
|
err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
|
||||||
cfg->hp_pins,
|
spec->multiout.hp_out_nid,
|
||||||
spec->multiout.hp_out_nid);
|
&extra_out_badness);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
badness += err;
|
badness += err;
|
||||||
}
|
}
|
||||||
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
|
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
|
||||||
err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
|
err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
|
||||||
cfg->speaker_pins,
|
cfg->speaker_pins,
|
||||||
spec->multiout.extra_out_nid);
|
spec->multiout.extra_out_nid,
|
||||||
|
&extra_out_badness);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
badness += err;
|
badness += err;
|
||||||
|
Loading…
Reference in New Issue
Block a user