[3.11.y.z extended stable] Patch "ALSA: hda - Add static DAC/pin mapping for AD1986A codec" has been added to staging queue

Luis Henriques luis.henriques at canonical.com
Wed Dec 18 10:20:50 UTC 2013


This is a note to let you know that I have just added a patch titled

    ALSA: hda - Add static DAC/pin mapping for AD1986A codec

to the linux-3.11.y-queue branch of the 3.11.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.11.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.11.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

>From 0d6b89614749ede26bae0e5c4e120305dc527299 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai at suse.de>
Date: Tue, 10 Dec 2013 17:29:26 +0100
Subject: 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 at suse.de>
Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
---
 sound/pci/hda/hda_generic.c  | 23 ++++++++++++++++++++++-
 sound/pci/hda/hda_generic.h  |  3 +++
 sound/pci/hda/patch_analog.c | 10 ++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index bd7efe8..08172b1 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -471,6 +471,20 @@ static void invalidate_nid_path(struct hda_codec *codec, int idx)
 	memset(path, 0, sizeof(*path));
 }

+/* return a DAC if paired to the given pin by codec driver */
+static hda_nid_t get_preferred_dac(struct hda_codec *codec, hda_nid_t pin)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	const hda_nid_t *list = spec->preferred_dacs;
+
+	if (!list)
+		return 0;
+	for (; *list; list += 2)
+		if (*list == pin)
+			return list[1];
+	return 0;
+}
+
 /* look for an empty DAC slot */
 static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin,
 			      bool is_digital)
@@ -1165,7 +1179,14 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
 			continue;
 		}

-		dacs[i] = look_for_dac(codec, pin, false);
+		dacs[i] = get_preferred_dac(codec, pin);
+		if (dacs[i]) {
+			if (is_dac_already_used(codec, dacs[i]))
+				badness += bad->shared_primary;
+		}
+
+		if (!dacs[i])
+			dacs[i] = look_for_dac(codec, pin, false);
 		if (!dacs[i] && !i) {
 			/* try to steal the DAC of surrounds for the front */
 			for (j = 1; j < num_outs; j++) {
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index e199a85..76c685a 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -245,6 +245,9 @@ struct hda_gen_spec {
 	const struct badness_table *main_out_badness;
 	const struct badness_table *extra_out_badness;

+	/* preferred pin/DAC pairs; an array of paired NIDs */
+	const hda_nid_t *preferred_dacs;
+
 	/* loopback mixing mode */
 	bool aamix_mode;

diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index a3d9143..c7db6e5 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)
 {
 	int err;
 	struct ad198x_spec *spec;
+	static hda_nid_t preferred_pairs[] = {
+		0x1a, 0x03,
+		0x1b, 0x03,
+		0x1c, 0x04,
+		0x1d, 0x05,
+		0x1e, 0x03,
+		0
+	};

 	err = alloc_ad_spec(codec);
 	if (err < 0)
@@ -1247,6 +1255,8 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
 	 * So, let's disable the shared stream.
 	 */
 	spec->gen.multiout.no_share_stream = 1;
+	/* give fixed DAC/pin pairs */
+	spec->gen.preferred_dacs = preferred_pairs;

 	/* AD1986A can't manage the dynamic pin on/off smoothly */
 	spec->gen.auto_mute_via_amp = 1;
--
1.8.3.2





More information about the kernel-team mailing list