Commit 677cd904aba939bc4cfdc3c1eada8ec46582127e

Authored by David Henningsson
Committed by Takashi Iwai
1 parent 3674f19dab

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;