Commit 677cd904aba939bc4cfdc3c1eada8ec46582127e
Committed by
Takashi Iwai
1 parent
3674f19dab
Exists in
master
and in
39 other branches
ALSA: HDA: New AD1984A model for Dell Precision R5500
For codec AD1984A, add a new model to support Dell Precision R5500 or the microphone jack won't work correctly. BugLink: http://bugs.launchpad.net/bugs/741516 Tested-by: Kent Baxley <kent.baxley@canonical.com> Cc: stable@kernel.org Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 1 changed file with 89 additions and 0 deletions Side-by-side Diff
sound/pci/hda/patch_analog.c
... | ... | @@ -4256,6 +4256,84 @@ |
4256 | 4256 | } |
4257 | 4257 | |
4258 | 4258 | /* |
4259 | + * Precision R5500 | |
4260 | + * 0x12 - HP/line-out | |
4261 | + * 0x13 - speaker (mono) | |
4262 | + * 0x15 - mic-in | |
4263 | + */ | |
4264 | + | |
4265 | +static struct hda_verb ad1984a_precision_verbs[] = { | |
4266 | + /* Unmute main output path */ | |
4267 | + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | |
4268 | + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ | |
4269 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ | |
4270 | + /* Analog mixer; mute as default */ | |
4271 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | |
4272 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | |
4273 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | |
4274 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | |
4275 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | |
4276 | + /* Select mic as input */ | |
4277 | + {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, | |
4278 | + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ | |
4279 | + /* Configure as mic */ | |
4280 | + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | |
4281 | + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | |
4282 | + /* HP unmute */ | |
4283 | + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
4284 | + /* turn on EAPD */ | |
4285 | + {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | |
4286 | + /* unsolicited event for pin-sense */ | |
4287 | + {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, | |
4288 | + { } /* end */ | |
4289 | +}; | |
4290 | + | |
4291 | +static struct snd_kcontrol_new ad1984a_precision_mixers[] = { | |
4292 | + HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | |
4293 | + HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | |
4294 | + HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | |
4295 | + HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), | |
4296 | + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | |
4297 | + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | |
4298 | + HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), | |
4299 | + HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), | |
4300 | + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), | |
4301 | + HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | |
4302 | + HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | |
4303 | + { } /* end */ | |
4304 | +}; | |
4305 | + | |
4306 | + | |
4307 | +/* mute internal speaker if HP is plugged */ | |
4308 | +static void ad1984a_precision_automute(struct hda_codec *codec) | |
4309 | +{ | |
4310 | + unsigned int present; | |
4311 | + | |
4312 | + present = snd_hda_jack_detect(codec, 0x12); | |
4313 | + snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, | |
4314 | + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | |
4315 | +} | |
4316 | + | |
4317 | + | |
4318 | +/* unsolicited event for HP jack sensing */ | |
4319 | +static void ad1984a_precision_unsol_event(struct hda_codec *codec, | |
4320 | + unsigned int res) | |
4321 | +{ | |
4322 | + if ((res >> 26) != AD1884A_HP_EVENT) | |
4323 | + return; | |
4324 | + ad1984a_precision_automute(codec); | |
4325 | +} | |
4326 | + | |
4327 | +/* initialize jack-sensing, too */ | |
4328 | +static int ad1984a_precision_init(struct hda_codec *codec) | |
4329 | +{ | |
4330 | + ad198x_init(codec); | |
4331 | + ad1984a_precision_automute(codec); | |
4332 | + return 0; | |
4333 | +} | |
4334 | + | |
4335 | + | |
4336 | +/* | |
4259 | 4337 | * HP Touchsmart |
4260 | 4338 | * port-A (0x11) - front hp-out |
4261 | 4339 | * port-B (0x14) - unused |
... | ... | @@ -4384,6 +4462,7 @@ |
4384 | 4462 | AD1884A_MOBILE, |
4385 | 4463 | AD1884A_THINKPAD, |
4386 | 4464 | AD1984A_TOUCHSMART, |
4465 | + AD1984A_PRECISION, | |
4387 | 4466 | AD1884A_MODELS |
4388 | 4467 | }; |
4389 | 4468 | |
4390 | 4469 | |
... | ... | @@ -4393,9 +4472,11 @@ |
4393 | 4472 | [AD1884A_MOBILE] = "mobile", |
4394 | 4473 | [AD1884A_THINKPAD] = "thinkpad", |
4395 | 4474 | [AD1984A_TOUCHSMART] = "touchsmart", |
4475 | + [AD1984A_PRECISION] = "precision", | |
4396 | 4476 | }; |
4397 | 4477 | |
4398 | 4478 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { |
4479 | + SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), | |
4399 | 4480 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), |
4400 | 4481 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), |
4401 | 4482 | SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), |
... | ... | @@ -4488,6 +4569,14 @@ |
4488 | 4569 | spec->input_mux = &ad1984a_thinkpad_capture_source; |
4489 | 4570 | codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; |
4490 | 4571 | codec->patch_ops.init = ad1984a_thinkpad_init; |
4572 | + break; | |
4573 | + case AD1984A_PRECISION: | |
4574 | + spec->mixers[0] = ad1984a_precision_mixers; | |
4575 | + spec->init_verbs[spec->num_init_verbs++] = | |
4576 | + ad1984a_precision_verbs; | |
4577 | + spec->multiout.dig_out_nid = 0; | |
4578 | + codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; | |
4579 | + codec->patch_ops.init = ad1984a_precision_init; | |
4491 | 4580 | break; |
4492 | 4581 | case AD1984A_TOUCHSMART: |
4493 | 4582 | spec->mixers[0] = ad1984a_touchsmart_mixers; |