|
@@ -2906,7 +2906,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
|
|
|
if (!nid)
|
|
|
continue;
|
|
|
if (found_in_nid_list(nid, spec->multiout.dac_nids,
|
|
|
- spec->multiout.num_dacs))
|
|
|
+ ARRAY_SIZE(spec->private_dac_nids)))
|
|
|
continue;
|
|
|
if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
|
|
|
ARRAY_SIZE(spec->multiout.hp_out_nid)))
|
|
@@ -2927,6 +2927,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/* return 0 if no possible DAC is found, 1 if one or more found */
|
|
|
static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
|
|
|
const hda_nid_t *pins, hda_nid_t *dacs)
|
|
|
{
|
|
@@ -2944,7 +2945,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
|
|
|
if (!dacs[i])
|
|
|
dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
|
|
|
}
|
|
|
- return 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
static int alc_auto_fill_multi_ios(struct hda_codec *codec,
|
|
@@ -2954,7 +2955,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
|
|
|
static int alc_auto_fill_dac_nids(struct hda_codec *codec)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
- const struct auto_pin_cfg *cfg = &spec->autocfg;
|
|
|
+ struct auto_pin_cfg *cfg = &spec->autocfg;
|
|
|
bool redone = false;
|
|
|
int i;
|
|
|
|
|
@@ -2965,6 +2966,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
|
|
|
spec->multiout.extra_out_nid[0] = 0;
|
|
|
memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
|
|
|
spec->multiout.dac_nids = spec->private_dac_nids;
|
|
|
+ spec->multi_ios = 0;
|
|
|
|
|
|
/* fill hard-wired DACs first */
|
|
|
if (!redone) {
|
|
@@ -2998,10 +3000,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
|
|
|
for (i = 0; i < cfg->line_outs; i++) {
|
|
|
if (spec->private_dac_nids[i])
|
|
|
spec->multiout.num_dacs++;
|
|
|
- else
|
|
|
+ else {
|
|
|
memmove(spec->private_dac_nids + i,
|
|
|
spec->private_dac_nids + i + 1,
|
|
|
sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
|
|
|
+ spec->private_dac_nids[cfg->line_outs - 1] = 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
|
|
@@ -3023,9 +3027,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
|
|
|
if (cfg->line_out_type != AUTO_PIN_HP_OUT)
|
|
|
alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
|
|
|
spec->multiout.hp_out_nid);
|
|
|
- if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
|
|
|
- alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins,
|
|
|
- spec->multiout.extra_out_nid);
|
|
|
+ if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
|
|
|
+ int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
|
|
|
+ cfg->speaker_pins,
|
|
|
+ spec->multiout.extra_out_nid);
|
|
|
+ /* if no speaker volume is assigned, try again as the primary
|
|
|
+ * output
|
|
|
+ */
|
|
|
+ if (!err && cfg->speaker_outs > 0 &&
|
|
|
+ cfg->line_out_type == AUTO_PIN_HP_OUT) {
|
|
|
+ cfg->hp_outs = cfg->line_outs;
|
|
|
+ memcpy(cfg->hp_pins, cfg->line_out_pins,
|
|
|
+ sizeof(cfg->hp_pins));
|
|
|
+ cfg->line_outs = cfg->speaker_outs;
|
|
|
+ memcpy(cfg->line_out_pins, cfg->speaker_pins,
|
|
|
+ sizeof(cfg->speaker_pins));
|
|
|
+ cfg->speaker_outs = 0;
|
|
|
+ memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
|
|
|
+ cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
|
|
|
+ redone = false;
|
|
|
+ goto again;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|