diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-01-04 08:50:04 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-12 02:43:33 -0500 |
commit | e22aab7dcf7c8e77a503dcde8cd2c548d0df0cdc (patch) | |
tree | 189b5ce62c3b8e783acbed513e64a4bea8d86ac9 /sound | |
parent | f5172a7ed966493414aa58319fbb7ab0a80cf889 (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.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++] = |