aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-04 08:50:04 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-12 02:43:33 -0500
commite22aab7dcf7c8e77a503dcde8cd2c548d0df0cdc (patch)
tree189b5ce62c3b8e783acbed513e64a4bea8d86ac9 /sound
parentf5172a7ed966493414aa58319fbb7ab0a80cf889 (diff)
ALSA: hda - Simplify the multi-io assignment with multi speakers
When speakers are chosen as the the primary output during evaluation, we did some tricks to assign the possible multi-io jacks with a certain offset value to multi_out dacs. This was a workaround for the case with multiple speakers like Acer Aspire. But this is quite ugly at the same time and the resultant code is hard to understand. More badly, it works wrongly for 2.1 speakers like Apple iMac91. In this patch, instead of fiddling with the offset to multi_out dacs, simply add a certain badness number if headphone(s) + multi-ios are possible. This simplify the code a bit, and it's more robust. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_generic.c63
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 */
947static 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 */
954static int fill_multi_ios(struct hda_codec *codec, 976static 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++] =