1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // 3 // Realtek ALC662 and compatible codecs 4 // 5 6 #include <linux/init.h> 7 #include <linux/module.h> 8 #include "realtek.h" 9 10 /* 11 * ALC662 support 12 * 13 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 14 * configuration. Each pin widget can choose any input DACs and a mixer. 15 * Each ADC is connected from a mixer of all inputs. This makes possible 16 * 6-channel independent captures. 17 * 18 * In addition, an independent DAC for the multi-playback (not used in this 19 * driver yet). 20 */ 21 22 /* 23 * BIOS auto configuration 24 */ 25 26 static int alc662_parse_auto_config(struct hda_codec *codec) 27 { 28 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 29 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; 30 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 31 const hda_nid_t *ssids; 32 33 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 || 34 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 || 35 codec->core.vendor_id == 0x10ec0671) 36 ssids = alc663_ssids; 37 else 38 ssids = alc662_ssids; 39 return alc_parse_auto_config(codec, alc662_ignore, ssids); 40 } 41 42 static void alc272_fixup_mario(struct hda_codec *codec, 43 const struct hda_fixup *fix, int action) 44 { 45 if (action != HDA_FIXUP_ACT_PRE_PROBE) 46 return; 47 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, 48 (0x3b << AC_AMPCAP_OFFSET_SHIFT) | 49 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | 50 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | 51 (0 << AC_AMPCAP_MUTE_SHIFT))) 52 codec_warn(codec, "failed to override amp caps for NID 0x2\n"); 53 } 54 55 /* avoid D3 for keeping GPIO up */ 56 static unsigned int gpio_led_power_filter(struct hda_codec *codec, 57 hda_nid_t nid, 58 unsigned int power_state) 59 { 60 struct alc_spec *spec = codec->spec; 61 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data) 62 return AC_PWRST_D0; 63 return power_state; 64 } 65 66 static void alc662_fixup_led_gpio1(struct hda_codec *codec, 67 const struct hda_fixup *fix, int action) 68 { 69 struct alc_spec *spec = codec->spec; 70 71 alc_fixup_hp_gpio_led(codec, action, 0x01, 0); 72 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 73 spec->mute_led_polarity = 1; 74 codec->power_filter = gpio_led_power_filter; 75 } 76 } 77 78 static void alc662_usi_automute_hook(struct hda_codec *codec, 79 struct hda_jack_callback *jack) 80 { 81 struct alc_spec *spec = codec->spec; 82 int vref; 83 msleep(200); 84 snd_hda_gen_hp_automute(codec, jack); 85 86 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; 87 msleep(100); 88 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 89 vref); 90 } 91 92 static void alc662_fixup_usi_headset_mic(struct hda_codec *codec, 93 const struct hda_fixup *fix, int action) 94 { 95 struct alc_spec *spec = codec->spec; 96 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 97 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 98 spec->gen.hp_automute_hook = alc662_usi_automute_hook; 99 } 100 } 101 102 static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec, 103 struct hda_jack_callback *cb) 104 { 105 /* surround speakers at 0x1b already get muted automatically when 106 * headphones are plugged in, but we have to mute/unmute the remaining 107 * channels manually: 108 * 0x15 - front left/front right 109 * 0x18 - front center/ LFE 110 */ 111 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) { 112 snd_hda_set_pin_ctl_cache(codec, 0x15, 0); 113 snd_hda_set_pin_ctl_cache(codec, 0x18, 0); 114 } else { 115 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT); 116 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT); 117 } 118 } 119 120 static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec, 121 const struct hda_fixup *fix, int action) 122 { 123 /* Pin 0x1b: shared headphones jack and surround speakers */ 124 if (!is_jack_detectable(codec, 0x1b)) 125 return; 126 127 switch (action) { 128 case HDA_FIXUP_ACT_PRE_PROBE: 129 snd_hda_jack_detect_enable_callback(codec, 0x1b, 130 alc662_aspire_ethos_mute_speakers); 131 /* subwoofer needs an extra GPIO setting to become audible */ 132 alc_setup_gpio(codec, 0x02); 133 break; 134 case HDA_FIXUP_ACT_INIT: 135 /* Make sure to start in a correct state, i.e. if 136 * headphones have been plugged in before powering up the system 137 */ 138 alc662_aspire_ethos_mute_speakers(codec, NULL); 139 break; 140 } 141 } 142 143 static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec, 144 const struct hda_fixup *fix, int action) 145 { 146 struct alc_spec *spec = codec->spec; 147 148 static const struct hda_pintbl pincfgs[] = { 149 { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */ 150 { 0x1b, 0x0181304f }, 151 { } 152 }; 153 154 switch (action) { 155 case HDA_FIXUP_ACT_PRE_PROBE: 156 spec->gen.mixer_nid = 0; 157 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 158 snd_hda_apply_pincfgs(codec, pincfgs); 159 break; 160 case HDA_FIXUP_ACT_INIT: 161 alc_write_coef_idx(codec, 0x19, 0xa054); 162 break; 163 } 164 } 165 166 static void alc897_hp_automute_hook(struct hda_codec *codec, 167 struct hda_jack_callback *jack) 168 { 169 struct alc_spec *spec = codec->spec; 170 int vref; 171 172 snd_hda_gen_hp_automute(codec, jack); 173 vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP; 174 snd_hda_set_pin_ctl(codec, 0x1b, vref); 175 } 176 177 static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec, 178 const struct hda_fixup *fix, int action) 179 { 180 struct alc_spec *spec = codec->spec; 181 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 182 spec->gen.hp_automute_hook = alc897_hp_automute_hook; 183 spec->no_shutup_pins = 1; 184 } 185 if (action == HDA_FIXUP_ACT_PROBE) { 186 snd_hda_set_pin_ctl_cache(codec, 0x1a, PIN_IN | AC_PINCTL_VREF_100); 187 } 188 } 189 190 static void alc897_fixup_lenovo_headset_mode(struct hda_codec *codec, 191 const struct hda_fixup *fix, int action) 192 { 193 struct alc_spec *spec = codec->spec; 194 195 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 196 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 197 spec->gen.hp_automute_hook = alc897_hp_automute_hook; 198 } 199 } 200 201 static const struct coef_fw alc668_coefs[] = { 202 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0), 203 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80), 204 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0), 205 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f), 206 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001), 207 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940), 208 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0), 209 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418), 210 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468), 211 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418), 212 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00), 213 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000), 214 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0), 215 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480), 216 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0), 217 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040), 218 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697), 219 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab), 220 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02), 221 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6), 222 {} 223 }; 224 225 static void alc668_restore_default_value(struct hda_codec *codec) 226 { 227 alc_process_coef_fw(codec, alc668_coefs); 228 } 229 230 static void alc_fixup_headset_mode_alc662(struct hda_codec *codec, 231 const struct hda_fixup *fix, int action) 232 { 233 struct alc_spec *spec = codec->spec; 234 235 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 236 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 237 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */ 238 239 /* Disable boost for mic-in permanently. (This code is only called 240 from quirks that guarantee that the headphone is at NID 0x1b.) */ 241 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000); 242 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP); 243 } else 244 alc_fixup_headset_mode(codec, fix, action); 245 } 246 247 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, 248 const struct hda_fixup *fix, int action) 249 { 250 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 251 alc_write_coef_idx(codec, 0xc4, 0x8000); 252 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0); 253 snd_hda_set_pin_ctl_cache(codec, 0x18, 0); 254 } 255 alc_fixup_headset_mode(codec, fix, action); 256 } 257 258 enum { 259 ALC662_FIXUP_ASPIRE, 260 ALC662_FIXUP_LED_GPIO1, 261 ALC662_FIXUP_IDEAPAD, 262 ALC272_FIXUP_MARIO, 263 ALC662_FIXUP_CZC_ET26, 264 ALC662_FIXUP_CZC_P10T, 265 ALC662_FIXUP_SKU_IGNORE, 266 ALC662_FIXUP_HP_RP5800, 267 ALC662_FIXUP_ASUS_MODE1, 268 ALC662_FIXUP_ASUS_MODE2, 269 ALC662_FIXUP_ASUS_MODE3, 270 ALC662_FIXUP_ASUS_MODE4, 271 ALC662_FIXUP_ASUS_MODE5, 272 ALC662_FIXUP_ASUS_MODE6, 273 ALC662_FIXUP_ASUS_MODE7, 274 ALC662_FIXUP_ASUS_MODE8, 275 ALC662_FIXUP_NO_JACK_DETECT, 276 ALC662_FIXUP_ZOTAC_Z68, 277 ALC662_FIXUP_INV_DMIC, 278 ALC662_FIXUP_DELL_MIC_NO_PRESENCE, 279 ALC668_FIXUP_DELL_MIC_NO_PRESENCE, 280 ALC662_FIXUP_HEADSET_MODE, 281 ALC668_FIXUP_HEADSET_MODE, 282 ALC662_FIXUP_BASS_MODE4_CHMAP, 283 ALC662_FIXUP_BASS_16, 284 ALC662_FIXUP_BASS_1A, 285 ALC662_FIXUP_BASS_CHMAP, 286 ALC668_FIXUP_AUTO_MUTE, 287 ALC668_FIXUP_DELL_DISABLE_AAMIX, 288 ALC668_FIXUP_DELL_XPS13, 289 ALC662_FIXUP_ASUS_Nx50, 290 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE, 291 ALC668_FIXUP_ASUS_Nx51, 292 ALC668_FIXUP_MIC_COEF, 293 ALC668_FIXUP_ASUS_G751, 294 ALC891_FIXUP_HEADSET_MODE, 295 ALC891_FIXUP_DELL_MIC_NO_PRESENCE, 296 ALC662_FIXUP_ACER_VERITON, 297 ALC892_FIXUP_ASROCK_MOBO, 298 ALC662_FIXUP_USI_FUNC, 299 ALC662_FIXUP_USI_HEADSET_MODE, 300 ALC662_FIXUP_LENOVO_MULTI_CODECS, 301 ALC669_FIXUP_ACER_ASPIRE_ETHOS, 302 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET, 303 ALC671_FIXUP_HP_HEADSET_MIC2, 304 ALC662_FIXUP_ACER_X2660G_HEADSET_MODE, 305 ALC662_FIXUP_ACER_NITRO_HEADSET_MODE, 306 ALC668_FIXUP_ASUS_NO_HEADSET_MIC, 307 ALC668_FIXUP_HEADSET_MIC, 308 ALC668_FIXUP_MIC_DET_COEF, 309 ALC897_FIXUP_LENOVO_HEADSET_MIC, 310 ALC897_FIXUP_HEADSET_MIC_PIN, 311 ALC897_FIXUP_HP_HSMIC_VERB, 312 ALC897_FIXUP_LENOVO_HEADSET_MODE, 313 ALC897_FIXUP_HEADSET_MIC_PIN2, 314 ALC897_FIXUP_UNIS_H3C_X500S, 315 ALC897_FIXUP_HEADSET_MIC_PIN3, 316 }; 317 318 static const struct hda_fixup alc662_fixups[] = { 319 [ALC662_FIXUP_ASPIRE] = { 320 .type = HDA_FIXUP_PINS, 321 .v.pins = (const struct hda_pintbl[]) { 322 { 0x15, 0x99130112 }, /* subwoofer */ 323 { } 324 } 325 }, 326 [ALC662_FIXUP_LED_GPIO1] = { 327 .type = HDA_FIXUP_FUNC, 328 .v.func = alc662_fixup_led_gpio1, 329 }, 330 [ALC662_FIXUP_IDEAPAD] = { 331 .type = HDA_FIXUP_PINS, 332 .v.pins = (const struct hda_pintbl[]) { 333 { 0x17, 0x99130112 }, /* subwoofer */ 334 { } 335 }, 336 .chained = true, 337 .chain_id = ALC662_FIXUP_LED_GPIO1, 338 }, 339 [ALC272_FIXUP_MARIO] = { 340 .type = HDA_FIXUP_FUNC, 341 .v.func = alc272_fixup_mario, 342 }, 343 [ALC662_FIXUP_CZC_ET26] = { 344 .type = HDA_FIXUP_PINS, 345 .v.pins = (const struct hda_pintbl[]) { 346 {0x12, 0x403cc000}, 347 {0x14, 0x90170110}, /* speaker */ 348 {0x15, 0x411111f0}, 349 {0x16, 0x411111f0}, 350 {0x18, 0x01a19030}, /* mic */ 351 {0x19, 0x90a7013f}, /* int-mic */ 352 {0x1a, 0x01014020}, 353 {0x1b, 0x0121401f}, 354 {0x1c, 0x411111f0}, 355 {0x1d, 0x411111f0}, 356 {0x1e, 0x40478e35}, 357 {} 358 }, 359 .chained = true, 360 .chain_id = ALC662_FIXUP_SKU_IGNORE 361 }, 362 [ALC662_FIXUP_CZC_P10T] = { 363 .type = HDA_FIXUP_VERBS, 364 .v.verbs = (const struct hda_verb[]) { 365 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 366 {} 367 } 368 }, 369 [ALC662_FIXUP_SKU_IGNORE] = { 370 .type = HDA_FIXUP_FUNC, 371 .v.func = alc_fixup_sku_ignore, 372 }, 373 [ALC662_FIXUP_HP_RP5800] = { 374 .type = HDA_FIXUP_PINS, 375 .v.pins = (const struct hda_pintbl[]) { 376 { 0x14, 0x0221201f }, /* HP out */ 377 { } 378 }, 379 .chained = true, 380 .chain_id = ALC662_FIXUP_SKU_IGNORE 381 }, 382 [ALC662_FIXUP_ASUS_MODE1] = { 383 .type = HDA_FIXUP_PINS, 384 .v.pins = (const struct hda_pintbl[]) { 385 { 0x14, 0x99130110 }, /* speaker */ 386 { 0x18, 0x01a19c20 }, /* mic */ 387 { 0x19, 0x99a3092f }, /* int-mic */ 388 { 0x21, 0x0121401f }, /* HP out */ 389 { } 390 }, 391 .chained = true, 392 .chain_id = ALC662_FIXUP_SKU_IGNORE 393 }, 394 [ALC662_FIXUP_ASUS_MODE2] = { 395 .type = HDA_FIXUP_PINS, 396 .v.pins = (const struct hda_pintbl[]) { 397 { 0x14, 0x99130110 }, /* speaker */ 398 { 0x18, 0x01a19820 }, /* mic */ 399 { 0x19, 0x99a3092f }, /* int-mic */ 400 { 0x1b, 0x0121401f }, /* HP out */ 401 { } 402 }, 403 .chained = true, 404 .chain_id = ALC662_FIXUP_SKU_IGNORE 405 }, 406 [ALC662_FIXUP_ASUS_MODE3] = { 407 .type = HDA_FIXUP_PINS, 408 .v.pins = (const struct hda_pintbl[]) { 409 { 0x14, 0x99130110 }, /* speaker */ 410 { 0x15, 0x0121441f }, /* HP */ 411 { 0x18, 0x01a19840 }, /* mic */ 412 { 0x19, 0x99a3094f }, /* int-mic */ 413 { 0x21, 0x01211420 }, /* HP2 */ 414 { } 415 }, 416 .chained = true, 417 .chain_id = ALC662_FIXUP_SKU_IGNORE 418 }, 419 [ALC662_FIXUP_ASUS_MODE4] = { 420 .type = HDA_FIXUP_PINS, 421 .v.pins = (const struct hda_pintbl[]) { 422 { 0x14, 0x99130110 }, /* speaker */ 423 { 0x16, 0x99130111 }, /* speaker */ 424 { 0x18, 0x01a19840 }, /* mic */ 425 { 0x19, 0x99a3094f }, /* int-mic */ 426 { 0x21, 0x0121441f }, /* HP */ 427 { } 428 }, 429 .chained = true, 430 .chain_id = ALC662_FIXUP_SKU_IGNORE 431 }, 432 [ALC662_FIXUP_ASUS_MODE5] = { 433 .type = HDA_FIXUP_PINS, 434 .v.pins = (const struct hda_pintbl[]) { 435 { 0x14, 0x99130110 }, /* speaker */ 436 { 0x15, 0x0121441f }, /* HP */ 437 { 0x16, 0x99130111 }, /* speaker */ 438 { 0x18, 0x01a19840 }, /* mic */ 439 { 0x19, 0x99a3094f }, /* int-mic */ 440 { } 441 }, 442 .chained = true, 443 .chain_id = ALC662_FIXUP_SKU_IGNORE 444 }, 445 [ALC662_FIXUP_ASUS_MODE6] = { 446 .type = HDA_FIXUP_PINS, 447 .v.pins = (const struct hda_pintbl[]) { 448 { 0x14, 0x99130110 }, /* speaker */ 449 { 0x15, 0x01211420 }, /* HP2 */ 450 { 0x18, 0x01a19840 }, /* mic */ 451 { 0x19, 0x99a3094f }, /* int-mic */ 452 { 0x1b, 0x0121441f }, /* HP */ 453 { } 454 }, 455 .chained = true, 456 .chain_id = ALC662_FIXUP_SKU_IGNORE 457 }, 458 [ALC662_FIXUP_ASUS_MODE7] = { 459 .type = HDA_FIXUP_PINS, 460 .v.pins = (const struct hda_pintbl[]) { 461 { 0x14, 0x99130110 }, /* speaker */ 462 { 0x17, 0x99130111 }, /* speaker */ 463 { 0x18, 0x01a19840 }, /* mic */ 464 { 0x19, 0x99a3094f }, /* int-mic */ 465 { 0x1b, 0x01214020 }, /* HP */ 466 { 0x21, 0x0121401f }, /* HP */ 467 { } 468 }, 469 .chained = true, 470 .chain_id = ALC662_FIXUP_SKU_IGNORE 471 }, 472 [ALC662_FIXUP_ASUS_MODE8] = { 473 .type = HDA_FIXUP_PINS, 474 .v.pins = (const struct hda_pintbl[]) { 475 { 0x14, 0x99130110 }, /* speaker */ 476 { 0x12, 0x99a30970 }, /* int-mic */ 477 { 0x15, 0x01214020 }, /* HP */ 478 { 0x17, 0x99130111 }, /* speaker */ 479 { 0x18, 0x01a19840 }, /* mic */ 480 { 0x21, 0x0121401f }, /* HP */ 481 { } 482 }, 483 .chained = true, 484 .chain_id = ALC662_FIXUP_SKU_IGNORE 485 }, 486 [ALC662_FIXUP_NO_JACK_DETECT] = { 487 .type = HDA_FIXUP_FUNC, 488 .v.func = alc_fixup_no_jack_detect, 489 }, 490 [ALC662_FIXUP_ZOTAC_Z68] = { 491 .type = HDA_FIXUP_PINS, 492 .v.pins = (const struct hda_pintbl[]) { 493 { 0x1b, 0x02214020 }, /* Front HP */ 494 { } 495 } 496 }, 497 [ALC662_FIXUP_INV_DMIC] = { 498 .type = HDA_FIXUP_FUNC, 499 .v.func = alc_fixup_inv_dmic, 500 }, 501 [ALC668_FIXUP_DELL_XPS13] = { 502 .type = HDA_FIXUP_FUNC, 503 .v.func = alc_fixup_dell_xps13, 504 .chained = true, 505 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX 506 }, 507 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = { 508 .type = HDA_FIXUP_FUNC, 509 .v.func = alc_fixup_disable_aamix, 510 .chained = true, 511 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE 512 }, 513 [ALC668_FIXUP_AUTO_MUTE] = { 514 .type = HDA_FIXUP_FUNC, 515 .v.func = alc_fixup_auto_mute_via_amp, 516 .chained = true, 517 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE 518 }, 519 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = { 520 .type = HDA_FIXUP_PINS, 521 .v.pins = (const struct hda_pintbl[]) { 522 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 523 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */ 524 { } 525 }, 526 .chained = true, 527 .chain_id = ALC662_FIXUP_HEADSET_MODE 528 }, 529 [ALC662_FIXUP_HEADSET_MODE] = { 530 .type = HDA_FIXUP_FUNC, 531 .v.func = alc_fixup_headset_mode_alc662, 532 }, 533 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { 534 .type = HDA_FIXUP_PINS, 535 .v.pins = (const struct hda_pintbl[]) { 536 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 537 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 538 { } 539 }, 540 .chained = true, 541 .chain_id = ALC668_FIXUP_HEADSET_MODE 542 }, 543 [ALC668_FIXUP_HEADSET_MODE] = { 544 .type = HDA_FIXUP_FUNC, 545 .v.func = alc_fixup_headset_mode_alc668, 546 }, 547 [ALC662_FIXUP_BASS_MODE4_CHMAP] = { 548 .type = HDA_FIXUP_FUNC, 549 .v.func = alc_fixup_bass_chmap, 550 .chained = true, 551 .chain_id = ALC662_FIXUP_ASUS_MODE4 552 }, 553 [ALC662_FIXUP_BASS_16] = { 554 .type = HDA_FIXUP_PINS, 555 .v.pins = (const struct hda_pintbl[]) { 556 {0x16, 0x80106111}, /* bass speaker */ 557 {} 558 }, 559 .chained = true, 560 .chain_id = ALC662_FIXUP_BASS_CHMAP, 561 }, 562 [ALC662_FIXUP_BASS_1A] = { 563 .type = HDA_FIXUP_PINS, 564 .v.pins = (const struct hda_pintbl[]) { 565 {0x1a, 0x80106111}, /* bass speaker */ 566 {} 567 }, 568 .chained = true, 569 .chain_id = ALC662_FIXUP_BASS_CHMAP, 570 }, 571 [ALC662_FIXUP_BASS_CHMAP] = { 572 .type = HDA_FIXUP_FUNC, 573 .v.func = alc_fixup_bass_chmap, 574 }, 575 [ALC662_FIXUP_ASUS_Nx50] = { 576 .type = HDA_FIXUP_FUNC, 577 .v.func = alc_fixup_auto_mute_via_amp, 578 .chained = true, 579 .chain_id = ALC662_FIXUP_BASS_1A 580 }, 581 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = { 582 .type = HDA_FIXUP_FUNC, 583 .v.func = alc_fixup_headset_mode_alc668, 584 .chain_id = ALC662_FIXUP_BASS_CHMAP 585 }, 586 [ALC668_FIXUP_ASUS_Nx51] = { 587 .type = HDA_FIXUP_PINS, 588 .v.pins = (const struct hda_pintbl[]) { 589 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 590 { 0x1a, 0x90170151 }, /* bass speaker */ 591 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 592 {} 593 }, 594 .chained = true, 595 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE, 596 }, 597 [ALC668_FIXUP_MIC_COEF] = { 598 .type = HDA_FIXUP_VERBS, 599 .v.verbs = (const struct hda_verb[]) { 600 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 }, 601 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 }, 602 {} 603 }, 604 }, 605 [ALC668_FIXUP_ASUS_G751] = { 606 .type = HDA_FIXUP_PINS, 607 .v.pins = (const struct hda_pintbl[]) { 608 { 0x16, 0x0421101f }, /* HP */ 609 {} 610 }, 611 .chained = true, 612 .chain_id = ALC668_FIXUP_MIC_COEF 613 }, 614 [ALC891_FIXUP_HEADSET_MODE] = { 615 .type = HDA_FIXUP_FUNC, 616 .v.func = alc_fixup_headset_mode, 617 }, 618 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = { 619 .type = HDA_FIXUP_PINS, 620 .v.pins = (const struct hda_pintbl[]) { 621 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 622 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 623 { } 624 }, 625 .chained = true, 626 .chain_id = ALC891_FIXUP_HEADSET_MODE 627 }, 628 [ALC662_FIXUP_ACER_VERITON] = { 629 .type = HDA_FIXUP_PINS, 630 .v.pins = (const struct hda_pintbl[]) { 631 { 0x15, 0x50170120 }, /* no internal speaker */ 632 { } 633 } 634 }, 635 [ALC892_FIXUP_ASROCK_MOBO] = { 636 .type = HDA_FIXUP_PINS, 637 .v.pins = (const struct hda_pintbl[]) { 638 { 0x15, 0x40f000f0 }, /* disabled */ 639 { 0x16, 0x40f000f0 }, /* disabled */ 640 { } 641 } 642 }, 643 [ALC662_FIXUP_USI_FUNC] = { 644 .type = HDA_FIXUP_FUNC, 645 .v.func = alc662_fixup_usi_headset_mic, 646 }, 647 [ALC662_FIXUP_USI_HEADSET_MODE] = { 648 .type = HDA_FIXUP_PINS, 649 .v.pins = (const struct hda_pintbl[]) { 650 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */ 651 { 0x18, 0x01a1903d }, 652 { } 653 }, 654 .chained = true, 655 .chain_id = ALC662_FIXUP_USI_FUNC 656 }, 657 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = { 658 .type = HDA_FIXUP_FUNC, 659 .v.func = alc233_alc662_fixup_lenovo_dual_codecs, 660 }, 661 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = { 662 .type = HDA_FIXUP_FUNC, 663 .v.func = alc662_fixup_aspire_ethos_hp, 664 }, 665 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = { 666 .type = HDA_FIXUP_PINS, 667 .v.pins = (const struct hda_pintbl[]) { 668 { 0x15, 0x92130110 }, /* front speakers */ 669 { 0x18, 0x99130111 }, /* center/subwoofer */ 670 { 0x1b, 0x11130012 }, /* surround plus jack for HP */ 671 { } 672 }, 673 .chained = true, 674 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET 675 }, 676 [ALC671_FIXUP_HP_HEADSET_MIC2] = { 677 .type = HDA_FIXUP_FUNC, 678 .v.func = alc671_fixup_hp_headset_mic2, 679 }, 680 [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = { 681 .type = HDA_FIXUP_PINS, 682 .v.pins = (const struct hda_pintbl[]) { 683 { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */ 684 { } 685 }, 686 .chained = true, 687 .chain_id = ALC662_FIXUP_USI_FUNC 688 }, 689 [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = { 690 .type = HDA_FIXUP_PINS, 691 .v.pins = (const struct hda_pintbl[]) { 692 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */ 693 { 0x1b, 0x0221144f }, 694 { } 695 }, 696 .chained = true, 697 .chain_id = ALC662_FIXUP_USI_FUNC 698 }, 699 [ALC668_FIXUP_ASUS_NO_HEADSET_MIC] = { 700 .type = HDA_FIXUP_PINS, 701 .v.pins = (const struct hda_pintbl[]) { 702 { 0x1b, 0x04a1112c }, 703 { } 704 }, 705 .chained = true, 706 .chain_id = ALC668_FIXUP_HEADSET_MIC 707 }, 708 [ALC668_FIXUP_HEADSET_MIC] = { 709 .type = HDA_FIXUP_FUNC, 710 .v.func = alc_fixup_headset_mic, 711 .chained = true, 712 .chain_id = ALC668_FIXUP_MIC_DET_COEF 713 }, 714 [ALC668_FIXUP_MIC_DET_COEF] = { 715 .type = HDA_FIXUP_VERBS, 716 .v.verbs = (const struct hda_verb[]) { 717 { 0x20, AC_VERB_SET_COEF_INDEX, 0x15 }, 718 { 0x20, AC_VERB_SET_PROC_COEF, 0x0d60 }, 719 {} 720 }, 721 }, 722 [ALC897_FIXUP_LENOVO_HEADSET_MIC] = { 723 .type = HDA_FIXUP_FUNC, 724 .v.func = alc897_fixup_lenovo_headset_mic, 725 }, 726 [ALC897_FIXUP_HEADSET_MIC_PIN] = { 727 .type = HDA_FIXUP_PINS, 728 .v.pins = (const struct hda_pintbl[]) { 729 { 0x1a, 0x03a11050 }, 730 { } 731 }, 732 .chained = true, 733 .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC 734 }, 735 [ALC897_FIXUP_HP_HSMIC_VERB] = { 736 .type = HDA_FIXUP_PINS, 737 .v.pins = (const struct hda_pintbl[]) { 738 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 739 { } 740 }, 741 }, 742 [ALC897_FIXUP_LENOVO_HEADSET_MODE] = { 743 .type = HDA_FIXUP_FUNC, 744 .v.func = alc897_fixup_lenovo_headset_mode, 745 }, 746 [ALC897_FIXUP_HEADSET_MIC_PIN2] = { 747 .type = HDA_FIXUP_PINS, 748 .v.pins = (const struct hda_pintbl[]) { 749 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */ 750 { } 751 }, 752 .chained = true, 753 .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE 754 }, 755 [ALC897_FIXUP_UNIS_H3C_X500S] = { 756 .type = HDA_FIXUP_VERBS, 757 .v.verbs = (const struct hda_verb[]) { 758 { 0x14, AC_VERB_SET_EAPD_BTLENABLE, 0 }, 759 {} 760 }, 761 }, 762 [ALC897_FIXUP_HEADSET_MIC_PIN3] = { 763 .type = HDA_FIXUP_PINS, 764 .v.pins = (const struct hda_pintbl[]) { 765 { 0x19, 0x03a11050 }, /* use as headset mic */ 766 { } 767 }, 768 }, 769 }; 770 771 static const struct hda_quirk alc662_fixup_tbl[] = { 772 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), 773 SND_PCI_QUIRK(0x1019, 0x9859, "JP-IK LEAP W502", ALC897_FIXUP_HEADSET_MIC_PIN3), 774 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), 775 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC), 776 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 777 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 778 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), 779 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), 780 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 781 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS), 782 SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE), 783 SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE), 784 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 785 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 786 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13), 787 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13), 788 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13), 789 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 790 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 791 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 792 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 793 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 794 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 795 SND_PCI_QUIRK(0x103c, 0x870c, "HP", ALC897_FIXUP_HP_HSMIC_VERB), 796 SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB), 797 SND_PCI_QUIRK(0x103c, 0x872b, "HP", ALC897_FIXUP_HP_HSMIC_VERB), 798 SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2), 799 SND_PCI_QUIRK(0x103c, 0x8768, "HP Slim Desktop S01", ALC671_FIXUP_HP_HEADSET_MIC2), 800 SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2), 801 SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2), 802 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE), 803 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50), 804 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50), 805 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751), 806 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A), 807 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), 808 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), 809 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51), 810 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51), 811 SND_PCI_QUIRK(0x1043, 0x185d, "ASUS G551JW", ALC668_FIXUP_ASUS_NO_HEADSET_MIC), 812 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8), 813 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), 814 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), 815 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), 816 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 817 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 818 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), 819 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), 820 SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN), 821 SND_PCI_QUIRK(0x17aa, 0x1064, "Lenovo P3 Tower", ALC897_FIXUP_HEADSET_MIC_PIN), 822 SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN), 823 SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN), 824 SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN), 825 SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN), 826 SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), 827 SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), 828 SND_PCI_QUIRK(0x17aa, 0x3364, "Lenovo ThinkCentre M90 Gen5", ALC897_FIXUP_HEADSET_MIC_PIN), 829 SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2), 830 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 831 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 832 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO), 833 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), 834 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON), 835 SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26), 836 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), 837 SND_PCI_QUIRK(0x1c6c, 0x1239, "Compaq N14JP6-V2", ALC897_FIXUP_HP_HSMIC_VERB), 838 839 #if 0 840 /* Below is a quirk table taken from the old code. 841 * Basically the device should work as is without the fixup table. 842 * If BIOS doesn't give a proper info, enable the corresponding 843 * fixup entry. 844 */ 845 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), 846 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), 847 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), 848 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), 849 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 850 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 851 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 852 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), 853 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), 854 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 855 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), 856 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), 857 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), 858 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), 859 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), 860 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 861 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), 862 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), 863 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 864 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 865 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 866 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 867 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), 868 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), 869 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), 870 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 871 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), 872 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 873 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 874 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), 875 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 876 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 877 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), 878 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), 879 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), 880 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), 881 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), 882 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), 883 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), 884 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 885 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), 886 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), 887 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 888 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), 889 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), 890 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), 891 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), 892 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), 893 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 894 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), 895 #endif 896 {} 897 }; 898 899 static const struct hda_model_fixup alc662_fixup_models[] = { 900 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"}, 901 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"}, 902 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 903 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"}, 904 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, 905 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, 906 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, 907 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, 908 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, 909 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, 910 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, 911 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, 912 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"}, 913 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, 914 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"}, 915 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, 916 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"}, 917 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"}, 918 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"}, 919 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"}, 920 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"}, 921 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"}, 922 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"}, 923 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"}, 924 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"}, 925 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"}, 926 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"}, 927 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"}, 928 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"}, 929 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"}, 930 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"}, 931 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"}, 932 {.id = ALC897_FIXUP_UNIS_H3C_X500S, .name = "unis-h3c-x500s"}, 933 {} 934 }; 935 936 static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { 937 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE, 938 {0x17, 0x02211010}, 939 {0x18, 0x01a19030}, 940 {0x1a, 0x01813040}, 941 {0x21, 0x01014020}), 942 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE, 943 {0x16, 0x01813030}, 944 {0x17, 0x02211010}, 945 {0x18, 0x01a19040}, 946 {0x21, 0x01014020}), 947 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE, 948 {0x14, 0x01014010}, 949 {0x18, 0x01a19020}, 950 {0x1a, 0x0181302f}, 951 {0x1b, 0x0221401f}), 952 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 953 {0x12, 0x99a30130}, 954 {0x14, 0x90170110}, 955 {0x15, 0x0321101f}, 956 {0x16, 0x03011020}), 957 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 958 {0x12, 0x99a30140}, 959 {0x14, 0x90170110}, 960 {0x15, 0x0321101f}, 961 {0x16, 0x03011020}), 962 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 963 {0x12, 0x99a30150}, 964 {0x14, 0x90170110}, 965 {0x15, 0x0321101f}, 966 {0x16, 0x03011020}), 967 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 968 {0x14, 0x90170110}, 969 {0x15, 0x0321101f}, 970 {0x16, 0x03011020}), 971 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE, 972 {0x12, 0x90a60130}, 973 {0x14, 0x90170110}, 974 {0x15, 0x0321101f}), 975 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, 976 {0x14, 0x01014010}, 977 {0x17, 0x90170150}, 978 {0x19, 0x02a11060}, 979 {0x1b, 0x01813030}, 980 {0x21, 0x02211020}), 981 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, 982 {0x14, 0x01014010}, 983 {0x18, 0x01a19040}, 984 {0x1b, 0x01813030}, 985 {0x21, 0x02211020}), 986 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, 987 {0x14, 0x01014020}, 988 {0x17, 0x90170110}, 989 {0x18, 0x01a19050}, 990 {0x1b, 0x01813040}, 991 {0x21, 0x02211030}), 992 {} 993 }; 994 995 /* 996 */ 997 static int alc662_probe(struct hda_codec *codec, const struct hda_device_id *id) 998 { 999 struct alc_spec *spec; 1000 int err; 1001 1002 err = alc_alloc_spec(codec, 0x0b); 1003 if (err < 0) 1004 return err; 1005 1006 spec = codec->spec; 1007 1008 spec->shutup = alc_eapd_shutup; 1009 1010 /* handle multiple HPs as is */ 1011 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 1012 1013 alc_fix_pll_init(codec, 0x20, 0x04, 15); 1014 1015 switch (codec->core.vendor_id) { 1016 case 0x10ec0668: 1017 spec->init_hook = alc668_restore_default_value; 1018 break; 1019 } 1020 1021 alc_pre_init(codec); 1022 1023 snd_hda_pick_fixup(codec, alc662_fixup_models, 1024 alc662_fixup_tbl, alc662_fixups); 1025 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true); 1026 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1027 1028 alc_auto_parse_customize_define(codec); 1029 1030 if (has_cdefine_beep(codec)) 1031 spec->gen.beep_nid = 0x01; 1032 1033 if ((alc_get_coef0(codec) & (1 << 14)) && 1034 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && 1035 spec->cdefine.platform_type == 1) { 1036 err = alc_codec_rename(codec, "ALC272X"); 1037 if (err < 0) 1038 goto error; 1039 } 1040 1041 /* automatic parse from the BIOS config */ 1042 err = alc662_parse_auto_config(codec); 1043 if (err < 0) 1044 goto error; 1045 1046 if (!spec->gen.no_analog && spec->gen.beep_nid) { 1047 switch (codec->core.vendor_id) { 1048 case 0x10ec0662: 1049 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 1050 break; 1051 case 0x10ec0272: 1052 case 0x10ec0663: 1053 case 0x10ec0665: 1054 case 0x10ec0668: 1055 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 1056 break; 1057 case 0x10ec0273: 1058 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 1059 break; 1060 } 1061 if (err < 0) 1062 goto error; 1063 } 1064 1065 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 1066 1067 return 0; 1068 1069 error: 1070 snd_hda_gen_remove(codec); 1071 return err; 1072 } 1073 1074 static const struct hda_codec_ops alc662_codec_ops = { 1075 .probe = alc662_probe, 1076 .remove = snd_hda_gen_remove, 1077 .build_controls = alc_build_controls, 1078 .build_pcms = snd_hda_gen_build_pcms, 1079 .init = alc_init, 1080 .unsol_event = snd_hda_jack_unsol_event, 1081 .resume = alc_resume, 1082 .suspend = alc_suspend, 1083 .check_power_status = snd_hda_gen_check_power_status, 1084 .stream_pm = snd_hda_gen_stream_pm, 1085 }; 1086 1087 /* 1088 * driver entries 1089 */ 1090 static const struct hda_device_id snd_hda_id_alc662[] = { 1091 HDA_CODEC_ID(0x10ec0272, "ALC272"), 1092 HDA_CODEC_ID_REV(0x10ec0662, 0x100101, "ALC662 rev1"), 1093 HDA_CODEC_ID_REV(0x10ec0662, 0x100300, "ALC662 rev3"), 1094 HDA_CODEC_ID(0x10ec0663, "ALC663"), 1095 HDA_CODEC_ID(0x10ec0665, "ALC665"), 1096 HDA_CODEC_ID(0x10ec0667, "ALC667"), 1097 HDA_CODEC_ID(0x10ec0668, "ALC668"), 1098 HDA_CODEC_ID(0x10ec0670, "ALC670"), 1099 HDA_CODEC_ID(0x10ec0671, "ALC671"), 1100 HDA_CODEC_ID(0x10ec0867, "ALC891"), 1101 HDA_CODEC_ID(0x10ec0892, "ALC892"), 1102 HDA_CODEC_ID(0x10ec0897, "ALC897"), 1103 {} /* terminator */ 1104 }; 1105 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc662); 1106 1107 MODULE_LICENSE("GPL"); 1108 MODULE_DESCRIPTION("Realtek ALC662 and compatible HD-audio codec"); 1109 MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK"); 1110 1111 static struct hda_codec_driver alc662_driver = { 1112 .id = snd_hda_id_alc662, 1113 .ops = &alc662_codec_ops, 1114 }; 1115 1116 module_hda_codec_driver(alc662_driver); 1117