aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_realtek.c331
1 files changed, 330 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f1ce7d7f5aa3..630e66743e8e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -18612,7 +18612,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18612 18612
18613 add_verb(spec, alc662_init_verbs); 18613 add_verb(spec, alc662_init_verbs);
18614 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18614 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18615 codec->vendor_id == 0x10ec0665) 18615 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18616 add_verb(spec, alc663_init_verbs); 18616 add_verb(spec, alc663_init_verbs);
18617 18617
18618 if (codec->vendor_id == 0x10ec0272) 18618 if (codec->vendor_id == 0x10ec0272)
@@ -18756,6 +18756,334 @@ static int patch_alc888(struct hda_codec *codec)
18756} 18756}
18757 18757
18758/* 18758/*
18759 * ALC680 support
18760 */
18761#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18762#define alc680_modes alc260_modes
18763
18764static hda_nid_t alc680_dac_nids[3] = {
18765 /* Lout1, Lout2, hp */
18766 0x02, 0x03, 0x04
18767};
18768
18769static hda_nid_t alc680_adc_nids[3] = {
18770 /* ADC0-2 */
18771 /* DMIC, MIC, Line-in*/
18772 0x07, 0x08, 0x09
18773};
18774
18775static struct snd_kcontrol_new alc680_base_mixer[] = {
18776 /* output mixer control */
18777 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18778 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18779 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18780 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18781 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18782 { }
18783};
18784
18785static struct snd_kcontrol_new alc680_capture_mixer[] = {
18786 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18787 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18788 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18789 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18790 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18791 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18792 { } /* end */
18793};
18794
18795/*
18796 * generic initialization of ADC, input mixers and output mixers
18797 */
18798static struct hda_verb alc680_init_verbs[] = {
18799 /* Unmute DAC0-1 and set vol = 0 */
18800 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18801 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18802 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18803
18804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
18805 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
18806 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
18807 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
18808 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
18809
18810 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18815 { }
18816};
18817
18818/* create input playback/capture controls for the given pin */
18819static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
18820 const char *ctlname, int idx)
18821{
18822 hda_nid_t dac;
18823 int err;
18824
18825 switch (nid) {
18826 case 0x14:
18827 dac = 0x02;
18828 break;
18829 case 0x15:
18830 dac = 0x03;
18831 break;
18832 case 0x16:
18833 dac = 0x04;
18834 break;
18835 default:
18836 return 0;
18837 }
18838 if (spec->multiout.dac_nids[0] != dac &&
18839 spec->multiout.dac_nids[1] != dac) {
18840 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
18841 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
18842 HDA_OUTPUT));
18843 if (err < 0)
18844 return err;
18845
18846 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
18847 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
18848
18849 if (err < 0)
18850 return err;
18851 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18852 }
18853
18854 return 0;
18855}
18856
18857/* add playback controls from the parsed DAC table */
18858static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
18859 const struct auto_pin_cfg *cfg)
18860{
18861 hda_nid_t nid;
18862 int err;
18863
18864 spec->multiout.dac_nids = spec->private_dac_nids;
18865
18866 nid = cfg->line_out_pins[0];
18867 if (nid) {
18868 const char *name;
18869 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18870 name = "Speaker";
18871 else
18872 name = "Front";
18873 err = alc680_new_analog_output(spec, nid, name, 0);
18874 if (err < 0)
18875 return err;
18876 }
18877
18878 nid = cfg->speaker_pins[0];
18879 if (nid) {
18880 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
18881 if (err < 0)
18882 return err;
18883 }
18884 nid = cfg->hp_pins[0];
18885 if (nid) {
18886 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
18887 if (err < 0)
18888 return err;
18889 }
18890
18891 return 0;
18892}
18893
18894static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
18895 hda_nid_t nid, int pin_type)
18896{
18897 alc_set_pin_output(codec, nid, pin_type);
18898}
18899
18900static void alc680_auto_init_multi_out(struct hda_codec *codec)
18901{
18902 struct alc_spec *spec = codec->spec;
18903 hda_nid_t nid = spec->autocfg.line_out_pins[0];
18904 if (nid) {
18905 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18906 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
18907 }
18908}
18909
18910static void alc680_auto_init_hp_out(struct hda_codec *codec)
18911{
18912 struct alc_spec *spec = codec->spec;
18913 hda_nid_t pin;
18914
18915 pin = spec->autocfg.hp_pins[0];
18916 if (pin)
18917 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
18918 pin = spec->autocfg.speaker_pins[0];
18919 if (pin)
18920 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
18921}
18922
18923/* pcm configuration: identical with ALC880 */
18924#define alc680_pcm_analog_playback alc880_pcm_analog_playback
18925#define alc680_pcm_analog_capture alc880_pcm_analog_capture
18926#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
18927#define alc680_pcm_digital_playback alc880_pcm_digital_playback
18928
18929static struct hda_input_mux alc680_capture_source = {
18930 .num_items = 1,
18931 .items = {
18932 { "Mic", 0x0 },
18933 },
18934};
18935
18936/*
18937 * BIOS auto configuration
18938 */
18939static int alc680_parse_auto_config(struct hda_codec *codec)
18940{
18941 struct alc_spec *spec = codec->spec;
18942 int err;
18943 static hda_nid_t alc680_ignore[] = { 0 };
18944
18945 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18946 alc680_ignore);
18947 if (err < 0)
18948 return err;
18949 if (!spec->autocfg.line_outs) {
18950 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
18951 spec->multiout.max_channels = 2;
18952 spec->no_analog = 1;
18953 goto dig_only;
18954 }
18955 return 0; /* can't find valid BIOS pin config */
18956 }
18957 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
18958 if (err < 0)
18959 return err;
18960
18961 spec->multiout.max_channels = 2;
18962
18963 dig_only:
18964 /* digital only support output */
18965 if (spec->autocfg.dig_outs) {
18966 spec->multiout.dig_out_nid = ALC680_DIGOUT_NID;
18967 spec->dig_out_type = spec->autocfg.dig_out_type[0];
18968 }
18969 if (spec->kctls.list)
18970 add_mixer(spec, spec->kctls.list);
18971
18972 add_verb(spec, alc680_init_verbs);
18973 spec->num_mux_defs = 1;
18974 spec->input_mux = &alc680_capture_source;
18975
18976 err = alc_auto_add_mic_boost(codec);
18977 if (err < 0)
18978 return err;
18979
18980 return 1;
18981}
18982
18983#define alc680_auto_init_analog_input alc882_auto_init_analog_input
18984
18985/* init callback for auto-configuration model -- overriding the default init */
18986static void alc680_auto_init(struct hda_codec *codec)
18987{
18988 struct alc_spec *spec = codec->spec;
18989 alc680_auto_init_multi_out(codec);
18990 alc680_auto_init_hp_out(codec);
18991 alc680_auto_init_analog_input(codec);
18992 if (spec->unsol_event)
18993 alc_inithook(codec);
18994}
18995
18996/*
18997 * configuration and preset
18998 */
18999static const char *alc680_models[ALC680_MODEL_LAST] = {
19000 [ALC680_BASE] = "alc680_base",
19001};
19002
19003static struct snd_pci_quirk alc680_cfg_tbl[] = {
19004 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19005 {}
19006};
19007
19008static struct alc_config_preset alc680_presets[] = {
19009 [ALC680_BASE] = {
19010 .mixers = { alc680_base_mixer },
19011 .cap_mixer = alc680_capture_mixer,
19012 .init_verbs = { alc680_init_verbs },
19013 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19014 .dac_nids = alc680_dac_nids,
19015 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19016 .adc_nids = alc680_adc_nids,
19017 .hp_nid = 0x04,
19018 .dig_out_nid = ALC680_DIGOUT_NID,
19019 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19020 .channel_mode = alc680_modes,
19021 .input_mux = &alc680_capture_source,
19022 },
19023};
19024
19025static int patch_alc680(struct hda_codec *codec)
19026{
19027 struct alc_spec *spec;
19028 int board_config;
19029 int err;
19030
19031 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19032 if (spec == NULL)
19033 return -ENOMEM;
19034
19035 codec->spec = spec;
19036
19037 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19038 alc680_models,
19039 alc680_cfg_tbl);
19040
19041 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19042 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19043 codec->chip_name);
19044 board_config = ALC680_AUTO;
19045 }
19046
19047 if (board_config == ALC680_AUTO) {
19048 /* automatic parse from the BIOS config */
19049 err = alc680_parse_auto_config(codec);
19050 if (err < 0) {
19051 alc_free(codec);
19052 return err;
19053 } else if (!err) {
19054 printk(KERN_INFO
19055 "hda_codec: Cannot set up configuration "
19056 "from BIOS. Using base mode...\n");
19057 board_config = ALC680_BASE;
19058 }
19059 }
19060
19061 if (board_config != ALC680_AUTO)
19062 setup_preset(codec, &alc680_presets[board_config]);
19063
19064 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19065 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19066 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19067 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19068
19069 if (!spec->adc_nids) {
19070 spec->adc_nids = alc680_adc_nids;
19071 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19072 }
19073
19074 if (!spec->cap_mixer)
19075 set_capture_mixer(codec);
19076
19077 spec->vmaster_nid = 0x02;
19078
19079 codec->patch_ops = alc_patch_ops;
19080 if (board_config == ALC680_AUTO)
19081 spec->init_hook = alc680_auto_init;
19082
19083 return 0;
19084}
19085
19086/*
18759 * patch entries 19087 * patch entries
18760 */ 19088 */
18761static struct hda_codec_preset snd_hda_preset_realtek[] = { 19089static struct hda_codec_preset snd_hda_preset_realtek[] = {
@@ -18779,6 +19107,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
18779 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 19107 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18780 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 19108 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18781 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 19109 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19110 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
18782 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 19111 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18783 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 19112 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18784 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 19113 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },