1 /* 2 * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, 3 * AD1986A, AD1988 4 * 5 * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> 6 * 7 * This driver is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This driver is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 #include <linux/init.h> 23 #include <linux/slab.h> 24 #include <linux/pci.h> 25 #include <linux/module.h> 26 27 #include <sound/core.h> 28 #include "hda_codec.h" 29 #include "hda_local.h" 30 #include "hda_auto_parser.h" 31 #include "hda_beep.h" 32 #include "hda_jack.h" 33 #include "hda_generic.h" 34 35 36 struct ad198x_spec { 37 struct hda_gen_spec gen; 38 39 /* for auto parser */ 40 int smux_paths[4]; 41 unsigned int cur_smux; 42 hda_nid_t eapd_nid; 43 44 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 45 }; 46 47 48 #ifdef CONFIG_SND_HDA_INPUT_BEEP 49 /* additional beep mixers; the actual parameters are overwritten at build */ 50 static const struct snd_kcontrol_new ad_beep_mixer[] = { 51 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), 52 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), 53 { } /* end */ 54 }; 55 56 #define set_beep_amp(spec, nid, idx, dir) \ 57 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 58 #else 59 #define set_beep_amp(spec, nid, idx, dir) /* NOP */ 60 #endif 61 62 #ifdef CONFIG_SND_HDA_INPUT_BEEP 63 static int create_beep_ctls(struct hda_codec *codec) 64 { 65 struct ad198x_spec *spec = codec->spec; 66 const struct snd_kcontrol_new *knew; 67 68 if (!spec->beep_amp) 69 return 0; 70 71 for (knew = ad_beep_mixer ; knew->name; knew++) { 72 int err; 73 struct snd_kcontrol *kctl; 74 kctl = snd_ctl_new1(knew, codec); 75 if (!kctl) 76 return -ENOMEM; 77 kctl->private_value = spec->beep_amp; 78 err = snd_hda_ctl_add(codec, 0, kctl); 79 if (err < 0) 80 return err; 81 } 82 return 0; 83 } 84 #else 85 #define create_beep_ctls(codec) 0 86 #endif 87 88 89 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, 90 hda_nid_t hp) 91 { 92 if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) 93 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, 94 !codec->inv_eapd ? 0x00 : 0x02); 95 if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) 96 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, 97 !codec->inv_eapd ? 0x00 : 0x02); 98 } 99 100 static void ad198x_power_eapd(struct hda_codec *codec) 101 { 102 /* We currently only handle front, HP */ 103 switch (codec->vendor_id) { 104 case 0x11d41882: 105 case 0x11d4882a: 106 case 0x11d41884: 107 case 0x11d41984: 108 case 0x11d41883: 109 case 0x11d4184a: 110 case 0x11d4194a: 111 case 0x11d4194b: 112 case 0x11d41988: 113 case 0x11d4198b: 114 case 0x11d4989a: 115 case 0x11d4989b: 116 ad198x_power_eapd_write(codec, 0x12, 0x11); 117 break; 118 case 0x11d41981: 119 case 0x11d41983: 120 ad198x_power_eapd_write(codec, 0x05, 0x06); 121 break; 122 case 0x11d41986: 123 ad198x_power_eapd_write(codec, 0x1b, 0x1a); 124 break; 125 } 126 } 127 128 static void ad198x_shutup(struct hda_codec *codec) 129 { 130 snd_hda_shutup_pins(codec); 131 ad198x_power_eapd(codec); 132 } 133 134 #ifdef CONFIG_PM 135 static int ad198x_suspend(struct hda_codec *codec) 136 { 137 ad198x_shutup(codec); 138 return 0; 139 } 140 #endif 141 142 /* follow EAPD via vmaster hook */ 143 static void ad_vmaster_eapd_hook(void *private_data, int enabled) 144 { 145 struct hda_codec *codec = private_data; 146 struct ad198x_spec *spec = codec->spec; 147 148 if (!spec->eapd_nid) 149 return; 150 if (codec->inv_eapd) 151 enabled = !enabled; 152 snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, 153 AC_VERB_SET_EAPD_BTLENABLE, 154 enabled ? 0x02 : 0x00); 155 } 156 157 /* 158 * Automatic parse of I/O pins from the BIOS configuration 159 */ 160 161 static int ad198x_auto_build_controls(struct hda_codec *codec) 162 { 163 int err; 164 165 err = snd_hda_gen_build_controls(codec); 166 if (err < 0) 167 return err; 168 err = create_beep_ctls(codec); 169 if (err < 0) 170 return err; 171 return 0; 172 } 173 174 static const struct hda_codec_ops ad198x_auto_patch_ops = { 175 .build_controls = ad198x_auto_build_controls, 176 .build_pcms = snd_hda_gen_build_pcms, 177 .init = snd_hda_gen_init, 178 .free = snd_hda_gen_free, 179 .unsol_event = snd_hda_jack_unsol_event, 180 #ifdef CONFIG_PM 181 .check_power_status = snd_hda_gen_check_power_status, 182 .suspend = ad198x_suspend, 183 #endif 184 .reboot_notify = ad198x_shutup, 185 }; 186 187 188 static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp) 189 { 190 struct ad198x_spec *spec = codec->spec; 191 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 192 int err; 193 194 codec->spdif_status_reset = 1; 195 codec->no_trigger_sense = 1; 196 codec->no_sticky_stream = 1; 197 198 spec->gen.indep_hp = indep_hp; 199 spec->gen.add_stereo_mix_input = 1; 200 201 err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); 202 if (err < 0) 203 return err; 204 err = snd_hda_gen_parse_auto_config(codec, cfg); 205 if (err < 0) 206 return err; 207 208 codec->patch_ops = ad198x_auto_patch_ops; 209 210 return 0; 211 } 212 213 /* 214 * AD1986A specific 215 */ 216 217 static int alloc_ad_spec(struct hda_codec *codec) 218 { 219 struct ad198x_spec *spec; 220 221 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 222 if (!spec) 223 return -ENOMEM; 224 codec->spec = spec; 225 snd_hda_gen_spec_init(&spec->gen); 226 return 0; 227 } 228 229 /* 230 * AD1986A fixup codes 231 */ 232 233 /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ 234 static void ad_fixup_inv_jack_detect(struct hda_codec *codec, 235 const struct hda_fixup *fix, int action) 236 { 237 struct ad198x_spec *spec = codec->spec; 238 239 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 240 codec->inv_jack_detect = 1; 241 spec->gen.keep_eapd_on = 1; 242 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 243 spec->eapd_nid = 0x1b; 244 } 245 } 246 247 enum { 248 AD1986A_FIXUP_INV_JACK_DETECT, 249 AD1986A_FIXUP_ULTRA, 250 AD1986A_FIXUP_SAMSUNG, 251 AD1986A_FIXUP_3STACK, 252 AD1986A_FIXUP_LAPTOP, 253 AD1986A_FIXUP_LAPTOP_IMIC, 254 }; 255 256 static const struct hda_fixup ad1986a_fixups[] = { 257 [AD1986A_FIXUP_INV_JACK_DETECT] = { 258 .type = HDA_FIXUP_FUNC, 259 .v.func = ad_fixup_inv_jack_detect, 260 }, 261 [AD1986A_FIXUP_ULTRA] = { 262 .type = HDA_FIXUP_PINS, 263 .v.pins = (const struct hda_pintbl[]) { 264 { 0x1b, 0x90170110 }, /* speaker */ 265 { 0x1d, 0x90a7013e }, /* int mic */ 266 {} 267 }, 268 }, 269 [AD1986A_FIXUP_SAMSUNG] = { 270 .type = HDA_FIXUP_PINS, 271 .v.pins = (const struct hda_pintbl[]) { 272 { 0x1b, 0x90170110 }, /* speaker */ 273 { 0x1d, 0x90a7013e }, /* int mic */ 274 { 0x20, 0x411111f0 }, /* N/A */ 275 { 0x24, 0x411111f0 }, /* N/A */ 276 {} 277 }, 278 }, 279 [AD1986A_FIXUP_3STACK] = { 280 .type = HDA_FIXUP_PINS, 281 .v.pins = (const struct hda_pintbl[]) { 282 { 0x1a, 0x02214021 }, /* headphone */ 283 { 0x1b, 0x01014011 }, /* front */ 284 { 0x1c, 0x01813030 }, /* line-in */ 285 { 0x1d, 0x01a19020 }, /* rear mic */ 286 { 0x1e, 0x411111f0 }, /* N/A */ 287 { 0x1f, 0x02a190f0 }, /* mic */ 288 { 0x20, 0x411111f0 }, /* N/A */ 289 {} 290 }, 291 }, 292 [AD1986A_FIXUP_LAPTOP] = { 293 .type = HDA_FIXUP_PINS, 294 .v.pins = (const struct hda_pintbl[]) { 295 { 0x1a, 0x02214021 }, /* headphone */ 296 { 0x1b, 0x90170110 }, /* speaker */ 297 { 0x1c, 0x411111f0 }, /* N/A */ 298 { 0x1d, 0x411111f0 }, /* N/A */ 299 { 0x1e, 0x411111f0 }, /* N/A */ 300 { 0x1f, 0x02a191f0 }, /* mic */ 301 { 0x20, 0x411111f0 }, /* N/A */ 302 {} 303 }, 304 }, 305 [AD1986A_FIXUP_LAPTOP_IMIC] = { 306 .type = HDA_FIXUP_PINS, 307 .v.pins = (const struct hda_pintbl[]) { 308 { 0x1d, 0x90a7013e }, /* int mic */ 309 {} 310 }, 311 .chained_before = 1, 312 .chain_id = AD1986A_FIXUP_LAPTOP, 313 }, 314 }; 315 316 static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { 317 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC), 318 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), 319 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), 320 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), 321 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), 322 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), 323 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), 324 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), 325 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK), 326 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK), 327 {} 328 }; 329 330 static const struct hda_model_fixup ad1986a_fixup_models[] = { 331 { .id = AD1986A_FIXUP_3STACK, .name = "3stack" }, 332 { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" }, 333 { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" }, 334 { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */ 335 {} 336 }; 337 338 /* 339 */ 340 static int patch_ad1986a(struct hda_codec *codec) 341 { 342 int err; 343 struct ad198x_spec *spec; 344 static hda_nid_t preferred_pairs[] = { 345 0x1a, 0x03, 346 0x1b, 0x03, 347 0x1c, 0x04, 348 0x1d, 0x05, 349 0x1e, 0x03, 350 0 351 }; 352 353 err = alloc_ad_spec(codec); 354 if (err < 0) 355 return err; 356 spec = codec->spec; 357 358 /* AD1986A has the inverted EAPD implementation */ 359 codec->inv_eapd = 1; 360 361 spec->gen.mixer_nid = 0x07; 362 spec->gen.beep_nid = 0x19; 363 set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); 364 365 /* AD1986A has a hardware problem that it can't share a stream 366 * with multiple output pins. The copy of front to surrounds 367 * causes noisy or silent outputs at a certain timing, e.g. 368 * changing the volume. 369 * So, let's disable the shared stream. 370 */ 371 spec->gen.multiout.no_share_stream = 1; 372 /* give fixed DAC/pin pairs */ 373 spec->gen.preferred_dacs = preferred_pairs; 374 375 /* AD1986A can't manage the dynamic pin on/off smoothly */ 376 spec->gen.auto_mute_via_amp = 1; 377 378 snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl, 379 ad1986a_fixups); 380 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 381 382 err = ad198x_parse_auto_config(codec, false); 383 if (err < 0) { 384 snd_hda_gen_free(codec); 385 return err; 386 } 387 388 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 389 390 return 0; 391 } 392 393 394 /* 395 * AD1983 specific 396 */ 397 398 /* 399 * SPDIF mux control for AD1983 auto-parser 400 */ 401 static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol, 402 struct snd_ctl_elem_info *uinfo) 403 { 404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 405 struct ad198x_spec *spec = codec->spec; 406 static const char * const texts2[] = { "PCM", "ADC" }; 407 static const char * const texts3[] = { "PCM", "ADC1", "ADC2" }; 408 hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; 409 int num_conns = snd_hda_get_num_conns(codec, dig_out); 410 411 if (num_conns == 2) 412 return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2); 413 else if (num_conns == 3) 414 return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); 415 else 416 return -EINVAL; 417 } 418 419 static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol, 420 struct snd_ctl_elem_value *ucontrol) 421 { 422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 423 struct ad198x_spec *spec = codec->spec; 424 425 ucontrol->value.enumerated.item[0] = spec->cur_smux; 426 return 0; 427 } 428 429 static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol, 430 struct snd_ctl_elem_value *ucontrol) 431 { 432 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 433 struct ad198x_spec *spec = codec->spec; 434 unsigned int val = ucontrol->value.enumerated.item[0]; 435 hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; 436 int num_conns = snd_hda_get_num_conns(codec, dig_out); 437 438 if (val >= num_conns) 439 return -EINVAL; 440 if (spec->cur_smux == val) 441 return 0; 442 spec->cur_smux = val; 443 snd_hda_codec_write_cache(codec, dig_out, 0, 444 AC_VERB_SET_CONNECT_SEL, val); 445 return 1; 446 } 447 448 static struct snd_kcontrol_new ad1983_auto_smux_mixer = { 449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 450 .name = "IEC958 Playback Source", 451 .info = ad1983_auto_smux_enum_info, 452 .get = ad1983_auto_smux_enum_get, 453 .put = ad1983_auto_smux_enum_put, 454 }; 455 456 static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) 457 { 458 struct ad198x_spec *spec = codec->spec; 459 hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; 460 int num_conns; 461 462 if (!dig_out) 463 return 0; 464 num_conns = snd_hda_get_num_conns(codec, dig_out); 465 if (num_conns != 2 && num_conns != 3) 466 return 0; 467 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer)) 468 return -ENOMEM; 469 return 0; 470 } 471 472 static int patch_ad1983(struct hda_codec *codec) 473 { 474 struct ad198x_spec *spec; 475 int err; 476 477 err = alloc_ad_spec(codec); 478 if (err < 0) 479 return err; 480 spec = codec->spec; 481 482 spec->gen.beep_nid = 0x10; 483 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 484 err = ad198x_parse_auto_config(codec, false); 485 if (err < 0) 486 goto error; 487 err = ad1983_add_spdif_mux_ctl(codec); 488 if (err < 0) 489 goto error; 490 return 0; 491 492 error: 493 snd_hda_gen_free(codec); 494 return err; 495 } 496 497 498 /* 499 * AD1981 HD specific 500 */ 501 502 static void ad1981_fixup_hp_eapd(struct hda_codec *codec, 503 const struct hda_fixup *fix, int action) 504 { 505 struct ad198x_spec *spec = codec->spec; 506 507 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 508 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 509 spec->eapd_nid = 0x05; 510 } 511 } 512 513 /* set the upper-limit for mixer amp to 0dB for avoiding the possible 514 * damage by overloading 515 */ 516 static void ad1981_fixup_amp_override(struct hda_codec *codec, 517 const struct hda_fixup *fix, int action) 518 { 519 if (action == HDA_FIXUP_ACT_PRE_PROBE) 520 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, 521 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 522 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 523 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 524 (1 << AC_AMPCAP_MUTE_SHIFT)); 525 } 526 527 enum { 528 AD1981_FIXUP_AMP_OVERRIDE, 529 AD1981_FIXUP_HP_EAPD, 530 }; 531 532 static const struct hda_fixup ad1981_fixups[] = { 533 [AD1981_FIXUP_AMP_OVERRIDE] = { 534 .type = HDA_FIXUP_FUNC, 535 .v.func = ad1981_fixup_amp_override, 536 }, 537 [AD1981_FIXUP_HP_EAPD] = { 538 .type = HDA_FIXUP_FUNC, 539 .v.func = ad1981_fixup_hp_eapd, 540 .chained = true, 541 .chain_id = AD1981_FIXUP_AMP_OVERRIDE, 542 }, 543 }; 544 545 static const struct snd_pci_quirk ad1981_fixup_tbl[] = { 546 SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), 547 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD), 548 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), 549 /* HP nx6320 (reversed SSID, H/W bug) */ 550 SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD), 551 {} 552 }; 553 554 static int patch_ad1981(struct hda_codec *codec) 555 { 556 struct ad198x_spec *spec; 557 int err; 558 559 err = alloc_ad_spec(codec); 560 if (err < 0) 561 return -ENOMEM; 562 spec = codec->spec; 563 564 spec->gen.mixer_nid = 0x0e; 565 spec->gen.beep_nid = 0x10; 566 set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); 567 568 snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); 569 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 570 571 err = ad198x_parse_auto_config(codec, false); 572 if (err < 0) 573 goto error; 574 err = ad1983_add_spdif_mux_ctl(codec); 575 if (err < 0) 576 goto error; 577 578 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 579 580 return 0; 581 582 error: 583 snd_hda_gen_free(codec); 584 return err; 585 } 586 587 588 /* 589 * AD1988 590 * 591 * Output pins and routes 592 * 593 * Pin Mix Sel DAC (*) 594 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06 595 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06 596 * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a 597 * port-D 0x12 (mute/hp) <- 0x29 <- 04 598 * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a 599 * port-F 0x16 (mute) <- 0x2a <- 06 600 * port-G 0x24 (mute) <- 0x27 <- 05 601 * port-H 0x25 (mute) <- 0x28 <- 0a 602 * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06 603 * 604 * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah 605 * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug. 606 * 607 * Input pins and routes 608 * 609 * pin boost mix input # / adc input # 610 * port-A 0x11 -> 0x38 -> mix 2, ADC 0 611 * port-B 0x14 -> 0x39 -> mix 0, ADC 1 612 * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2 613 * port-D 0x12 -> 0x3d -> mix 3, ADC 8 614 * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4 615 * port-F 0x16 -> 0x3b -> mix 5, ADC 3 616 * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6 617 * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7 618 * 619 * 620 * DAC assignment 621 * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03 622 * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03 623 * 624 * Inputs of Analog Mix (0x20) 625 * 0:Port-B (front mic) 626 * 1:Port-C/G/H (line-in) 627 * 2:Port-A 628 * 3:Port-D (line-in/2) 629 * 4:Port-E/G/H (mic-in) 630 * 5:Port-F (mic2-in) 631 * 6:CD 632 * 7:Beep 633 * 634 * ADC selection 635 * 0:Port-A 636 * 1:Port-B (front mic-in) 637 * 2:Port-C (line-in) 638 * 3:Port-F (mic2-in) 639 * 4:Port-E (mic-in) 640 * 5:CD 641 * 6:Port-G 642 * 7:Port-H 643 * 8:Port-D (line-in/2) 644 * 9:Mix 645 * 646 * Proposed pin assignments by the datasheet 647 * 648 * 6-stack 649 * Port-A front headphone 650 * B front mic-in 651 * C rear line-in 652 * D rear front-out 653 * E rear mic-in 654 * F rear surround 655 * G rear CLFE 656 * H rear side 657 * 658 * 3-stack 659 * Port-A front headphone 660 * B front mic 661 * C rear line-in/surround 662 * D rear front-out 663 * E rear mic-in/CLFE 664 * 665 * laptop 666 * Port-A headphone 667 * B mic-in 668 * C docking station 669 * D internal speaker (with EAPD) 670 * E/F quad mic array 671 */ 672 673 #ifdef ENABLE_AD_STATIC_QUIRKS 674 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 675 struct snd_ctl_elem_info *uinfo) 676 { 677 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 678 struct ad198x_spec *spec = codec->spec; 679 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 680 spec->num_channel_mode); 681 } 682 683 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, 684 struct snd_ctl_elem_value *ucontrol) 685 { 686 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 687 struct ad198x_spec *spec = codec->spec; 688 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 689 spec->num_channel_mode, spec->multiout.max_channels); 690 } 691 692 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, 693 struct snd_ctl_elem_value *ucontrol) 694 { 695 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 696 struct ad198x_spec *spec = codec->spec; 697 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 698 spec->num_channel_mode, 699 &spec->multiout.max_channels); 700 if (err >= 0 && spec->need_dac_fix) 701 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 702 return err; 703 } 704 #endif /* ENABLE_AD_STATIC_QUIRKS */ 705 706 static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, 707 struct snd_ctl_elem_info *uinfo) 708 { 709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 710 static const char * const texts[] = { 711 "PCM", "ADC1", "ADC2", "ADC3", 712 }; 713 int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; 714 if (num_conns > 4) 715 num_conns = 4; 716 return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts); 717 } 718 719 static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol, 720 struct snd_ctl_elem_value *ucontrol) 721 { 722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 723 struct ad198x_spec *spec = codec->spec; 724 725 ucontrol->value.enumerated.item[0] = spec->cur_smux; 726 return 0; 727 } 728 729 static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, 730 struct snd_ctl_elem_value *ucontrol) 731 { 732 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 733 struct ad198x_spec *spec = codec->spec; 734 unsigned int val = ucontrol->value.enumerated.item[0]; 735 struct nid_path *path; 736 int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; 737 738 if (val >= num_conns) 739 return -EINVAL; 740 if (spec->cur_smux == val) 741 return 0; 742 743 mutex_lock(&codec->control_mutex); 744 codec->cached_write = 1; 745 path = snd_hda_get_path_from_idx(codec, 746 spec->smux_paths[spec->cur_smux]); 747 if (path) 748 snd_hda_activate_path(codec, path, false, true); 749 path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]); 750 if (path) 751 snd_hda_activate_path(codec, path, true, true); 752 spec->cur_smux = val; 753 codec->cached_write = 0; 754 mutex_unlock(&codec->control_mutex); 755 snd_hda_codec_flush_cache(codec); /* flush the updates */ 756 return 1; 757 } 758 759 static struct snd_kcontrol_new ad1988_auto_smux_mixer = { 760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 761 .name = "IEC958 Playback Source", 762 .info = ad1988_auto_smux_enum_info, 763 .get = ad1988_auto_smux_enum_get, 764 .put = ad1988_auto_smux_enum_put, 765 }; 766 767 static int ad1988_auto_init(struct hda_codec *codec) 768 { 769 struct ad198x_spec *spec = codec->spec; 770 int i, err; 771 772 err = snd_hda_gen_init(codec); 773 if (err < 0) 774 return err; 775 if (!spec->gen.autocfg.dig_outs) 776 return 0; 777 778 for (i = 0; i < 4; i++) { 779 struct nid_path *path; 780 path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]); 781 if (path) 782 snd_hda_activate_path(codec, path, path->active, false); 783 } 784 785 return 0; 786 } 787 788 static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec) 789 { 790 struct ad198x_spec *spec = codec->spec; 791 int i, num_conns; 792 /* we create four static faked paths, since AD codecs have odd 793 * widget connections regarding the SPDIF out source 794 */ 795 static struct nid_path fake_paths[4] = { 796 { 797 .depth = 3, 798 .path = { 0x02, 0x1d, 0x1b }, 799 .idx = { 0, 0, 0 }, 800 .multi = { 0, 0, 0 }, 801 }, 802 { 803 .depth = 4, 804 .path = { 0x08, 0x0b, 0x1d, 0x1b }, 805 .idx = { 0, 0, 1, 0 }, 806 .multi = { 0, 1, 0, 0 }, 807 }, 808 { 809 .depth = 4, 810 .path = { 0x09, 0x0b, 0x1d, 0x1b }, 811 .idx = { 0, 1, 1, 0 }, 812 .multi = { 0, 1, 0, 0 }, 813 }, 814 { 815 .depth = 4, 816 .path = { 0x0f, 0x0b, 0x1d, 0x1b }, 817 .idx = { 0, 2, 1, 0 }, 818 .multi = { 0, 1, 0, 0 }, 819 }, 820 }; 821 822 /* SPDIF source mux appears to be present only on AD1988A */ 823 if (!spec->gen.autocfg.dig_outs || 824 get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX) 825 return 0; 826 827 num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; 828 if (num_conns != 3 && num_conns != 4) 829 return 0; 830 831 for (i = 0; i < num_conns; i++) { 832 struct nid_path *path = snd_array_new(&spec->gen.paths); 833 if (!path) 834 return -ENOMEM; 835 *path = fake_paths[i]; 836 if (!i) 837 path->active = 1; 838 spec->smux_paths[i] = snd_hda_get_path_idx(codec, path); 839 } 840 841 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer)) 842 return -ENOMEM; 843 844 codec->patch_ops.init = ad1988_auto_init; 845 846 return 0; 847 } 848 849 /* 850 */ 851 852 enum { 853 AD1988_FIXUP_6STACK_DIG, 854 }; 855 856 static const struct hda_fixup ad1988_fixups[] = { 857 [AD1988_FIXUP_6STACK_DIG] = { 858 .type = HDA_FIXUP_PINS, 859 .v.pins = (const struct hda_pintbl[]) { 860 { 0x11, 0x02214130 }, /* front-hp */ 861 { 0x12, 0x01014010 }, /* line-out */ 862 { 0x14, 0x02a19122 }, /* front-mic */ 863 { 0x15, 0x01813021 }, /* line-in */ 864 { 0x16, 0x01011012 }, /* line-out */ 865 { 0x17, 0x01a19020 }, /* mic */ 866 { 0x1b, 0x0145f1f0 }, /* SPDIF */ 867 { 0x24, 0x01016011 }, /* line-out */ 868 { 0x25, 0x01012013 }, /* line-out */ 869 { } 870 } 871 }, 872 }; 873 874 static const struct hda_model_fixup ad1988_fixup_models[] = { 875 { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" }, 876 {} 877 }; 878 879 static int patch_ad1988(struct hda_codec *codec) 880 { 881 struct ad198x_spec *spec; 882 int err; 883 884 err = alloc_ad_spec(codec); 885 if (err < 0) 886 return err; 887 spec = codec->spec; 888 889 spec->gen.mixer_nid = 0x20; 890 spec->gen.mixer_merge_nid = 0x21; 891 spec->gen.beep_nid = 0x10; 892 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 893 894 snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups); 895 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 896 897 err = ad198x_parse_auto_config(codec, true); 898 if (err < 0) 899 goto error; 900 err = ad1988_add_spdif_mux_ctl(codec); 901 if (err < 0) 902 goto error; 903 904 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 905 906 return 0; 907 908 error: 909 snd_hda_gen_free(codec); 910 return err; 911 } 912 913 914 /* 915 * AD1884 / AD1984 916 * 917 * port-B - front line/mic-in 918 * port-E - aux in/out 919 * port-F - aux in/out 920 * port-C - rear line/mic-in 921 * port-D - rear line/hp-out 922 * port-A - front line/hp-out 923 * 924 * AD1984 = AD1884 + two digital mic-ins 925 * 926 * AD1883 / AD1884A / AD1984A / AD1984B 927 * 928 * port-B (0x14) - front mic-in 929 * port-E (0x1c) - rear mic-in 930 * port-F (0x16) - CD / ext out 931 * port-C (0x15) - rear line-in 932 * port-D (0x12) - rear line-out 933 * port-A (0x11) - front hp-out 934 * 935 * AD1984A = AD1884A + digital-mic 936 * AD1883 = equivalent with AD1984A 937 * AD1984B = AD1984A + extra SPDIF-out 938 */ 939 940 /* set the upper-limit for mixer amp to 0dB for avoiding the possible 941 * damage by overloading 942 */ 943 static void ad1884_fixup_amp_override(struct hda_codec *codec, 944 const struct hda_fixup *fix, int action) 945 { 946 if (action == HDA_FIXUP_ACT_PRE_PROBE) 947 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 948 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 949 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 950 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 951 (1 << AC_AMPCAP_MUTE_SHIFT)); 952 } 953 954 /* toggle GPIO1 according to the mute state */ 955 static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled) 956 { 957 struct hda_codec *codec = private_data; 958 struct ad198x_spec *spec = codec->spec; 959 960 if (spec->eapd_nid) 961 ad_vmaster_eapd_hook(private_data, enabled); 962 snd_hda_codec_update_cache(codec, 0x01, 0, 963 AC_VERB_SET_GPIO_DATA, 964 enabled ? 0x00 : 0x02); 965 } 966 967 static void ad1884_fixup_hp_eapd(struct hda_codec *codec, 968 const struct hda_fixup *fix, int action) 969 { 970 struct ad198x_spec *spec = codec->spec; 971 static const struct hda_verb gpio_init_verbs[] = { 972 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 973 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 974 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 975 {}, 976 }; 977 978 switch (action) { 979 case HDA_FIXUP_ACT_PRE_PROBE: 980 spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook; 981 spec->gen.own_eapd_ctl = 1; 982 snd_hda_sequence_write_cache(codec, gpio_init_verbs); 983 break; 984 case HDA_FIXUP_ACT_PROBE: 985 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 986 spec->eapd_nid = spec->gen.autocfg.line_out_pins[0]; 987 else 988 spec->eapd_nid = spec->gen.autocfg.speaker_pins[0]; 989 break; 990 } 991 } 992 993 static void ad1884_fixup_thinkpad(struct hda_codec *codec, 994 const struct hda_fixup *fix, int action) 995 { 996 struct ad198x_spec *spec = codec->spec; 997 998 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 999 spec->gen.keep_eapd_on = 1; 1000 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 1001 spec->eapd_nid = 0x12; 1002 } 1003 } 1004 1005 /* set magic COEFs for dmic */ 1006 static const struct hda_verb ad1884_dmic_init_verbs[] = { 1007 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, 1008 {0x01, AC_VERB_SET_PROC_COEF, 0x08}, 1009 {} 1010 }; 1011 1012 enum { 1013 AD1884_FIXUP_AMP_OVERRIDE, 1014 AD1884_FIXUP_HP_EAPD, 1015 AD1884_FIXUP_DMIC_COEF, 1016 AD1884_FIXUP_THINKPAD, 1017 AD1884_FIXUP_HP_TOUCHSMART, 1018 }; 1019 1020 static const struct hda_fixup ad1884_fixups[] = { 1021 [AD1884_FIXUP_AMP_OVERRIDE] = { 1022 .type = HDA_FIXUP_FUNC, 1023 .v.func = ad1884_fixup_amp_override, 1024 }, 1025 [AD1884_FIXUP_HP_EAPD] = { 1026 .type = HDA_FIXUP_FUNC, 1027 .v.func = ad1884_fixup_hp_eapd, 1028 .chained = true, 1029 .chain_id = AD1884_FIXUP_AMP_OVERRIDE, 1030 }, 1031 [AD1884_FIXUP_DMIC_COEF] = { 1032 .type = HDA_FIXUP_VERBS, 1033 .v.verbs = ad1884_dmic_init_verbs, 1034 }, 1035 [AD1884_FIXUP_THINKPAD] = { 1036 .type = HDA_FIXUP_FUNC, 1037 .v.func = ad1884_fixup_thinkpad, 1038 .chained = true, 1039 .chain_id = AD1884_FIXUP_DMIC_COEF, 1040 }, 1041 [AD1884_FIXUP_HP_TOUCHSMART] = { 1042 .type = HDA_FIXUP_VERBS, 1043 .v.verbs = ad1884_dmic_init_verbs, 1044 .chained = true, 1045 .chain_id = AD1884_FIXUP_HP_EAPD, 1046 }, 1047 }; 1048 1049 static const struct snd_pci_quirk ad1884_fixup_tbl[] = { 1050 SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART), 1051 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), 1052 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_THINKPAD), 1053 {} 1054 }; 1055 1056 1057 static int patch_ad1884(struct hda_codec *codec) 1058 { 1059 struct ad198x_spec *spec; 1060 int err; 1061 1062 err = alloc_ad_spec(codec); 1063 if (err < 0) 1064 return err; 1065 spec = codec->spec; 1066 1067 spec->gen.mixer_nid = 0x20; 1068 spec->gen.beep_nid = 0x10; 1069 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 1070 1071 snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); 1072 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1073 1074 err = ad198x_parse_auto_config(codec, true); 1075 if (err < 0) 1076 goto error; 1077 err = ad1983_add_spdif_mux_ctl(codec); 1078 if (err < 0) 1079 goto error; 1080 1081 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 1082 1083 return 0; 1084 1085 error: 1086 snd_hda_gen_free(codec); 1087 return err; 1088 } 1089 1090 /* 1091 * AD1882 / AD1882A 1092 * 1093 * port-A - front hp-out 1094 * port-B - front mic-in 1095 * port-C - rear line-in, shared surr-out (3stack) 1096 * port-D - rear line-out 1097 * port-E - rear mic-in, shared clfe-out (3stack) 1098 * port-F - rear surr-out (6stack) 1099 * port-G - rear clfe-out (6stack) 1100 */ 1101 1102 static int patch_ad1882(struct hda_codec *codec) 1103 { 1104 struct ad198x_spec *spec; 1105 int err; 1106 1107 err = alloc_ad_spec(codec); 1108 if (err < 0) 1109 return err; 1110 spec = codec->spec; 1111 1112 spec->gen.mixer_nid = 0x20; 1113 spec->gen.mixer_merge_nid = 0x21; 1114 spec->gen.beep_nid = 0x10; 1115 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 1116 err = ad198x_parse_auto_config(codec, true); 1117 if (err < 0) 1118 goto error; 1119 err = ad1988_add_spdif_mux_ctl(codec); 1120 if (err < 0) 1121 goto error; 1122 return 0; 1123 1124 error: 1125 snd_hda_gen_free(codec); 1126 return err; 1127 } 1128 1129 1130 /* 1131 * patch entries 1132 */ 1133 static const struct hda_codec_preset snd_hda_preset_analog[] = { 1134 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 }, 1135 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 1136 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 }, 1137 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, 1138 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 }, 1139 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 }, 1140 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 1141 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 1142 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 }, 1143 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 1144 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 1145 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 1146 { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, 1147 { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, 1148 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, 1149 {} /* terminator */ 1150 }; 1151 1152 MODULE_ALIAS("snd-hda-codec-id:11d4*"); 1153 1154 MODULE_LICENSE("GPL"); 1155 MODULE_DESCRIPTION("Analog Devices HD-audio codec"); 1156 1157 static struct hda_codec_preset_list analog_list = { 1158 .preset = snd_hda_preset_analog, 1159 .owner = THIS_MODULE, 1160 }; 1161 1162 static int __init patch_analog_init(void) 1163 { 1164 return snd_hda_add_codec_preset(&analog_list); 1165 } 1166 1167 static void __exit patch_analog_exit(void) 1168 { 1169 snd_hda_delete_codec_preset(&analog_list); 1170 } 1171 1172 module_init(patch_analog_init) 1173 module_exit(patch_analog_exit) 1174