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.c89
1 files changed, 82 insertions, 7 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index cccaf9c7a7bb..b524f89a1f13 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -169,7 +169,7 @@ static void cs_automute(struct hda_codec *codec)
169 169
170 snd_hda_gen_update_outputs(codec); 170 snd_hda_gen_update_outputs(codec);
171 171
172 if (spec->gpio_eapd_hp) { 172 if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
173 spec->gpio_data = spec->gen.hp_jack_present ? 173 spec->gpio_data = spec->gen.hp_jack_present ?
174 spec->gpio_eapd_hp : spec->gpio_eapd_speaker; 174 spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
175 snd_hda_codec_write(codec, 0x01, 0, 175 snd_hda_codec_write(codec, 0x01, 0,
@@ -291,10 +291,11 @@ static int cs_init(struct hda_codec *codec)
291{ 291{
292 struct cs_spec *spec = codec->spec; 292 struct cs_spec *spec = codec->spec;
293 293
294 /* init_verb sequence for C0/C1/C2 errata*/ 294 if (spec->vendor_nid == CS420X_VENDOR_NID) {
295 snd_hda_sequence_write(codec, cs_errata_init_verbs); 295 /* init_verb sequence for C0/C1/C2 errata*/
296 296 snd_hda_sequence_write(codec, cs_errata_init_verbs);
297 snd_hda_sequence_write(codec, cs_coef_init_verbs); 297 snd_hda_sequence_write(codec, cs_coef_init_verbs);
298 }
298 299
299 snd_hda_gen_init(codec); 300 snd_hda_gen_init(codec);
300 301
@@ -307,8 +308,10 @@ static int cs_init(struct hda_codec *codec)
307 spec->gpio_data); 308 spec->gpio_data);
308 } 309 }
309 310
310 init_input_coef(codec); 311 if (spec->vendor_nid == CS420X_VENDOR_NID) {
311 init_digital_coef(codec); 312 init_input_coef(codec);
313 init_digital_coef(codec);
314 }
312 315
313 return 0; 316 return 0;
314} 317}
@@ -552,6 +555,76 @@ static int patch_cs420x(struct hda_codec *codec)
552} 555}
553 556
554/* 557/*
558 * CS4208 support:
559 * Its layout is no longer compatible with CS4206/CS4207, and the generic
560 * parser seems working fairly well, except for trivial fixups.
561 */
562enum {
563 CS4208_GPIO0,
564};
565
566static const struct hda_model_fixup cs4208_models[] = {
567 { .id = CS4208_GPIO0, .name = "gpio0" },
568 {}
569};
570
571static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
572 /* codec SSID */
573 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookPro 6,1", CS4208_GPIO0),
574 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookPro 6,2", CS4208_GPIO0),
575 {} /* terminator */
576};
577
578static void cs4208_fixup_gpio0(struct hda_codec *codec,
579 const struct hda_fixup *fix, int action)
580{
581 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
582 struct cs_spec *spec = codec->spec;
583 spec->gpio_eapd_hp = 0;
584 spec->gpio_eapd_speaker = 1;
585 spec->gpio_mask = spec->gpio_dir =
586 spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
587 }
588}
589
590static const struct hda_fixup cs4208_fixups[] = {
591 [CS4208_GPIO0] = {
592 .type = HDA_FIXUP_FUNC,
593 .v.func = cs4208_fixup_gpio0,
594 },
595};
596
597static int patch_cs4208(struct hda_codec *codec)
598{
599 struct cs_spec *spec;
600 int err;
601
602 spec = cs_alloc_spec(codec, 0); /* no specific w/a */
603 if (!spec)
604 return -ENOMEM;
605
606 spec->gen.automute_hook = cs_automute;
607
608 snd_hda_pick_fixup(codec, cs4208_models, cs4208_fixup_tbl,
609 cs4208_fixups);
610 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
611
612 err = cs_parse_auto_config(codec);
613 if (err < 0)
614 goto error;
615
616 codec->patch_ops = cs_patch_ops;
617
618 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
619
620 return 0;
621
622 error:
623 cs_free(codec);
624 return err;
625}
626
627/*
555 * Cirrus Logic CS4210 628 * Cirrus Logic CS4210
556 * 629 *
557 * 1 DAC => HP(sense) / Speakers, 630 * 1 DAC => HP(sense) / Speakers,
@@ -991,6 +1064,7 @@ static int patch_cs4213(struct hda_codec *codec)
991static const struct hda_codec_preset snd_hda_preset_cirrus[] = { 1064static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
992 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 1065 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
993 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 1066 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1067 { .id = 0x10134208, .name = "CS4208", .patch = patch_cs4208 },
994 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 }, 1068 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 },
995 { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 }, 1069 { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 },
996 {} /* terminator */ 1070 {} /* terminator */
@@ -998,6 +1072,7 @@ static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
998 1072
999MODULE_ALIAS("snd-hda-codec-id:10134206"); 1073MODULE_ALIAS("snd-hda-codec-id:10134206");
1000MODULE_ALIAS("snd-hda-codec-id:10134207"); 1074MODULE_ALIAS("snd-hda-codec-id:10134207");
1075MODULE_ALIAS("snd-hda-codec-id:10134208");
1001MODULE_ALIAS("snd-hda-codec-id:10134210"); 1076MODULE_ALIAS("snd-hda-codec-id:10134210");
1002MODULE_ALIAS("snd-hda-codec-id:10134213"); 1077MODULE_ALIAS("snd-hda-codec-id:10134213");
1003 1078