aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorTorben Schulz <public@letorbi.de>2009-05-18 09:02:35 -0400
committerTakashi Iwai <tiwai@suse.de>2009-05-18 09:13:02 -0400
commiteb4c41d30ba1f973c8b10be3644571ab997ae0d6 (patch)
tree86e0e795f613d591da6e712840853d06ddaba75e /sound/pci/hda/patch_realtek.c
parent313f6e2d40bd67e394a65e7d64acd0cf9c9d248d (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/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c151
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
7497static 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) */
7627static 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) */
7636static 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) */
7645static 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) */
7654static 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
7662static 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
7614static struct hda_verb alc883_medion_eapd_verbs[] = { 7669static 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
7947static 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
7892static struct hda_bind_ctls alc883_bind_cap_vol = { 7973static 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
8645static 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 */
8659static 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
8675static 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) {