diff options
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 137 |
1 files changed, 68 insertions, 69 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b4f78952381a..0ecd75e2d28f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -5068,6 +5068,25 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, | |||
5068 | return 0; | 5068 | return 0; |
5069 | } | 5069 | } |
5070 | 5070 | ||
5071 | static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, | ||
5072 | bool can_be_master) | ||
5073 | { | ||
5074 | if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) | ||
5075 | return "Master"; | ||
5076 | |||
5077 | switch (cfg->line_out_type) { | ||
5078 | case AUTO_PIN_SPEAKER_OUT: | ||
5079 | return "Speaker"; | ||
5080 | case AUTO_PIN_HP_OUT: | ||
5081 | return "Headphone"; | ||
5082 | default: | ||
5083 | if (cfg->line_outs == 1) | ||
5084 | return "PCM"; | ||
5085 | break; | ||
5086 | } | ||
5087 | return NULL; | ||
5088 | } | ||
5089 | |||
5071 | /* add playback controls from the parsed DAC table */ | 5090 | /* add playback controls from the parsed DAC table */ |
5072 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | 5091 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, |
5073 | const struct auto_pin_cfg *cfg) | 5092 | const struct auto_pin_cfg *cfg) |
@@ -5075,6 +5094,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5075 | static const char *chname[4] = { | 5094 | static const char *chname[4] = { |
5076 | "Front", "Surround", NULL /*CLFE*/, "Side" | 5095 | "Front", "Surround", NULL /*CLFE*/, "Side" |
5077 | }; | 5096 | }; |
5097 | const char *pfx = alc_get_line_out_pfx(cfg, false); | ||
5078 | hda_nid_t nid; | 5098 | hda_nid_t nid; |
5079 | int i, err; | 5099 | int i, err; |
5080 | 5100 | ||
@@ -5082,7 +5102,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5082 | if (!spec->multiout.dac_nids[i]) | 5102 | if (!spec->multiout.dac_nids[i]) |
5083 | continue; | 5103 | continue; |
5084 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | 5104 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); |
5085 | if (i == 2) { | 5105 | if (!pfx && i == 2) { |
5086 | /* Center/LFE */ | 5106 | /* Center/LFE */ |
5087 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, | 5107 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
5088 | "Center", | 5108 | "Center", |
@@ -5109,18 +5129,17 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5109 | if (err < 0) | 5129 | if (err < 0) |
5110 | return err; | 5130 | return err; |
5111 | } else { | 5131 | } else { |
5112 | const char *pfx; | 5132 | const char *name = pfx; |
5113 | if (cfg->line_outs == 1 && | 5133 | if (!name) |
5114 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | 5134 | name = chname[i]; |
5115 | pfx = "Speaker"; | 5135 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
5116 | else | 5136 | name, i, |
5117 | pfx = chname[i]; | ||
5118 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, | ||
5119 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | 5137 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
5120 | HDA_OUTPUT)); | 5138 | HDA_OUTPUT)); |
5121 | if (err < 0) | 5139 | if (err < 0) |
5122 | return err; | 5140 | return err; |
5123 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, | 5141 | err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
5142 | name, i, | ||
5124 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, | 5143 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, |
5125 | HDA_INPUT)); | 5144 | HDA_INPUT)); |
5126 | if (err < 0) | 5145 | if (err < 0) |
@@ -12085,13 +12104,8 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12085 | spec->multiout.dac_nids = spec->private_dac_nids; | 12104 | spec->multiout.dac_nids = spec->private_dac_nids; |
12086 | spec->multiout.dac_nids[0] = 2; | 12105 | spec->multiout.dac_nids[0] = 2; |
12087 | 12106 | ||
12088 | if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) | 12107 | pfx = alc_get_line_out_pfx(cfg, true); |
12089 | pfx = "Master"; | 12108 | if (!pfx) |
12090 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
12091 | pfx = "Speaker"; | ||
12092 | else if (cfg->line_out_type == AUTO_PIN_HP_OUT) | ||
12093 | pfx = "Headphone"; | ||
12094 | else | ||
12095 | pfx = "Front"; | 12109 | pfx = "Front"; |
12096 | for (i = 0; i < 2; i++) { | 12110 | for (i = 0; i < 2; i++) { |
12097 | err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); | 12111 | err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); |
@@ -15885,13 +15899,16 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec, | |||
15885 | return 0; | 15899 | return 0; |
15886 | } | 15900 | } |
15887 | 15901 | ||
15888 | static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, | 15902 | static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx, |
15889 | hda_nid_t nid, unsigned int chs) | 15903 | hda_nid_t nid, int idx, unsigned int chs) |
15890 | { | 15904 | { |
15891 | return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, | 15905 | return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx, |
15892 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 15906 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
15893 | } | 15907 | } |
15894 | 15908 | ||
15909 | #define alc861_create_out_sw(codec, pfx, nid, chs) \ | ||
15910 | __alc861_create_out_sw(codec, pfx, nid, 0, chs) | ||
15911 | |||
15895 | /* add playback controls from the parsed DAC table */ | 15912 | /* add playback controls from the parsed DAC table */ |
15896 | static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, | 15913 | static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, |
15897 | const struct auto_pin_cfg *cfg) | 15914 | const struct auto_pin_cfg *cfg) |
@@ -15900,26 +15917,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
15900 | static const char *chname[4] = { | 15917 | static const char *chname[4] = { |
15901 | "Front", "Surround", NULL /*CLFE*/, "Side" | 15918 | "Front", "Surround", NULL /*CLFE*/, "Side" |
15902 | }; | 15919 | }; |
15920 | const char *pfx = alc_get_line_out_pfx(cfg, true); | ||
15903 | hda_nid_t nid; | 15921 | hda_nid_t nid; |
15904 | int i, err; | 15922 | int i, err; |
15905 | 15923 | ||
15906 | if (cfg->line_outs == 1) { | ||
15907 | const char *pfx = NULL; | ||
15908 | if (!cfg->hp_outs) | ||
15909 | pfx = "Master"; | ||
15910 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
15911 | pfx = "Speaker"; | ||
15912 | if (pfx) { | ||
15913 | nid = spec->multiout.dac_nids[0]; | ||
15914 | return alc861_create_out_sw(codec, pfx, nid, 3); | ||
15915 | } | ||
15916 | } | ||
15917 | |||
15918 | for (i = 0; i < cfg->line_outs; i++) { | 15924 | for (i = 0; i < cfg->line_outs; i++) { |
15919 | nid = spec->multiout.dac_nids[i]; | 15925 | nid = spec->multiout.dac_nids[i]; |
15920 | if (!nid) | 15926 | if (!nid) |
15921 | continue; | 15927 | continue; |
15922 | if (i == 2) { | 15928 | if (!pfx && i == 2) { |
15923 | /* Center/LFE */ | 15929 | /* Center/LFE */ |
15924 | err = alc861_create_out_sw(codec, "Center", nid, 1); | 15930 | err = alc861_create_out_sw(codec, "Center", nid, 1); |
15925 | if (err < 0) | 15931 | if (err < 0) |
@@ -15928,7 +15934,10 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
15928 | if (err < 0) | 15934 | if (err < 0) |
15929 | return err; | 15935 | return err; |
15930 | } else { | 15936 | } else { |
15931 | err = alc861_create_out_sw(codec, chname[i], nid, 3); | 15937 | const char *name = pfx; |
15938 | if (!name) | ||
15939 | name = chname[i]; | ||
15940 | err = __alc861_create_out_sw(codec, name, nid, i, 3); | ||
15932 | if (err < 0) | 15941 | if (err < 0) |
15933 | return err; | 15942 | return err; |
15934 | } | 15943 | } |
@@ -17033,6 +17042,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
17033 | const struct auto_pin_cfg *cfg) | 17042 | const struct auto_pin_cfg *cfg) |
17034 | { | 17043 | { |
17035 | static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; | 17044 | static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; |
17045 | const char *pfx = alc_get_line_out_pfx(cfg, true); | ||
17036 | hda_nid_t nid_v, nid_s; | 17046 | hda_nid_t nid_v, nid_s; |
17037 | int i, err; | 17047 | int i, err; |
17038 | 17048 | ||
@@ -17046,7 +17056,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
17046 | alc880_dac_to_idx( | 17056 | alc880_dac_to_idx( |
17047 | spec->multiout.dac_nids[i])); | 17057 | spec->multiout.dac_nids[i])); |
17048 | 17058 | ||
17049 | if (i == 2) { | 17059 | if (!pfx && i == 2) { |
17050 | /* Center/LFE */ | 17060 | /* Center/LFE */ |
17051 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, | 17061 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
17052 | "Center", | 17062 | "Center", |
@@ -17073,24 +17083,17 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
17073 | if (err < 0) | 17083 | if (err < 0) |
17074 | return err; | 17084 | return err; |
17075 | } else { | 17085 | } else { |
17076 | const char *pfx; | 17086 | const char *name = pfx; |
17077 | if (cfg->line_outs == 1 && | 17087 | if (!name) |
17078 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | 17088 | name = chname[i]; |
17079 | if (!cfg->hp_pins) | 17089 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
17080 | pfx = "Speaker"; | 17090 | name, i, |
17081 | else | ||
17082 | pfx = "PCM"; | ||
17083 | } else | ||
17084 | pfx = chname[i]; | ||
17085 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, | ||
17086 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, | 17091 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, |
17087 | HDA_OUTPUT)); | 17092 | HDA_OUTPUT)); |
17088 | if (err < 0) | 17093 | if (err < 0) |
17089 | return err; | 17094 | return err; |
17090 | if (cfg->line_outs == 1 && | 17095 | err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
17091 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | 17096 | name, i, |
17092 | pfx = "Speaker"; | ||
17093 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, | ||
17094 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, | 17097 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, |
17095 | HDA_INPUT)); | 17098 | HDA_INPUT)); |
17096 | if (err < 0) | 17099 | if (err < 0) |
@@ -19078,20 +19081,24 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec, | |||
19078 | return 0; | 19081 | return 0; |
19079 | } | 19082 | } |
19080 | 19083 | ||
19081 | static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, | 19084 | static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, |
19082 | hda_nid_t nid, unsigned int chs) | 19085 | hda_nid_t nid, int idx, unsigned int chs) |
19083 | { | 19086 | { |
19084 | return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, | 19087 | return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, |
19085 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 19088 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
19086 | } | 19089 | } |
19087 | 19090 | ||
19088 | static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, | 19091 | static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, |
19089 | hda_nid_t nid, unsigned int chs) | 19092 | hda_nid_t nid, int idx, unsigned int chs) |
19090 | { | 19093 | { |
19091 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, | 19094 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, |
19092 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); | 19095 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); |
19093 | } | 19096 | } |
19094 | 19097 | ||
19098 | #define alc662_add_vol_ctl(spec, pfx, nid, chs) \ | ||
19099 | __alc662_add_vol_ctl(spec, pfx, nid, 0, chs) | ||
19100 | #define alc662_add_sw_ctl(spec, pfx, nid, chs) \ | ||
19101 | __alc662_add_sw_ctl(spec, pfx, nid, 0, chs) | ||
19095 | #define alc662_add_stereo_vol(spec, pfx, nid) \ | 19102 | #define alc662_add_stereo_vol(spec, pfx, nid) \ |
19096 | alc662_add_vol_ctl(spec, pfx, nid, 3) | 19103 | alc662_add_vol_ctl(spec, pfx, nid, 3) |
19097 | #define alc662_add_stereo_sw(spec, pfx, nid) \ | 19104 | #define alc662_add_stereo_sw(spec, pfx, nid) \ |
@@ -19105,6 +19112,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
19105 | static const char *chname[4] = { | 19112 | static const char *chname[4] = { |
19106 | "Front", "Surround", NULL /*CLFE*/, "Side" | 19113 | "Front", "Surround", NULL /*CLFE*/, "Side" |
19107 | }; | 19114 | }; |
19115 | const char *pfx = alc_get_line_out_pfx(cfg, true); | ||
19108 | hda_nid_t nid, mix; | 19116 | hda_nid_t nid, mix; |
19109 | int i, err; | 19117 | int i, err; |
19110 | 19118 | ||
@@ -19115,7 +19123,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
19115 | mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); | 19123 | mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); |
19116 | if (!mix) | 19124 | if (!mix) |
19117 | continue; | 19125 | continue; |
19118 | if (i == 2) { | 19126 | if (!pfx && i == 2) { |
19119 | /* Center/LFE */ | 19127 | /* Center/LFE */ |
19120 | err = alc662_add_vol_ctl(spec, "Center", nid, 1); | 19128 | err = alc662_add_vol_ctl(spec, "Center", nid, 1); |
19121 | if (err < 0) | 19129 | if (err < 0) |
@@ -19130,22 +19138,13 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
19130 | if (err < 0) | 19138 | if (err < 0) |
19131 | return err; | 19139 | return err; |
19132 | } else { | 19140 | } else { |
19133 | const char *pfx; | 19141 | const char *name = pfx; |
19134 | if (cfg->line_outs == 1 && | 19142 | if (!name) |
19135 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | 19143 | name = chname[i]; |
19136 | if (cfg->hp_outs) | 19144 | err = __alc662_add_vol_ctl(spec, name, nid, i, 3); |
19137 | pfx = "Speaker"; | ||
19138 | else | ||
19139 | pfx = "PCM"; | ||
19140 | } else | ||
19141 | pfx = chname[i]; | ||
19142 | err = alc662_add_vol_ctl(spec, pfx, nid, 3); | ||
19143 | if (err < 0) | 19145 | if (err < 0) |
19144 | return err; | 19146 | return err; |
19145 | if (cfg->line_outs == 1 && | 19147 | err = __alc662_add_sw_ctl(spec, name, mix, i, 3); |
19146 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
19147 | pfx = "Speaker"; | ||
19148 | err = alc662_add_sw_ctl(spec, pfx, mix, 3); | ||
19149 | if (err < 0) | 19148 | if (err < 0) |
19150 | return err; | 19149 | return err; |
19151 | } | 19150 | } |