[PATCH 3.12 016/123] ALSA: hda - Control SPDIF out pin on MacBookPro 11,2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Takashi Iwai <tiwai@xxxxxxx>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 0c52db8cca7b033d03ebcda652158e2311d5ac64 upstream.

The SPDIF output MBP11,2 requires the pin control to be set/cleared
for turning on/off the optical SPDIF.  The red light turns off only
when the corresponding pin control is cleared (or powered to D3).

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=64401
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
Signed-off-by: Jiri Slaby <jslaby@xxxxxxx>
---
 sound/pci/hda/patch_cirrus.c | 56 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index d54d218fe810..7b0aac9d27ca 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -47,6 +47,10 @@ struct cs_spec {
 	unsigned int spdif_present:1;
 	unsigned int sense_b:1;
 	hda_nid_t vendor_nid;
+
+	/* for MBP SPDIF control */
+	int (*spdif_sw_put)(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol);
 };
 
 /* available models with CS420x */
@@ -331,10 +335,21 @@ static int cs_init(struct hda_codec *codec)
 	return 0;
 }
 
+static int cs_build_controls(struct hda_codec *codec)
+{
+	int err;
+
+	err = snd_hda_gen_build_controls(codec);
+	if (err < 0)
+		return err;
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
+	return 0;
+}
+
 #define cs_free		snd_hda_gen_free
 
 static const struct hda_codec_ops cs_patch_ops = {
-	.build_controls = snd_hda_gen_build_controls,
+	.build_controls = cs_build_controls,
 	.build_pcms = snd_hda_gen_build_pcms,
 	.init = cs_init,
 	.free = cs_free,
@@ -601,12 +616,14 @@ static int patch_cs420x(struct hda_codec *codec)
 enum {
 	CS4208_MAC_AUTO,
 	CS4208_MBA6,
+	CS4208_MBP11,
 	CS4208_GPIO0,
 };
 
 static const struct hda_model_fixup cs4208_models[] = {
 	{ .id = CS4208_GPIO0, .name = "gpio0" },
 	{ .id = CS4208_MBA6, .name = "mba6" },
+	{ .id = CS4208_MBP11, .name = "mbp11" },
 	{}
 };
 
@@ -617,6 +634,7 @@ static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
 
 /* codec SSID matching */
 static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
+	SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
 	SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
 	SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
 	{} /* terminator */
@@ -648,6 +666,36 @@ static void cs4208_fixup_mac(struct hda_codec *codec,
 	snd_hda_apply_fixup(codec, action);
 }
 
+static int cs4208_spdif_sw_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct cs_spec *spec = codec->spec;
+	hda_nid_t pin = spec->gen.autocfg.dig_out_pins[0];
+	int pinctl = ucontrol->value.integer.value[0] ? PIN_OUT : 0;
+
+	snd_hda_set_pin_ctl_cache(codec, pin, pinctl);
+	return spec->spdif_sw_put(kcontrol, ucontrol);
+}
+
+/* hook the SPDIF switch */
+static void cs4208_fixup_spdif_switch(struct hda_codec *codec,
+				      const struct hda_fixup *fix, int action)
+{
+	if (action == HDA_FIXUP_ACT_BUILD) {
+		struct cs_spec *spec = codec->spec;
+		struct snd_kcontrol *kctl;
+
+		if (!spec->gen.autocfg.dig_out_pins[0])
+			return;
+		kctl = snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch");
+		if (!kctl)
+			return;
+		spec->spdif_sw_put = kctl->put;
+		kctl->put = cs4208_spdif_sw_put;
+	}
+}
+
 static const struct hda_fixup cs4208_fixups[] = {
 	[CS4208_MBA6] = {
 		.type = HDA_FIXUP_PINS,
@@ -655,6 +703,12 @@ static const struct hda_fixup cs4208_fixups[] = {
 		.chained = true,
 		.chain_id = CS4208_GPIO0,
 	},
+	[CS4208_MBP11] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cs4208_fixup_spdif_switch,
+		.chained = true,
+		.chain_id = CS4208_GPIO0,
+	},
 	[CS4208_GPIO0] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = cs4208_fixup_gpio0,
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]