diff options
-rw-r--r-- | sound/pci/hda/hda_generic.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index f9ecbe09a526..f9d3ea3c5a68 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -943,6 +943,28 @@ static bool can_be_multiio_pin(struct hda_codec *codec, | |||
943 | return true; | 943 | return true; |
944 | } | 944 | } |
945 | 945 | ||
946 | /* count the number of input pins that are capable to be multi-io */ | ||
947 | static int count_multiio_pins(struct hda_codec *codec, hda_nid_t reference_pin) | ||
948 | { | ||
949 | struct hda_gen_spec *spec = codec->spec; | ||
950 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
951 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); | ||
952 | unsigned int location = get_defcfg_location(defcfg); | ||
953 | int type, i; | ||
954 | int num_pins = 0; | ||
955 | |||
956 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
957 | for (i = 0; i < cfg->num_inputs; i++) { | ||
958 | if (cfg->inputs[i].type != type) | ||
959 | continue; | ||
960 | if (can_be_multiio_pin(codec, location, | ||
961 | cfg->inputs[i].pin)) | ||
962 | num_pins++; | ||
963 | } | ||
964 | } | ||
965 | return num_pins; | ||
966 | } | ||
967 | |||
946 | /* | 968 | /* |
947 | * multi-io helper | 969 | * multi-io helper |
948 | * | 970 | * |
@@ -953,11 +975,11 @@ static bool can_be_multiio_pin(struct hda_codec *codec, | |||
953 | */ | 975 | */ |
954 | static int fill_multi_ios(struct hda_codec *codec, | 976 | static int fill_multi_ios(struct hda_codec *codec, |
955 | hda_nid_t reference_pin, | 977 | hda_nid_t reference_pin, |
956 | bool hardwired, int offset) | 978 | bool hardwired) |
957 | { | 979 | { |
958 | struct hda_gen_spec *spec = codec->spec; | 980 | struct hda_gen_spec *spec = codec->spec; |
959 | struct auto_pin_cfg *cfg = &spec->autocfg; | 981 | struct auto_pin_cfg *cfg = &spec->autocfg; |
960 | int type, i, j, dacs, num_pins, old_pins; | 982 | int type, i, j, num_pins, old_pins; |
961 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); | 983 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); |
962 | unsigned int location = get_defcfg_location(defcfg); | 984 | unsigned int location = get_defcfg_location(defcfg); |
963 | int badness = 0; | 985 | int badness = 0; |
@@ -966,20 +988,10 @@ static int fill_multi_ios(struct hda_codec *codec, | |||
966 | if (old_pins >= 2) | 988 | if (old_pins >= 2) |
967 | goto end_fill; | 989 | goto end_fill; |
968 | 990 | ||
969 | num_pins = 0; | 991 | num_pins = count_multiio_pins(codec, reference_pin); |
970 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
971 | for (i = 0; i < cfg->num_inputs; i++) { | ||
972 | if (cfg->inputs[i].type != type) | ||
973 | continue; | ||
974 | if (can_be_multiio_pin(codec, location, | ||
975 | cfg->inputs[i].pin)) | ||
976 | num_pins++; | ||
977 | } | ||
978 | } | ||
979 | if (num_pins < 2) | 992 | if (num_pins < 2) |
980 | goto end_fill; | 993 | goto end_fill; |
981 | 994 | ||
982 | dacs = spec->multiout.num_dacs; | ||
983 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | 995 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { |
984 | for (i = 0; i < cfg->num_inputs; i++) { | 996 | for (i = 0; i < cfg->num_inputs; i++) { |
985 | struct nid_path *path; | 997 | struct nid_path *path; |
@@ -997,11 +1009,6 @@ static int fill_multi_ios(struct hda_codec *codec, | |||
997 | if (j < spec->multi_ios) | 1009 | if (j < spec->multi_ios) |
998 | continue; | 1010 | continue; |
999 | 1011 | ||
1000 | if (offset && offset + spec->multi_ios < dacs) { | ||
1001 | dac = spec->private_dac_nids[offset + spec->multi_ios]; | ||
1002 | if (!is_reachable_path(codec, dac, nid)) | ||
1003 | dac = 0; | ||
1004 | } | ||
1005 | if (hardwired) | 1012 | if (hardwired) |
1006 | dac = get_dac_if_single(codec, nid); | 1013 | dac = get_dac_if_single(codec, nid); |
1007 | else if (!dac) | 1014 | else if (!dac) |
@@ -1109,7 +1116,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec, | |||
1109 | spec->multiout.extra_out_nid); | 1116 | spec->multiout.extra_out_nid); |
1110 | if (fill_mio_first && cfg->line_outs == 1 && | 1117 | if (fill_mio_first && cfg->line_outs == 1 && |
1111 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 1118 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
1112 | err = fill_multi_ios(codec, cfg->line_out_pins[0], true, 0); | 1119 | err = fill_multi_ios(codec, cfg->line_out_pins[0], true); |
1113 | if (!err) | 1120 | if (!err) |
1114 | mapped = true; | 1121 | mapped = true; |
1115 | } | 1122 | } |
@@ -1136,7 +1143,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec, | |||
1136 | if (fill_mio_first && | 1143 | if (fill_mio_first && |
1137 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 1144 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
1138 | /* try to fill multi-io first */ | 1145 | /* try to fill multi-io first */ |
1139 | err = fill_multi_ios(codec, cfg->line_out_pins[0], false, 0); | 1146 | err = fill_multi_ios(codec, cfg->line_out_pins[0], false); |
1140 | if (err < 0) | 1147 | if (err < 0) |
1141 | return err; | 1148 | return err; |
1142 | /* we don't count badness at this stage yet */ | 1149 | /* we don't count badness at this stage yet */ |
@@ -1160,22 +1167,16 @@ static int fill_and_eval_dacs(struct hda_codec *codec, | |||
1160 | badness += err; | 1167 | badness += err; |
1161 | } | 1168 | } |
1162 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 1169 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
1163 | err = fill_multi_ios(codec, cfg->line_out_pins[0], false, 0); | 1170 | err = fill_multi_ios(codec, cfg->line_out_pins[0], false); |
1164 | if (err < 0) | ||
1165 | return err; | ||
1166 | badness += err; | ||
1167 | } | ||
1168 | if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
1169 | /* try multi-ios with HP + inputs */ | ||
1170 | int offset = 0; | ||
1171 | if (cfg->line_outs >= 3) | ||
1172 | offset = 1; | ||
1173 | err = fill_multi_ios(codec, cfg->hp_pins[0], false, offset); | ||
1174 | if (err < 0) | 1171 | if (err < 0) |
1175 | return err; | 1172 | return err; |
1176 | badness += err; | 1173 | badness += err; |
1177 | } | 1174 | } |
1178 | 1175 | ||
1176 | if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
1177 | if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2) | ||
1178 | spec->multi_ios = 1; /* give badness */ | ||
1179 | |||
1179 | if (spec->multi_ios == 2) { | 1180 | if (spec->multi_ios == 2) { |
1180 | for (i = 0; i < 2; i++) | 1181 | for (i = 0; i < 2; i++) |
1181 | spec->private_dac_nids[spec->multiout.num_dacs++] = | 1182 | spec->private_dac_nids[spec->multiout.num_dacs++] = |