aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-12-10 11:29:26 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-20 10:45:06 -0500
commit2a9f683edd34578a3d1e789781f4499af4990d63 (patch)
treeff827ca459d063201bc6507b38d4b3571d706ec6
parent44b8b7a7f2e76dd1aea131bcf79417252a1f3f11 (diff)
ALSA: hda - Add static DAC/pin mapping for AD1986A codec
commit 3690739b013504d33fe9348dd45f6b126aa370fb upstream. AD1986A codec is a pretty old codec and has really many hidden restrictions. One of such is that each DAC is dedicated to certain pin although there are possible connections. Currently, the generic parser tries to assign individual DACs as much as possible, and this lead to two bad situations: connections where the sound actually doesn't work, and connections conflicting other channels. We may fix this by trying to find the best connections more harder, but as of now, it's easier to give some hints for paired DAC/pin connections and honor them if available, since such a hint is needed only for specific codecs (right now only AD1986A, and there will be unlikely any others in future). Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=64971 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=66621 Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--sound/pci/hda/hda_generic.c23
-rw-r--r--sound/pci/hda/hda_generic.h3
-rw-r--r--sound/pci/hda/patch_analog.c10
3 files changed, 35 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 7975031312cb..b4e4dd6fd91c 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -468,6 +468,20 @@ static void invalidate_nid_path(struct hda_codec *codec, int idx)
468 memset(path, 0, sizeof(*path)); 468 memset(path, 0, sizeof(*path));
469} 469}
470 470
471/* return a DAC if paired to the given pin by codec driver */
472static hda_nid_t get_preferred_dac(struct hda_codec *codec, hda_nid_t pin)
473{
474 struct hda_gen_spec *spec = codec->spec;
475 const hda_nid_t *list = spec->preferred_dacs;
476
477 if (!list)
478 return 0;
479 for (; *list; list += 2)
480 if (*list == pin)
481 return list[1];
482 return 0;
483}
484
471/* look for an empty DAC slot */ 485/* look for an empty DAC slot */
472static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin, 486static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin,
473 bool is_digital) 487 bool is_digital)
@@ -1134,7 +1148,14 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
1134 continue; 1148 continue;
1135 } 1149 }
1136 1150
1137 dacs[i] = look_for_dac(codec, pin, false); 1151 dacs[i] = get_preferred_dac(codec, pin);
1152 if (dacs[i]) {
1153 if (is_dac_already_used(codec, dacs[i]))
1154 badness += bad->shared_primary;
1155 }
1156
1157 if (!dacs[i])
1158 dacs[i] = look_for_dac(codec, pin, false);
1138 if (!dacs[i] && !i) { 1159 if (!dacs[i] && !i) {
1139 /* try to steal the DAC of surrounds for the front */ 1160 /* try to steal the DAC of surrounds for the front */
1140 for (j = 1; j < num_outs; j++) { 1161 for (j = 1; j < num_outs; j++) {
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 76200314ee95..a18a1005002f 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -241,6 +241,9 @@ struct hda_gen_spec {
241 const struct badness_table *main_out_badness; 241 const struct badness_table *main_out_badness;
242 const struct badness_table *extra_out_badness; 242 const struct badness_table *extra_out_badness;
243 243
244 /* preferred pin/DAC pairs; an array of paired NIDs */
245 const hda_nid_t *preferred_dacs;
246
244 /* loopback mixing mode */ 247 /* loopback mixing mode */
245 bool aamix_mode; 248 bool aamix_mode;
246 249
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e17b55a95bc5..a7b07f72c9dd 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1227,6 +1227,14 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
1227{ 1227{
1228 int err; 1228 int err;
1229 struct ad198x_spec *spec; 1229 struct ad198x_spec *spec;
1230 static hda_nid_t preferred_pairs[] = {
1231 0x1a, 0x03,
1232 0x1b, 0x03,
1233 0x1c, 0x04,
1234 0x1d, 0x05,
1235 0x1e, 0x03,
1236 0
1237 };
1230 1238
1231 err = alloc_ad_spec(codec); 1239 err = alloc_ad_spec(codec);
1232 if (err < 0) 1240 if (err < 0)
@@ -1247,6 +1255,8 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
1247 * So, let's disable the shared stream. 1255 * So, let's disable the shared stream.
1248 */ 1256 */
1249 spec->gen.multiout.no_share_stream = 1; 1257 spec->gen.multiout.no_share_stream = 1;
1258 /* give fixed DAC/pin pairs */
1259 spec->gen.preferred_dacs = preferred_pairs;
1250 1260
1251 snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups); 1261 snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups);
1252 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1262 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);