diff options
Diffstat (limited to 'sound/pci/hda/patch_cirrus.c')
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 61a7113..a2537b2 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -68,6 +68,7 @@ struct cs_spec { unsigned int hp_detect:1; unsigned int mic_detect:1; + unsigned int speaker_2_1:1; /* CS421x */ unsigned int spdif_detect:1; unsigned int sense_b:1; @@ -84,7 +85,7 @@ enum { CS420X_GPIO_13, CS420X_GPIO_23, CS420X_MBP101, - CS420X_MBP101_COEF, + CS420X_MBP81, CS420X_AUTO, /* aliases */ CS420X_IMAC27_122 = CS420X_GPIO_23, @@ -101,8 +102,8 @@ enum { #define CS420X_VENDOR_NID 0x11 #define CS_DIG_OUT1_PIN_NID 0x10 #define CS_DIG_OUT2_PIN_NID 0x15 -#define CS_DMIC1_PIN_NID 0x12 -#define CS_DMIC2_PIN_NID 0x0e +#define CS_DMIC1_PIN_NID 0x0e +#define CS_DMIC2_PIN_NID 0x12 /* coef indices */ #define IDX_SPDIF_STAT 0x0000 @@ -343,6 +344,9 @@ static int cs_build_pcms(struct hda_codec *codec) info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0]; info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; + if (spec->speaker_2_1) + info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = + snd_pcm_2_1_chmaps; info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid[spec->cur_input]; @@ -443,6 +447,9 @@ static int parse_output(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nid; spec->multiout.max_channels = i * 2; + if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && i == 2) + spec->speaker_2_1 = 1; /* assume 2.1 speakers */ + /* add HP and speakers */ extra_nids = 0; for (i = 0; i < cfg->hp_outs; i++) { @@ -466,6 +473,7 @@ static int parse_output(struct hda_codec *codec) memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->line_outs = 0; + memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins)); } return 0; @@ -632,7 +640,9 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, index = idx; break; case AUTO_PIN_SPEAKER_OUT: - if (num_ctls > 1) + if (spec->speaker_2_1) + name = idx ? "Bass Speaker" : "Speaker"; + else if (num_ctls > 1) name = speakers[idx]; else name = "Speaker"; @@ -873,8 +883,9 @@ static int build_digital_output(struct hda_codec *codec) if (!spec->multiout.dig_out_nid) return 0; - err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid, - spec->multiout.dig_out_nid); + err = snd_hda_create_dig_out_ctls(codec, spec->multiout.dig_out_nid, + spec->multiout.dig_out_nid, + spec->pcm_rec[1].pcm_type); if (err < 0) return err; err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); @@ -1078,15 +1089,16 @@ static void init_input(struct hda_codec *codec) if (spec->mic_detect) cs_automic(codec, NULL); - coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ + coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); if (is_active_pin(codec, CS_DMIC2_PIN_NID)) - coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ + coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ if (is_active_pin(codec, CS_DMIC1_PIN_NID)) - coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off + coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off * No effect if SPDIF_OUT2 is * selected in IDX_SPDIF_CTL. */ - cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); + + cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); } else { if (spec->mic_detect) cs_automic(codec, NULL); @@ -1106,8 +1118,11 @@ static const struct hda_verb cs_coef_init_verbs[] = { | 0x1000 /* Enable DACs High Pass Filter */ | 0x0400 /* Disable Coefficient Auto increment */ )}, + /* ADC1/2 - Digital and Analog Soft Ramp */ + {0x11, AC_VERB_SET_COEF_INDEX, IDX_ADC_CFG}, + {0x11, AC_VERB_SET_PROC_COEF, 0x000a}, /* Beep */ - {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, + {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ {} /* terminator */ @@ -1162,14 +1177,6 @@ static const struct hda_verb cs_errata_init_verbs[] = { {} /* terminator */ }; -static const struct hda_verb mbp101_init_verbs[] = { - {0x11, AC_VERB_SET_COEF_INDEX, 0x0002}, - {0x11, AC_VERB_SET_PROC_COEF, 0x100a}, - {0x11, AC_VERB_SET_COEF_INDEX, 0x0004}, - {0x11, AC_VERB_SET_PROC_COEF, 0x000f}, - {} -}; - /* SPDIF setup */ static void init_digital(struct hda_codec *codec) { @@ -1194,6 +1201,8 @@ static int cs_init(struct hda_codec *codec) snd_hda_sequence_write(codec, cs_coef_init_verbs); + snd_hda_gen_apply_verbs(codec); + if (spec->gpio_mask) { snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, spec->gpio_mask); @@ -1286,6 +1295,7 @@ static const struct hda_model_fixup cs420x_models[] = { { .id = CS420X_IMAC27_122, .name = "imac27_122" }, { .id = CS420X_APPLE, .name = "apple" }, { .id = CS420X_MBP101, .name = "mbp101" }, + { .id = CS420X_MBP81, .name = "mbp81" }, {} }; @@ -1298,6 +1308,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ /* codec SSID */ + SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), @@ -1408,11 +1419,16 @@ static const struct hda_fixup cs420x_fixups[] = { .type = HDA_FIXUP_PINS, .v.pins = mbp101_pincfgs, .chained = true, - .chain_id = CS420X_MBP101_COEF, + .chain_id = CS420X_GPIO_13, }, - [CS420X_MBP101_COEF] = { + [CS420X_MBP81] = { .type = HDA_FIXUP_VERBS, - .v.verbs = mbp101_init_verbs, + .v.verbs = (const struct hda_verb[]) { + /* internal mic ADC2: right only, single ended */ + {0x11, AC_VERB_SET_COEF_INDEX, IDX_ADC_CFG}, + {0x11, AC_VERB_SET_PROC_COEF, 0x102a}, + {} + }, .chained = true, .chain_id = CS420X_GPIO_13, }, @@ -1728,8 +1744,7 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, } -static struct snd_kcontrol_new cs421x_capture_source = { - +static const struct snd_kcontrol_new cs421x_capture_source = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -1946,7 +1961,7 @@ static int cs421x_suspend(struct hda_codec *codec) } #endif -static struct hda_codec_ops cs421x_patch_ops = { +static const struct hda_codec_ops cs421x_patch_ops = { .build_controls = cs421x_build_controls, .build_pcms = cs_build_pcms, .init = cs421x_init, |