From d70f363222ef373c2037412f09a600357cfa1c7a Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Thu, 19 Apr 2012 15:18:08 +0200
Subject: [PATCH] ALSA: hda/conexant - Set up the missing docking-station pins
Git-commit: d70f363222ef373c2037412f09a600357cfa1c7a
Patch-mainline: 3.4-rc6
References: FATE#313695

ThinkPad 410,420,510,520 and X201 with cx50585 & co chips have the
docking-station ports, but BIOS doesn't initialize for these pins.
Thus, like the former X200, we need to set up the pins manually in the
driver.

The odd part is that the same PCI SSID is used for X200 and T400, thus
we need to prepare individual fixup tables for cx5051 and others.

Bugzilla entries:
	https://bugzilla.redhat.com/show_bug.cgi?id=808559
	https://bugzilla.redhat.com/show_bug.cgi?id=806217
	https://bugzilla.redhat.com/show_bug.cgi?id=810697

Reported-by: Josh Boyer <jwboyer@redhat.com>
Reported-by: Jens Taprogge <jens.taprogge@taprogge.org>
Tested-by: Jens Taprogge <jens.taprogge@taprogge.org>
Cc: <stable@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/pci/hda/patch_conexant.c |   27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -4424,8 +4424,10 @@ static void apply_pin_fixup(struct hda_c
 
 enum {
 	CXT_PINCFG_LENOVO_X200,
+	CXT_PINCFG_LENOVO_TP410,
 };
 
+/* ThinkPad X200 & co with cxt5051 */
 static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
 	{ 0x17, 0x21a11000 }, /* dock-mic */
@@ -4434,15 +4436,33 @@ static const struct cxt_pincfg cxt_pincf
 	{}
 };
 
+/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
+static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
+	{ 0x19, 0x042110ff }, /* HP (seq# overridden) */
+	{ 0x1a, 0x21a190f0 }, /* dock-mic */
+	{ 0x1c, 0x212140ff }, /* dock-HP */
+	{}
+};
+
 static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
 	[CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
+	[CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
 };
 
-static const struct snd_pci_quirk cxt_fixups[] = {
+static const struct snd_pci_quirk cxt5051_fixups[] = {
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
 	{}
 };
 
+static const struct snd_pci_quirk cxt5066_fixups[] = {
+	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+	{}
+};
+
 static int patch_conexant_auto(struct hda_codec *codec)
 {
 	struct conexant_spec *spec;
@@ -4463,13 +4483,14 @@ static int patch_conexant_auto(struct hd
 	case 0x14f15051:
 		add_cx5051_fake_mutes(codec);
 		codec->pin_amp_workaround = 1;
+		apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
 		break;
 	default:
 		codec->pin_amp_workaround = 1;
+		apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
+		break;
 	}
 
-	apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
-
 	/* Show mute-led control only on HP laptops
 	 * This is a sort of white-list: on HP laptops, EAPD corresponds
 	 * only to the mute-LED without actualy amp function.  Meanwhile,
