diff options
author | Torben Schulz <public@letorbi.de> | 2009-05-18 09:02:35 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-05-18 09:13:02 -0400 |
commit | eb4c41d30ba1f973c8b10be3644571ab997ae0d6 (patch) | |
tree | 86e0e795f613d591da6e712840853d06ddaba75e /sound | |
parent | 313f6e2d40bd67e394a65e7d64acd0cf9c9d248d (diff) |
ALSA: hda - Improved MacBook 3,1 support
This patch adds support for MacBook 3,1 sound by adding a model new
"mb31" with the appropriate init verbs, mixers and channel modes to
the ALC883 configuration. patch_alc882() and patch_alc883() are
modified to handle the MacBook 3,1 sound-chip (Realtek ALC889A)
correctly.
Signed-off-by: Torben Schulz <public@letorbi.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 151 |
1 files changed, 146 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 62f4d0ca7e14..b942019461a1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -240,6 +240,7 @@ enum { | |||
240 | ALC883_3ST_6ch_INTEL, | 240 | ALC883_3ST_6ch_INTEL, |
241 | ALC888_ASUS_M90V, | 241 | ALC888_ASUS_M90V, |
242 | ALC888_ASUS_EEE1601, | 242 | ALC888_ASUS_EEE1601, |
243 | ALC889A_MB31, | ||
243 | ALC1200_ASUS_P5Q, | 244 | ALC1200_ASUS_P5Q, |
244 | ALC883_AUTO, | 245 | ALC883_AUTO, |
245 | ALC883_MODEL_LAST, | 246 | ALC883_MODEL_LAST, |
@@ -7291,7 +7292,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
7291 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ | 7292 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ |
7292 | case 0x106b00a4: /* MacbookPro4,1 */ | 7293 | case 0x106b00a4: /* MacbookPro4,1 */ |
7293 | case 0x106b2c00: /* Macbook Pro rev3 */ | 7294 | case 0x106b2c00: /* Macbook Pro rev3 */ |
7294 | case 0x106b3600: /* Macbook 3.1 */ | 7295 | /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */ |
7295 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ | 7296 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ |
7296 | board_config = ALC885_MBP3; | 7297 | board_config = ALC885_MBP3; |
7297 | break; | 7298 | break; |
@@ -7493,6 +7494,17 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { | |||
7493 | }, | 7494 | }, |
7494 | }; | 7495 | }; |
7495 | 7496 | ||
7497 | static struct hda_input_mux alc889A_mb31_capture_source = { | ||
7498 | .num_items = 2, | ||
7499 | .items = { | ||
7500 | { "Mic", 0x0 }, | ||
7501 | /* Front Mic (0x01) unused */ | ||
7502 | { "Line", 0x2 }, | ||
7503 | /* Line 2 (0x03) unused */ | ||
7504 | /* CD (0x04) unsused? */ | ||
7505 | }, | ||
7506 | }; | ||
7507 | |||
7496 | /* | 7508 | /* |
7497 | * 2ch mode | 7509 | * 2ch mode |
7498 | */ | 7510 | */ |
@@ -7611,6 +7623,49 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { | |||
7611 | { 8, alc883_sixstack_ch8_init }, | 7623 | { 8, alc883_sixstack_ch8_init }, |
7612 | }; | 7624 | }; |
7613 | 7625 | ||
7626 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ | ||
7627 | static struct hda_verb alc889A_mb31_ch2_init[] = { | ||
7628 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
7629 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7630 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
7631 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
7632 | { } /* end */ | ||
7633 | }; | ||
7634 | |||
7635 | /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ | ||
7636 | static struct hda_verb alc889A_mb31_ch4_init[] = { | ||
7637 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
7638 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7639 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
7640 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
7641 | { } /* end */ | ||
7642 | }; | ||
7643 | |||
7644 | /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ | ||
7645 | static struct hda_verb alc889A_mb31_ch5_init[] = { | ||
7646 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ | ||
7647 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7648 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
7649 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
7650 | { } /* end */ | ||
7651 | }; | ||
7652 | |||
7653 | /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ | ||
7654 | static struct hda_verb alc889A_mb31_ch6_init[] = { | ||
7655 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ | ||
7656 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ | ||
7657 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
7658 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
7659 | { } /* end */ | ||
7660 | }; | ||
7661 | |||
7662 | static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { | ||
7663 | { 2, alc889A_mb31_ch2_init }, | ||
7664 | { 4, alc889A_mb31_ch4_init }, | ||
7665 | { 5, alc889A_mb31_ch5_init }, | ||
7666 | { 6, alc889A_mb31_ch6_init }, | ||
7667 | }; | ||
7668 | |||
7614 | static struct hda_verb alc883_medion_eapd_verbs[] = { | 7669 | static struct hda_verb alc883_medion_eapd_verbs[] = { |
7615 | /* eanable EAPD on medion laptop */ | 7670 | /* eanable EAPD on medion laptop */ |
7616 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 7671 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
@@ -7889,6 +7944,32 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | |||
7889 | { } /* end */ | 7944 | { } /* end */ |
7890 | }; | 7945 | }; |
7891 | 7946 | ||
7947 | static struct snd_kcontrol_new alc889A_mb31_mixer[] = { | ||
7948 | /* Output mixers */ | ||
7949 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
7950 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
7951 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
7952 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
7953 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, | ||
7954 | HDA_OUTPUT), | ||
7955 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), | ||
7956 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), | ||
7957 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), | ||
7958 | /* Output switches */ | ||
7959 | HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), | ||
7960 | HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), | ||
7961 | HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), | ||
7962 | /* Boost mixers */ | ||
7963 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | ||
7964 | HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), | ||
7965 | /* Input mixers */ | ||
7966 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
7967 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
7968 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7969 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7970 | { } /* end */ | ||
7971 | }; | ||
7972 | |||
7892 | static struct hda_bind_ctls alc883_bind_cap_vol = { | 7973 | static struct hda_bind_ctls alc883_bind_cap_vol = { |
7893 | .ops = &snd_hda_bind_vol, | 7974 | .ops = &snd_hda_bind_vol, |
7894 | .values = { | 7975 | .values = { |
@@ -8561,6 +8642,42 @@ static void alc883_eee1601_inithook(struct hda_codec *codec) | |||
8561 | alc_automute_pin(codec); | 8642 | alc_automute_pin(codec); |
8562 | } | 8643 | } |
8563 | 8644 | ||
8645 | static struct hda_verb alc889A_mb31_verbs[] = { | ||
8646 | /* Init rear pin (used as headphone output) */ | ||
8647 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ | ||
8648 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ | ||
8649 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
8650 | /* Init line pin (used as output in 4ch and 6ch mode) */ | ||
8651 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ | ||
8652 | /* Init line 2 pin (used as headphone out by default) */ | ||
8653 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ | ||
8654 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ | ||
8655 | { } /* end */ | ||
8656 | }; | ||
8657 | |||
8658 | /* Mute speakers according to the headphone jack state */ | ||
8659 | static void alc889A_mb31_automute(struct hda_codec *codec) | ||
8660 | { | ||
8661 | unsigned int present; | ||
8662 | |||
8663 | /* Mute only in 2ch or 4ch mode */ | ||
8664 | if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) | ||
8665 | == 0x00) { | ||
8666 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
8667 | AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; | ||
8668 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8669 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8670 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8671 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8672 | } | ||
8673 | } | ||
8674 | |||
8675 | static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) | ||
8676 | { | ||
8677 | if ((res >> 26) == ALC880_HP_EVENT) | ||
8678 | alc889A_mb31_automute(codec); | ||
8679 | } | ||
8680 | |||
8564 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 8681 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
8565 | #define alc883_loopbacks alc880_loopbacks | 8682 | #define alc883_loopbacks alc880_loopbacks |
8566 | #endif | 8683 | #endif |
@@ -8601,6 +8718,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
8601 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", | 8718 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", |
8602 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", | 8719 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", |
8603 | [ALC1200_ASUS_P5Q] = "asus-p5q", | 8720 | [ALC1200_ASUS_P5Q] = "asus-p5q", |
8721 | [ALC889A_MB31] = "mb31", | ||
8604 | [ALC883_AUTO] = "auto", | 8722 | [ALC883_AUTO] = "auto", |
8605 | }; | 8723 | }; |
8606 | 8724 | ||
@@ -9052,6 +9170,21 @@ static struct alc_config_preset alc883_presets[] = { | |||
9052 | .channel_mode = alc883_sixstack_modes, | 9170 | .channel_mode = alc883_sixstack_modes, |
9053 | .input_mux = &alc883_capture_source, | 9171 | .input_mux = &alc883_capture_source, |
9054 | }, | 9172 | }, |
9173 | [ALC889A_MB31] = { | ||
9174 | .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, | ||
9175 | .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, | ||
9176 | alc880_gpio1_init_verbs }, | ||
9177 | .adc_nids = alc883_adc_nids, | ||
9178 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
9179 | .dac_nids = alc883_dac_nids, | ||
9180 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9181 | .channel_mode = alc889A_mb31_6ch_modes, | ||
9182 | .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), | ||
9183 | .input_mux = &alc889A_mb31_capture_source, | ||
9184 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9185 | .unsol_event = alc889A_mb31_unsol_event, | ||
9186 | .init_hook = alc889A_mb31_automute, | ||
9187 | }, | ||
9055 | }; | 9188 | }; |
9056 | 9189 | ||
9057 | 9190 | ||
@@ -9197,10 +9330,18 @@ static int patch_alc883(struct hda_codec *codec) | |||
9197 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, | 9330 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, |
9198 | alc883_models, | 9331 | alc883_models, |
9199 | alc883_cfg_tbl); | 9332 | alc883_cfg_tbl); |
9200 | if (board_config < 0) { | 9333 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { |
9201 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 9334 | /* Pick up systems that don't supply PCI SSID */ |
9202 | "trying auto-probe from BIOS...\n", codec->chip_name); | 9335 | switch (codec->subsystem_id) { |
9203 | board_config = ALC883_AUTO; | 9336 | case 0x106b3600: /* Macbook 3.1 */ |
9337 | board_config = ALC889A_MB31; | ||
9338 | break; | ||
9339 | default: | ||
9340 | printk(KERN_INFO | ||
9341 | "hda_codec: Unknown model for %s, trying " | ||
9342 | "auto-probe from BIOS...\n", codec->chip_name); | ||
9343 | board_config = ALC883_AUTO; | ||
9344 | } | ||
9204 | } | 9345 | } |
9205 | 9346 | ||
9206 | if (board_config == ALC883_AUTO) { | 9347 | if (board_config == ALC883_AUTO) { |