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