diff options
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
| -rw-r--r-- | sound/pci/hda/hda_generic.c | 46 | 
1 files changed, 46 insertions, 0 deletions
| diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 78897d05d80..43c2ea53956 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -995,6 +995,8 @@ enum {  	BAD_NO_EXTRA_SURR_DAC = 0x101,  	/* Primary DAC shared with main surrounds */  	BAD_SHARED_SURROUND = 0x100, +	/* No independent HP possible */ +	BAD_NO_INDEP_HP = 0x40,  	/* Primary DAC shared with main CLFE */  	BAD_SHARED_CLFE = 0x10,  	/* Primary DAC shared with extra surrounds */ @@ -1392,6 +1394,43 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)  	return snd_hda_get_path_idx(codec, path);  } +/* check whether the independent HP is available with the current config */ +static bool indep_hp_possible(struct hda_codec *codec) +{ +	struct hda_gen_spec *spec = codec->spec; +	struct auto_pin_cfg *cfg = &spec->autocfg; +	struct nid_path *path; +	int i, idx; + +	if (cfg->line_out_type == AUTO_PIN_HP_OUT) +		idx = spec->out_paths[0]; +	else +		idx = spec->hp_paths[0]; +	path = snd_hda_get_path_from_idx(codec, idx); +	if (!path) +		return false; + +	/* assume no path conflicts unless aamix is involved */ +	if (!spec->mixer_nid || !is_nid_contained(path, spec->mixer_nid)) +		return true; + +	/* check whether output paths contain aamix */ +	for (i = 0; i < cfg->line_outs; i++) { +		if (spec->out_paths[i] == idx) +			break; +		path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]); +		if (path && is_nid_contained(path, spec->mixer_nid)) +			return false; +	} +	for (i = 0; i < cfg->speaker_outs; i++) { +		path = snd_hda_get_path_from_idx(codec, spec->speaker_paths[i]); +		if (path && is_nid_contained(path, spec->mixer_nid)) +			return false; +	} + +	return true; +} +  /* fill the empty entries in the dac array for speaker/hp with the   * shared dac pointed by the paths   */ @@ -1545,6 +1584,9 @@ static int fill_and_eval_dacs(struct hda_codec *codec,  		badness += BAD_MULTI_IO;  	} +	if (spec->indep_hp && !indep_hp_possible(codec)) +		badness += BAD_NO_INDEP_HP; +  	/* re-fill the shared DAC for speaker / headphone */  	if (cfg->line_out_type != AUTO_PIN_HP_OUT)  		refill_shared_dacs(codec, cfg->hp_outs, @@ -1758,6 +1800,10 @@ static int parse_output_paths(struct hda_codec *codec)  				cfg->speaker_pins, val);  	} +	/* clear indep_hp flag if not available */ +	if (spec->indep_hp && !indep_hp_possible(codec)) +		spec->indep_hp = 0; +  	kfree(best_cfg);  	return 0;  } |