diff options
Diffstat (limited to 'sound/pci/hda/patch_cirrus.c')
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 3bcb67172358..a2537b2f8724 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -68,6 +68,7 @@ struct cs_spec { | |||
68 | 68 | ||
69 | unsigned int hp_detect:1; | 69 | unsigned int hp_detect:1; |
70 | unsigned int mic_detect:1; | 70 | unsigned int mic_detect:1; |
71 | unsigned int speaker_2_1:1; | ||
71 | /* CS421x */ | 72 | /* CS421x */ |
72 | unsigned int spdif_detect:1; | 73 | unsigned int spdif_detect:1; |
73 | unsigned int sense_b:1; | 74 | unsigned int sense_b:1; |
@@ -84,7 +85,7 @@ enum { | |||
84 | CS420X_GPIO_13, | 85 | CS420X_GPIO_13, |
85 | CS420X_GPIO_23, | 86 | CS420X_GPIO_23, |
86 | CS420X_MBP101, | 87 | CS420X_MBP101, |
87 | CS420X_MBP101_COEF, | 88 | CS420X_MBP81, |
88 | CS420X_AUTO, | 89 | CS420X_AUTO, |
89 | /* aliases */ | 90 | /* aliases */ |
90 | CS420X_IMAC27_122 = CS420X_GPIO_23, | 91 | CS420X_IMAC27_122 = CS420X_GPIO_23, |
@@ -343,6 +344,9 @@ static int cs_build_pcms(struct hda_codec *codec) | |||
343 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0]; | 344 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0]; |
344 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | 345 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = |
345 | spec->multiout.max_channels; | 346 | spec->multiout.max_channels; |
347 | if (spec->speaker_2_1) | ||
348 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
349 | snd_pcm_2_1_chmaps; | ||
346 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture; | 350 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture; |
347 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | 351 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = |
348 | spec->adc_nid[spec->cur_input]; | 352 | spec->adc_nid[spec->cur_input]; |
@@ -443,6 +447,9 @@ static int parse_output(struct hda_codec *codec) | |||
443 | spec->multiout.dac_nids = spec->dac_nid; | 447 | spec->multiout.dac_nids = spec->dac_nid; |
444 | spec->multiout.max_channels = i * 2; | 448 | spec->multiout.max_channels = i * 2; |
445 | 449 | ||
450 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && i == 2) | ||
451 | spec->speaker_2_1 = 1; /* assume 2.1 speakers */ | ||
452 | |||
446 | /* add HP and speakers */ | 453 | /* add HP and speakers */ |
447 | extra_nids = 0; | 454 | extra_nids = 0; |
448 | for (i = 0; i < cfg->hp_outs; i++) { | 455 | for (i = 0; i < cfg->hp_outs; i++) { |
@@ -633,7 +640,9 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, | |||
633 | index = idx; | 640 | index = idx; |
634 | break; | 641 | break; |
635 | case AUTO_PIN_SPEAKER_OUT: | 642 | case AUTO_PIN_SPEAKER_OUT: |
636 | if (num_ctls > 1) | 643 | if (spec->speaker_2_1) |
644 | name = idx ? "Bass Speaker" : "Speaker"; | ||
645 | else if (num_ctls > 1) | ||
637 | name = speakers[idx]; | 646 | name = speakers[idx]; |
638 | else | 647 | else |
639 | name = "Speaker"; | 648 | name = "Speaker"; |
@@ -874,8 +883,9 @@ static int build_digital_output(struct hda_codec *codec) | |||
874 | if (!spec->multiout.dig_out_nid) | 883 | if (!spec->multiout.dig_out_nid) |
875 | return 0; | 884 | return 0; |
876 | 885 | ||
877 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid, | 886 | err = snd_hda_create_dig_out_ctls(codec, spec->multiout.dig_out_nid, |
878 | spec->multiout.dig_out_nid); | 887 | spec->multiout.dig_out_nid, |
888 | spec->pcm_rec[1].pcm_type); | ||
879 | if (err < 0) | 889 | if (err < 0) |
880 | return err; | 890 | return err; |
881 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); | 891 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); |
@@ -1079,9 +1089,6 @@ static void init_input(struct hda_codec *codec) | |||
1079 | if (spec->mic_detect) | 1089 | if (spec->mic_detect) |
1080 | cs_automic(codec, NULL); | 1090 | cs_automic(codec, NULL); |
1081 | 1091 | ||
1082 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ | ||
1083 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | ||
1084 | |||
1085 | coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); | 1092 | coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); |
1086 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) | 1093 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) |
1087 | coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ | 1094 | coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ |
@@ -1111,6 +1118,9 @@ static const struct hda_verb cs_coef_init_verbs[] = { | |||
1111 | | 0x1000 /* Enable DACs High Pass Filter */ | 1118 | | 0x1000 /* Enable DACs High Pass Filter */ |
1112 | | 0x0400 /* Disable Coefficient Auto increment */ | 1119 | | 0x0400 /* Disable Coefficient Auto increment */ |
1113 | )}, | 1120 | )}, |
1121 | /* ADC1/2 - Digital and Analog Soft Ramp */ | ||
1122 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_ADC_CFG}, | ||
1123 | {0x11, AC_VERB_SET_PROC_COEF, 0x000a}, | ||
1114 | /* Beep */ | 1124 | /* Beep */ |
1115 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, | 1125 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, |
1116 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ | 1126 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ |
@@ -1167,14 +1177,6 @@ static const struct hda_verb cs_errata_init_verbs[] = { | |||
1167 | {} /* terminator */ | 1177 | {} /* terminator */ |
1168 | }; | 1178 | }; |
1169 | 1179 | ||
1170 | static const struct hda_verb mbp101_init_verbs[] = { | ||
1171 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0002}, | ||
1172 | {0x11, AC_VERB_SET_PROC_COEF, 0x100a}, | ||
1173 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0004}, | ||
1174 | {0x11, AC_VERB_SET_PROC_COEF, 0x000f}, | ||
1175 | {} | ||
1176 | }; | ||
1177 | |||
1178 | /* SPDIF setup */ | 1180 | /* SPDIF setup */ |
1179 | static void init_digital(struct hda_codec *codec) | 1181 | static void init_digital(struct hda_codec *codec) |
1180 | { | 1182 | { |
@@ -1199,6 +1201,8 @@ static int cs_init(struct hda_codec *codec) | |||
1199 | 1201 | ||
1200 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | 1202 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
1201 | 1203 | ||
1204 | snd_hda_gen_apply_verbs(codec); | ||
1205 | |||
1202 | if (spec->gpio_mask) { | 1206 | if (spec->gpio_mask) { |
1203 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, | 1207 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, |
1204 | spec->gpio_mask); | 1208 | spec->gpio_mask); |
@@ -1291,6 +1295,7 @@ static const struct hda_model_fixup cs420x_models[] = { | |||
1291 | { .id = CS420X_IMAC27_122, .name = "imac27_122" }, | 1295 | { .id = CS420X_IMAC27_122, .name = "imac27_122" }, |
1292 | { .id = CS420X_APPLE, .name = "apple" }, | 1296 | { .id = CS420X_APPLE, .name = "apple" }, |
1293 | { .id = CS420X_MBP101, .name = "mbp101" }, | 1297 | { .id = CS420X_MBP101, .name = "mbp101" }, |
1298 | { .id = CS420X_MBP81, .name = "mbp81" }, | ||
1294 | {} | 1299 | {} |
1295 | }; | 1300 | }; |
1296 | 1301 | ||
@@ -1303,6 +1308,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { | |||
1303 | /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ | 1308 | /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ |
1304 | 1309 | ||
1305 | /* codec SSID */ | 1310 | /* codec SSID */ |
1311 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), | ||
1306 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), | 1312 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), |
1307 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), | 1313 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), |
1308 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), | 1314 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), |
@@ -1413,11 +1419,16 @@ static const struct hda_fixup cs420x_fixups[] = { | |||
1413 | .type = HDA_FIXUP_PINS, | 1419 | .type = HDA_FIXUP_PINS, |
1414 | .v.pins = mbp101_pincfgs, | 1420 | .v.pins = mbp101_pincfgs, |
1415 | .chained = true, | 1421 | .chained = true, |
1416 | .chain_id = CS420X_MBP101_COEF, | 1422 | .chain_id = CS420X_GPIO_13, |
1417 | }, | 1423 | }, |
1418 | [CS420X_MBP101_COEF] = { | 1424 | [CS420X_MBP81] = { |
1419 | .type = HDA_FIXUP_VERBS, | 1425 | .type = HDA_FIXUP_VERBS, |
1420 | .v.verbs = mbp101_init_verbs, | 1426 | .v.verbs = (const struct hda_verb[]) { |
1427 | /* internal mic ADC2: right only, single ended */ | ||
1428 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_ADC_CFG}, | ||
1429 | {0x11, AC_VERB_SET_PROC_COEF, 0x102a}, | ||
1430 | {} | ||
1431 | }, | ||
1421 | .chained = true, | 1432 | .chained = true, |
1422 | .chain_id = CS420X_GPIO_13, | 1433 | .chain_id = CS420X_GPIO_13, |
1423 | }, | 1434 | }, |