aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_cirrus.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_cirrus.c')
-rw-r--r--sound/pci/hda/patch_cirrus.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 072755c8289c..fc492ac24caa 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -47,6 +47,10 @@ struct cs_spec {
47 unsigned int spdif_present:1; 47 unsigned int spdif_present:1;
48 unsigned int sense_b:1; 48 unsigned int sense_b:1;
49 hda_nid_t vendor_nid; 49 hda_nid_t vendor_nid;
50
51 /* for MBP SPDIF control */
52 int (*spdif_sw_put)(struct snd_kcontrol *kcontrol,
53 struct snd_ctl_elem_value *ucontrol);
50}; 54};
51 55
52/* available models with CS420x */ 56/* available models with CS420x */
@@ -331,10 +335,21 @@ static int cs_init(struct hda_codec *codec)
331 return 0; 335 return 0;
332} 336}
333 337
338static int cs_build_controls(struct hda_codec *codec)
339{
340 int err;
341
342 err = snd_hda_gen_build_controls(codec);
343 if (err < 0)
344 return err;
345 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
346 return 0;
347}
348
334#define cs_free snd_hda_gen_free 349#define cs_free snd_hda_gen_free
335 350
336static const struct hda_codec_ops cs_patch_ops = { 351static const struct hda_codec_ops cs_patch_ops = {
337 .build_controls = snd_hda_gen_build_controls, 352 .build_controls = cs_build_controls,
338 .build_pcms = snd_hda_gen_build_pcms, 353 .build_pcms = snd_hda_gen_build_pcms,
339 .init = cs_init, 354 .init = cs_init,
340 .free = cs_free, 355 .free = cs_free,
@@ -599,12 +614,14 @@ static int patch_cs420x(struct hda_codec *codec)
599enum { 614enum {
600 CS4208_MAC_AUTO, 615 CS4208_MAC_AUTO,
601 CS4208_MBA6, 616 CS4208_MBA6,
617 CS4208_MBP11,
602 CS4208_GPIO0, 618 CS4208_GPIO0,
603}; 619};
604 620
605static const struct hda_model_fixup cs4208_models[] = { 621static const struct hda_model_fixup cs4208_models[] = {
606 { .id = CS4208_GPIO0, .name = "gpio0" }, 622 { .id = CS4208_GPIO0, .name = "gpio0" },
607 { .id = CS4208_MBA6, .name = "mba6" }, 623 { .id = CS4208_MBA6, .name = "mba6" },
624 { .id = CS4208_MBP11, .name = "mbp11" },
608 {} 625 {}
609}; 626};
610 627
@@ -615,6 +632,7 @@ static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
615 632
616/* codec SSID matching */ 633/* codec SSID matching */
617static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = { 634static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
635 SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
618 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), 636 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
619 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), 637 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
620 {} /* terminator */ 638 {} /* terminator */
@@ -646,6 +664,36 @@ static void cs4208_fixup_mac(struct hda_codec *codec,
646 snd_hda_apply_fixup(codec, action); 664 snd_hda_apply_fixup(codec, action);
647} 665}
648 666
667static int cs4208_spdif_sw_put(struct snd_kcontrol *kcontrol,
668 struct snd_ctl_elem_value *ucontrol)
669{
670 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
671 struct cs_spec *spec = codec->spec;
672 hda_nid_t pin = spec->gen.autocfg.dig_out_pins[0];
673 int pinctl = ucontrol->value.integer.value[0] ? PIN_OUT : 0;
674
675 snd_hda_set_pin_ctl_cache(codec, pin, pinctl);
676 return spec->spdif_sw_put(kcontrol, ucontrol);
677}
678
679/* hook the SPDIF switch */
680static void cs4208_fixup_spdif_switch(struct hda_codec *codec,
681 const struct hda_fixup *fix, int action)
682{
683 if (action == HDA_FIXUP_ACT_BUILD) {
684 struct cs_spec *spec = codec->spec;
685 struct snd_kcontrol *kctl;
686
687 if (!spec->gen.autocfg.dig_out_pins[0])
688 return;
689 kctl = snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch");
690 if (!kctl)
691 return;
692 spec->spdif_sw_put = kctl->put;
693 kctl->put = cs4208_spdif_sw_put;
694 }
695}
696
649static const struct hda_fixup cs4208_fixups[] = { 697static const struct hda_fixup cs4208_fixups[] = {
650 [CS4208_MBA6] = { 698 [CS4208_MBA6] = {
651 .type = HDA_FIXUP_PINS, 699 .type = HDA_FIXUP_PINS,
@@ -653,6 +701,12 @@ static const struct hda_fixup cs4208_fixups[] = {
653 .chained = true, 701 .chained = true,
654 .chain_id = CS4208_GPIO0, 702 .chain_id = CS4208_GPIO0,
655 }, 703 },
704 [CS4208_MBP11] = {
705 .type = HDA_FIXUP_FUNC,
706 .v.func = cs4208_fixup_spdif_switch,
707 .chained = true,
708 .chain_id = CS4208_GPIO0,
709 },
656 [CS4208_GPIO0] = { 710 [CS4208_GPIO0] = {
657 .type = HDA_FIXUP_FUNC, 711 .type = HDA_FIXUP_FUNC,
658 .v.func = cs4208_fixup_gpio0, 712 .v.func = cs4208_fixup_gpio0,