aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_realtek.c241
1 files changed, 155 insertions, 86 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 87da5e805c8e..7810d3dcad83 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -17146,70 +17146,145 @@ static struct alc_config_preset alc662_presets[] = {
17146 * BIOS auto configuration 17146 * BIOS auto configuration
17147 */ 17147 */
17148 17148
17149/* convert from MIX nid to DAC */
17150static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17151{
17152 if (nid == 0x0f)
17153 return 0x02;
17154 else if (nid >= 0x0c && nid <= 0x0e)
17155 return nid - 0x0c + 0x02;
17156 else
17157 return 0;
17158}
17159
17160/* get MIX nid connected to the given pin targeted to DAC */
17161static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17162 hda_nid_t dac)
17163{
17164 hda_nid_t mix[4];
17165 int i, num;
17166
17167 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17168 for (i = 0; i < num; i++) {
17169 if (alc662_mix_to_dac(mix[i]) == dac)
17170 return mix[i];
17171 }
17172 return 0;
17173}
17174
17175/* look for an empty DAC slot */
17176static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17177{
17178 struct alc_spec *spec = codec->spec;
17179 hda_nid_t srcs[5];
17180 int i, j, num;
17181
17182 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17183 if (num < 0)
17184 return 0;
17185 for (i = 0; i < num; i++) {
17186 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17187 if (!nid)
17188 continue;
17189 for (j = 0; j < spec->multiout.num_dacs; j++)
17190 if (spec->multiout.dac_nids[j] == nid)
17191 break;
17192 if (j >= spec->multiout.num_dacs)
17193 return nid;
17194 }
17195 return 0;
17196}
17197
17198/* fill in the dac_nids table from the parsed pin configuration */
17199static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17200 const struct auto_pin_cfg *cfg)
17201{
17202 struct alc_spec *spec = codec->spec;
17203 int i;
17204 hda_nid_t dac;
17205
17206 spec->multiout.dac_nids = spec->private_dac_nids;
17207 for (i = 0; i < cfg->line_outs; i++) {
17208 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17209 if (!dac)
17210 continue;
17211 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17212 }
17213 return 0;
17214}
17215
17216static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17217 hda_nid_t nid, unsigned int chs)
17218{
17219 char name[32];
17220 sprintf(name, "%s Playback Volume", pfx);
17221 return add_control(spec, ALC_CTL_WIDGET_VOL, name,
17222 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17223}
17224
17225static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17226 hda_nid_t nid, unsigned int chs)
17227{
17228 char name[32];
17229 sprintf(name, "%s Playback Switch", pfx);
17230 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17231 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17232}
17233
17234#define alc662_add_stereo_vol(spec, pfx, nid) \
17235 alc662_add_vol_ctl(spec, pfx, nid, 3)
17236#define alc662_add_stereo_sw(spec, pfx, nid) \
17237 alc662_add_sw_ctl(spec, pfx, nid, 3)
17238
17149/* add playback controls from the parsed DAC table */ 17239/* add playback controls from the parsed DAC table */
17150static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 17240static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17151 const struct auto_pin_cfg *cfg) 17241 const struct auto_pin_cfg *cfg)
17152{ 17242{
17153 char name[32]; 17243 struct alc_spec *spec = codec->spec;
17154 static const char *chname[4] = { 17244 static const char *chname[4] = {
17155 "Front", "Surround", NULL /*CLFE*/, "Side" 17245 "Front", "Surround", NULL /*CLFE*/, "Side"
17156 }; 17246 };
17157 hda_nid_t nid; 17247 hda_nid_t nid, mix;
17158 int i, err; 17248 int i, err;
17159 17249
17160 for (i = 0; i < cfg->line_outs; i++) { 17250 for (i = 0; i < cfg->line_outs; i++) {
17161 if (!spec->multiout.dac_nids[i]) 17251 nid = spec->multiout.dac_nids[i];
17252 if (!nid)
17253 continue;
17254 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17255 if (!mix)
17162 continue; 17256 continue;
17163 nid = alc880_idx_to_dac(i);
17164 if (i == 2) { 17257 if (i == 2) {
17165 /* Center/LFE */ 17258 /* Center/LFE */
17166 err = add_control(spec, ALC_CTL_WIDGET_VOL, 17259 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17167 "Center Playback Volume",
17168 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
17169 HDA_OUTPUT));
17170 if (err < 0) 17260 if (err < 0)
17171 return err; 17261 return err;
17172 err = add_control(spec, ALC_CTL_WIDGET_VOL, 17262 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17173 "LFE Playback Volume",
17174 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
17175 HDA_OUTPUT));
17176 if (err < 0) 17263 if (err < 0)
17177 return err; 17264 return err;
17178 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 17265 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17179 "Center Playback Switch",
17180 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
17181 HDA_INPUT));
17182 if (err < 0) 17266 if (err < 0)
17183 return err; 17267 return err;
17184 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 17268 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17185 "LFE Playback Switch",
17186 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
17187 HDA_INPUT));
17188 if (err < 0) 17269 if (err < 0)
17189 return err; 17270 return err;
17190 } else { 17271 } else {
17191 const char *pfx; 17272 const char *pfx;
17192 if (cfg->line_outs == 1 && 17273 if (cfg->line_outs == 1 &&
17193 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 17274 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17194 if (!cfg->hp_pins) 17275 if (cfg->hp_outs)
17195 pfx = "Speaker"; 17276 pfx = "Speaker";
17196 else 17277 else
17197 pfx = "PCM"; 17278 pfx = "PCM";
17198 } else 17279 } else
17199 pfx = chname[i]; 17280 pfx = chname[i];
17200 sprintf(name, "%s Playback Volume", pfx); 17281 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17201 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17202 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
17203 HDA_OUTPUT));
17204 if (err < 0) 17282 if (err < 0)
17205 return err; 17283 return err;
17206 if (cfg->line_outs == 1 && 17284 if (cfg->line_outs == 1 &&
17207 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 17285 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17208 pfx = "Speaker"; 17286 pfx = "Speaker";
17209 sprintf(name, "%s Playback Switch", pfx); 17287 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17210 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17211 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),