diff options
author | David Henningsson <david.henningsson@canonical.com> | 2011-02-07 09:19:34 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-03-25 06:31:54 -0400 |
commit | 677cd904aba939bc4cfdc3c1eada8ec46582127e (patch) | |
tree | b084ca2bfa202bbe7b9eb7bbb3d19758d8853c38 | |
parent | 3674f19dabd15f9541079a588149a370d888f4e6 (diff) |
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>
-rw-r--r-- | sound/pci/hda/patch_analog.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 734c6ee55d8a..2942d2a9ea10 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -4256,6 +4256,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) | |||
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 | * HP Touchsmart | 4337 | * HP Touchsmart |
4260 | * port-A (0x11) - front hp-out | 4338 | * port-A (0x11) - front hp-out |
4261 | * port-B (0x14) - unused | 4339 | * port-B (0x14) - unused |
@@ -4384,6 +4462,7 @@ enum { | |||
4384 | AD1884A_MOBILE, | 4462 | AD1884A_MOBILE, |
4385 | AD1884A_THINKPAD, | 4463 | AD1884A_THINKPAD, |
4386 | AD1984A_TOUCHSMART, | 4464 | AD1984A_TOUCHSMART, |
4465 | AD1984A_PRECISION, | ||
4387 | AD1884A_MODELS | 4466 | AD1884A_MODELS |
4388 | }; | 4467 | }; |
4389 | 4468 | ||
@@ -4393,9 +4472,11 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { | |||
4393 | [AD1884A_MOBILE] = "mobile", | 4472 | [AD1884A_MOBILE] = "mobile", |
4394 | [AD1884A_THINKPAD] = "thinkpad", | 4473 | [AD1884A_THINKPAD] = "thinkpad", |
4395 | [AD1984A_TOUCHSMART] = "touchsmart", | 4474 | [AD1984A_TOUCHSMART] = "touchsmart", |
4475 | [AD1984A_PRECISION] = "precision", | ||
4396 | }; | 4476 | }; |
4397 | 4477 | ||
4398 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { | 4478 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { |
4479 | SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), | ||
4399 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), | 4480 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), |
4400 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), | 4481 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), |
4401 | SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), | 4482 | SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), |
@@ -4489,6 +4570,14 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4489 | codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; | 4570 | codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; |
4490 | codec->patch_ops.init = ad1984a_thinkpad_init; | 4571 | codec->patch_ops.init = ad1984a_thinkpad_init; |
4491 | break; | 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; | ||
4580 | break; | ||
4492 | case AD1984A_TOUCHSMART: | 4581 | case AD1984A_TOUCHSMART: |
4493 | spec->mixers[0] = ad1984a_touchsmart_mixers; | 4582 | spec->mixers[0] = ad1984a_touchsmart_mixers; |
4494 | spec->init_verbs[0] = ad1984a_touchsmart_verbs; | 4583 | spec->init_verbs[0] = ad1984a_touchsmart_verbs; |