aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-09-09 07:57:57 -0400
committerTakashi Iwai <tiwai@suse.de>2013-09-09 10:09:57 -0400
commitbe8cf44526d8972c2dbf6e561162dad924a712a5 (patch)
tree365ce377f597d8089a31276908c4106e14b5a349 /sound
parent83f72151352791836a1b9c1542614cc9bf71ac61 (diff)
ALSA: hda - Add CS4208 codec support for MacBook 6,1 and 6,2
MacBook 6,1 and 6,2 have a CS4208 codec instead of CS4206/CS4207 on the former models. Most of functions work fine as is, except for the silent speaker output. After debugging sessions, it turned out that the machine needs to set GPIO 0 for the speaker amp. This patch adds the basic support for CS4208 and the fixup for these MacBooks. Basically the codec works just with the generic parser. For re-using the existing GPIO amp code and init/free callbacks, a few places have been changed so that CS4206/4207-specific codes (errata, etc) won't hit with CS4208. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60811 Reported-and-tested-by: Imre Kaloz <kaloz@openwrt.org> Reported-and-tested-by: Ian Munsie <darkstarsword@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-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