1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Universal Interface for Intel High Definition Audio Codec 4 * 5 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec 6 * 7 * (C) 2006-2009 VIA Technology, Inc. 8 * (C) 2006-2008 Takashi Iwai <tiwai@suse.de> 9 */ 10 11 /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */ 12 /* */ 13 /* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */ 14 /* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */ 15 /* 2006-08-02 Lydia Wang Add support to VT1709 codec */ 16 /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */ 17 /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */ 18 /* 2007-09-17 Lydia Wang Add VT1708B codec support */ 19 /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ 20 /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ 21 /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ 22 /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ 23 /* 2008-04-09 Lydia Wang Add Independent HP feature */ 24 /* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */ 25 /* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */ 26 /* 2009-02-16 Logan Li Add support for VT1718S */ 27 /* 2009-03-13 Logan Li Add support for VT1716S */ 28 /* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */ 29 /* 2009-07-08 Lydia Wang Add support for VT2002P */ 30 /* 2009-07-21 Lydia Wang Add support for VT1812 */ 31 /* 2009-09-19 Lydia Wang Add support for VT1818S */ 32 /* */ 33 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 34 35 36 #include <linux/init.h> 37 #include <linux/delay.h> 38 #include <linux/slab.h> 39 #include <linux/module.h> 40 #include <sound/core.h> 41 #include <sound/asoundef.h> 42 #include <sound/hda_codec.h> 43 #include "hda_local.h" 44 #include "hda_auto_parser.h" 45 #include "hda_jack.h" 46 #include "hda_generic.h" 47 48 /* Pin Widget NID */ 49 #define VT1708_HP_PIN_NID 0x20 50 #define VT1708_CD_PIN_NID 0x24 51 52 enum VIA_HDA_CODEC { 53 UNKNOWN = -1, 54 VT1708, 55 VT1709_10CH, 56 VT1709_6CH, 57 VT1708B_8CH, 58 VT1708B_4CH, 59 VT1708S, 60 VT1708BCE, 61 VT1702, 62 VT1718S, 63 VT1716S, 64 VT2002P, 65 VT1812, 66 VT1802, 67 VT1705CF, 68 VT1808, 69 CODEC_TYPES, 70 }; 71 72 #define VT2002P_COMPATIBLE(spec) \ 73 ((spec)->codec_type == VT2002P ||\ 74 (spec)->codec_type == VT1812 ||\ 75 (spec)->codec_type == VT1802) 76 77 struct via_spec { 78 struct hda_gen_spec gen; 79 80 /* HP mode source */ 81 unsigned int dmic_enabled; 82 enum VIA_HDA_CODEC codec_type; 83 84 /* analog low-power control */ 85 bool alc_mode; 86 87 /* work to check hp jack state */ 88 int hp_work_active; 89 int vt1708_jack_detect; 90 }; 91 92 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); 93 static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo, 94 struct hda_codec *codec, 95 struct snd_pcm_substream *substream, 96 int action); 97 98 static const struct hda_codec_ops via_patch_ops; /* defined below */ 99 100 static struct via_spec *via_new_spec(struct hda_codec *codec) 101 { 102 struct via_spec *spec; 103 104 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 105 if (spec == NULL) 106 return NULL; 107 108 codec->spec = spec; 109 snd_hda_gen_spec_init(&spec->gen); 110 spec->codec_type = get_codec_type(codec); 111 /* VT1708BCE & VT1708S are almost same */ 112 if (spec->codec_type == VT1708BCE) 113 spec->codec_type = VT1708S; 114 spec->gen.indep_hp = 1; 115 spec->gen.keep_eapd_on = 1; 116 spec->gen.pcm_playback_hook = via_playback_pcm_hook; 117 spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO; 118 codec->power_save_node = 1; 119 spec->gen.power_down_unused = 1; 120 codec->patch_ops = via_patch_ops; 121 return spec; 122 } 123 124 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) 125 { 126 u32 vendor_id = codec->core.vendor_id; 127 u16 ven_id = vendor_id >> 16; 128 u16 dev_id = vendor_id & 0xffff; 129 enum VIA_HDA_CODEC codec_type; 130 131 /* get codec type */ 132 if (ven_id != 0x1106) 133 codec_type = UNKNOWN; 134 else if (dev_id >= 0x1708 && dev_id <= 0x170b) 135 codec_type = VT1708; 136 else if (dev_id >= 0xe710 && dev_id <= 0xe713) 137 codec_type = VT1709_10CH; 138 else if (dev_id >= 0xe714 && dev_id <= 0xe717) 139 codec_type = VT1709_6CH; 140 else if (dev_id >= 0xe720 && dev_id <= 0xe723) { 141 codec_type = VT1708B_8CH; 142 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7) 143 codec_type = VT1708BCE; 144 } else if (dev_id >= 0xe724 && dev_id <= 0xe727) 145 codec_type = VT1708B_4CH; 146 else if ((dev_id & 0xfff) == 0x397 147 && (dev_id >> 12) < 8) 148 codec_type = VT1708S; 149 else if ((dev_id & 0xfff) == 0x398 150 && (dev_id >> 12) < 8) 151 codec_type = VT1702; 152 else if ((dev_id & 0xfff) == 0x428 153 && (dev_id >> 12) < 8) 154 codec_type = VT1718S; 155 else if (dev_id == 0x0433 || dev_id == 0xa721) 156 codec_type = VT1716S; 157 else if (dev_id == 0x0441 || dev_id == 0x4441) 158 codec_type = VT1718S; 159 else if (dev_id == 0x0438 || dev_id == 0x4438) 160 codec_type = VT2002P; 161 else if (dev_id == 0x0448) 162 codec_type = VT1812; 163 else if (dev_id == 0x0440) 164 codec_type = VT1708S; 165 else if ((dev_id & 0xfff) == 0x446) 166 codec_type = VT1802; 167 else if (dev_id == 0x4760) 168 codec_type = VT1705CF; 169 else if (dev_id == 0x4761 || dev_id == 0x4762) 170 codec_type = VT1808; 171 else 172 codec_type = UNKNOWN; 173 return codec_type; 174 }; 175 176 static void analog_low_current_mode(struct hda_codec *codec); 177 static bool is_aa_path_mute(struct hda_codec *codec); 178 179 #define hp_detect_with_aa(codec) \ 180 (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ 181 !is_aa_path_mute(codec)) 182 183 static void vt1708_stop_hp_work(struct hda_codec *codec) 184 { 185 struct via_spec *spec = codec->spec; 186 if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs) 187 return; 188 if (spec->hp_work_active) { 189 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1); 190 codec->jackpoll_interval = 0; 191 cancel_delayed_work_sync(&codec->jackpoll_work); 192 spec->hp_work_active = false; 193 } 194 } 195 196 static void vt1708_update_hp_work(struct hda_codec *codec) 197 { 198 struct via_spec *spec = codec->spec; 199 if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs) 200 return; 201 if (spec->vt1708_jack_detect) { 202 if (!spec->hp_work_active) { 203 codec->jackpoll_interval = msecs_to_jiffies(100); 204 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0); 205 schedule_delayed_work(&codec->jackpoll_work, 0); 206 spec->hp_work_active = true; 207 } 208 } else if (!hp_detect_with_aa(codec)) 209 vt1708_stop_hp_work(codec); 210 } 211 212 static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, 213 struct snd_ctl_elem_info *uinfo) 214 { 215 return snd_hda_enum_bool_helper_info(kcontrol, uinfo); 216 } 217 218 static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol, 219 struct snd_ctl_elem_value *ucontrol) 220 { 221 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 222 struct via_spec *spec = codec->spec; 223 224 ucontrol->value.enumerated.item[0] = spec->gen.power_down_unused; 225 return 0; 226 } 227 228 static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol, 229 struct snd_ctl_elem_value *ucontrol) 230 { 231 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 232 struct via_spec *spec = codec->spec; 233 bool val = !!ucontrol->value.enumerated.item[0]; 234 235 if (val == spec->gen.power_down_unused) 236 return 0; 237 /* codec->power_save_node = val; */ /* widget PM seems yet broken */ 238 spec->gen.power_down_unused = val; 239 analog_low_current_mode(codec); 240 return 1; 241 } 242 243 static const struct snd_kcontrol_new via_pin_power_ctl_enum = { 244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 245 .name = "Dynamic Power-Control", 246 .info = via_pin_power_ctl_info, 247 .get = via_pin_power_ctl_get, 248 .put = via_pin_power_ctl_put, 249 }; 250 251 #ifdef CONFIG_SND_HDA_INPUT_BEEP 252 /* additional beep mixers; the actual parameters are overwritten at build */ 253 static const struct snd_kcontrol_new via_beep_mixer[] = { 254 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), 255 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), 256 }; 257 258 static int set_beep_amp(struct via_spec *spec, hda_nid_t nid, 259 int idx, int dir) 260 { 261 struct snd_kcontrol_new *knew; 262 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); 263 int i; 264 265 spec->gen.beep_nid = nid; 266 for (i = 0; i < ARRAY_SIZE(via_beep_mixer); i++) { 267 knew = snd_hda_gen_add_kctl(&spec->gen, NULL, 268 &via_beep_mixer[i]); 269 if (!knew) 270 return -ENOMEM; 271 knew->private_value = beep_amp; 272 } 273 return 0; 274 } 275 276 static int auto_parse_beep(struct hda_codec *codec) 277 { 278 struct via_spec *spec = codec->spec; 279 hda_nid_t nid; 280 281 for_each_hda_codec_node(nid, codec) 282 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) 283 return set_beep_amp(spec, nid, 0, HDA_OUTPUT); 284 return 0; 285 } 286 #else 287 #define auto_parse_beep(codec) 0 288 #endif 289 290 /* check AA path's mute status */ 291 static bool is_aa_path_mute(struct hda_codec *codec) 292 { 293 struct via_spec *spec = codec->spec; 294 const struct hda_amp_list *p; 295 int ch, v; 296 297 p = spec->gen.loopback.amplist; 298 if (!p) 299 return true; 300 for (; p->nid; p++) { 301 for (ch = 0; ch < 2; ch++) { 302 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir, 303 p->idx); 304 if (!(v & HDA_AMP_MUTE) && v > 0) 305 return false; 306 } 307 } 308 return true; 309 } 310 311 /* enter/exit analog low-current mode */ 312 static void __analog_low_current_mode(struct hda_codec *codec, bool force) 313 { 314 struct via_spec *spec = codec->spec; 315 bool enable; 316 unsigned int verb, parm; 317 318 if (!codec->power_save_node) 319 enable = false; 320 else 321 enable = is_aa_path_mute(codec) && !spec->gen.active_streams; 322 if (enable == spec->alc_mode && !force) 323 return; 324 spec->alc_mode = enable; 325 326 /* decide low current mode's verb & parameter */ 327 switch (spec->codec_type) { 328 case VT1708B_8CH: 329 case VT1708B_4CH: 330 verb = 0xf70; 331 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */ 332 break; 333 case VT1708S: 334 case VT1718S: 335 case VT1716S: 336 verb = 0xf73; 337 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */ 338 break; 339 case VT1702: 340 verb = 0xf73; 341 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */ 342 break; 343 case VT2002P: 344 case VT1812: 345 case VT1802: 346 verb = 0xf93; 347 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ 348 break; 349 case VT1705CF: 350 case VT1808: 351 verb = 0xf82; 352 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ 353 break; 354 default: 355 return; /* other codecs are not supported */ 356 } 357 /* send verb */ 358 snd_hda_codec_write(codec, codec->core.afg, 0, verb, parm); 359 } 360 361 static void analog_low_current_mode(struct hda_codec *codec) 362 { 363 return __analog_low_current_mode(codec, false); 364 } 365 366 static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo, 367 struct hda_codec *codec, 368 struct snd_pcm_substream *substream, 369 int action) 370 { 371 analog_low_current_mode(codec); 372 vt1708_update_hp_work(codec); 373 } 374 375 static void via_free(struct hda_codec *codec) 376 { 377 vt1708_stop_hp_work(codec); 378 snd_hda_gen_free(codec); 379 } 380 381 #ifdef CONFIG_PM 382 static int via_suspend(struct hda_codec *codec) 383 { 384 struct via_spec *spec = codec->spec; 385 vt1708_stop_hp_work(codec); 386 387 /* Fix pop noise on headphones */ 388 if (spec->codec_type == VT1802) 389 snd_hda_shutup_pins(codec); 390 391 return 0; 392 } 393 394 static int via_resume(struct hda_codec *codec) 395 { 396 /* some delay here to make jack detection working (bko#98921) */ 397 msleep(10); 398 codec->patch_ops.init(codec); 399 snd_hda_regmap_sync(codec); 400 return 0; 401 } 402 #endif 403 404 #ifdef CONFIG_PM 405 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 406 { 407 struct via_spec *spec = codec->spec; 408 analog_low_current_mode(codec); 409 vt1708_update_hp_work(codec); 410 return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid); 411 } 412 #endif 413 414 /* 415 */ 416 417 static int via_init(struct hda_codec *codec); 418 419 static const struct hda_codec_ops via_patch_ops = { 420 .build_controls = snd_hda_gen_build_controls, 421 .build_pcms = snd_hda_gen_build_pcms, 422 .init = via_init, 423 .free = via_free, 424 .unsol_event = snd_hda_jack_unsol_event, 425 #ifdef CONFIG_PM 426 .suspend = via_suspend, 427 .resume = via_resume, 428 .check_power_status = via_check_power_status, 429 #endif 430 }; 431 432 433 static const struct hda_verb vt1708_init_verbs[] = { 434 /* power down jack detect function */ 435 {0x1, 0xf81, 0x1}, 436 { } 437 }; 438 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) 439 { 440 unsigned int def_conf; 441 unsigned char seqassoc; 442 443 def_conf = snd_hda_codec_get_pincfg(codec, nid); 444 seqassoc = (unsigned char) get_defcfg_association(def_conf); 445 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf); 446 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE 447 && (seqassoc == 0xf0 || seqassoc == 0xff)) { 448 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30)); 449 snd_hda_codec_set_pincfg(codec, nid, def_conf); 450 } 451 452 return; 453 } 454 455 static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol, 456 struct snd_ctl_elem_value *ucontrol) 457 { 458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 459 struct via_spec *spec = codec->spec; 460 461 if (spec->codec_type != VT1708) 462 return 0; 463 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect; 464 return 0; 465 } 466 467 static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, 468 struct snd_ctl_elem_value *ucontrol) 469 { 470 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 471 struct via_spec *spec = codec->spec; 472 int val; 473 474 if (spec->codec_type != VT1708) 475 return 0; 476 val = !!ucontrol->value.integer.value[0]; 477 if (spec->vt1708_jack_detect == val) 478 return 0; 479 spec->vt1708_jack_detect = val; 480 vt1708_update_hp_work(codec); 481 return 1; 482 } 483 484 static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { 485 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 486 .name = "Jack Detect", 487 .count = 1, 488 .info = snd_ctl_boolean_mono_info, 489 .get = vt1708_jack_detect_get, 490 .put = vt1708_jack_detect_put, 491 }; 492 493 static const struct badness_table via_main_out_badness = { 494 .no_primary_dac = 0x10000, 495 .no_dac = 0x4000, 496 .shared_primary = 0x10000, 497 .shared_surr = 0x20, 498 .shared_clfe = 0x20, 499 .shared_surr_main = 0x20, 500 }; 501 static const struct badness_table via_extra_out_badness = { 502 .no_primary_dac = 0x4000, 503 .no_dac = 0x4000, 504 .shared_primary = 0x12, 505 .shared_surr = 0x20, 506 .shared_clfe = 0x20, 507 .shared_surr_main = 0x10, 508 }; 509 510 static int via_parse_auto_config(struct hda_codec *codec) 511 { 512 struct via_spec *spec = codec->spec; 513 int err; 514 515 spec->gen.main_out_badness = &via_main_out_badness; 516 spec->gen.extra_out_badness = &via_extra_out_badness; 517 518 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); 519 if (err < 0) 520 return err; 521 522 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); 523 if (err < 0) 524 return err; 525 526 err = auto_parse_beep(codec); 527 if (err < 0) 528 return err; 529 530 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &via_pin_power_ctl_enum)) 531 return -ENOMEM; 532 533 /* disable widget PM at start for compatibility */ 534 codec->power_save_node = 0; 535 spec->gen.power_down_unused = 0; 536 return 0; 537 } 538 539 static int via_init(struct hda_codec *codec) 540 { 541 /* init power states */ 542 __analog_low_current_mode(codec, true); 543 544 snd_hda_gen_init(codec); 545 546 vt1708_update_hp_work(codec); 547 548 return 0; 549 } 550 551 static int vt1708_build_controls(struct hda_codec *codec) 552 { 553 /* In order not to create "Phantom Jack" controls, 554 temporary enable jackpoll */ 555 int err; 556 int old_interval = codec->jackpoll_interval; 557 codec->jackpoll_interval = msecs_to_jiffies(100); 558 err = snd_hda_gen_build_controls(codec); 559 codec->jackpoll_interval = old_interval; 560 return err; 561 } 562 563 static int vt1708_build_pcms(struct hda_codec *codec) 564 { 565 struct via_spec *spec = codec->spec; 566 int i, err; 567 568 err = snd_hda_gen_build_pcms(codec); 569 if (err < 0 || codec->core.vendor_id != 0x11061708) 570 return err; 571 572 /* We got noisy outputs on the right channel on VT1708 when 573 * 24bit samples are used. Until any workaround is found, 574 * disable the 24bit format, so far. 575 */ 576 for (i = 0; i < ARRAY_SIZE(spec->gen.pcm_rec); i++) { 577 struct hda_pcm *info = spec->gen.pcm_rec[i]; 578 if (!info) 579 continue; 580 if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || 581 info->pcm_type != HDA_PCM_TYPE_AUDIO) 582 continue; 583 info->stream[SNDRV_PCM_STREAM_PLAYBACK].formats = 584 SNDRV_PCM_FMTBIT_S16_LE; 585 } 586 587 return 0; 588 } 589 590 static int patch_vt1708(struct hda_codec *codec) 591 { 592 struct via_spec *spec; 593 int err; 594 595 /* create a codec specific record */ 596 spec = via_new_spec(codec); 597 if (spec == NULL) 598 return -ENOMEM; 599 600 /* override some patch_ops */ 601 codec->patch_ops.build_controls = vt1708_build_controls; 602 codec->patch_ops.build_pcms = vt1708_build_pcms; 603 spec->gen.mixer_nid = 0x17; 604 605 /* set jackpoll_interval while parsing the codec */ 606 codec->jackpoll_interval = msecs_to_jiffies(100); 607 spec->vt1708_jack_detect = 1; 608 609 /* don't support the input jack switching due to lack of unsol event */ 610 /* (it may work with polling, though, but it needs testing) */ 611 spec->gen.suppress_auto_mic = 1; 612 /* Some machines show the broken speaker mute */ 613 spec->gen.auto_mute_via_amp = 1; 614 615 /* Add HP and CD pin config connect bit re-config action */ 616 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); 617 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID); 618 619 err = snd_hda_add_verbs(codec, vt1708_init_verbs); 620 if (err < 0) 621 goto error; 622 623 /* automatic parse from the BIOS config */ 624 err = via_parse_auto_config(codec); 625 if (err < 0) 626 goto error; 627 628 /* add jack detect on/off control */ 629 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1708_jack_detect_ctl)) { 630 err = -ENOMEM; 631 goto error; 632 } 633 634 /* clear jackpoll_interval again; it's set dynamically */ 635 codec->jackpoll_interval = 0; 636 637 return 0; 638 639 error: 640 via_free(codec); 641 return err; 642 } 643 644 static int patch_vt1709(struct hda_codec *codec) 645 { 646 struct via_spec *spec; 647 int err; 648 649 /* create a codec specific record */ 650 spec = via_new_spec(codec); 651 if (spec == NULL) 652 return -ENOMEM; 653 654 spec->gen.mixer_nid = 0x18; 655 656 err = via_parse_auto_config(codec); 657 if (err < 0) 658 goto error; 659 660 return 0; 661 662 error: 663 via_free(codec); 664 return err; 665 } 666 667 static int patch_vt1708S(struct hda_codec *codec); 668 static int patch_vt1708B(struct hda_codec *codec) 669 { 670 struct via_spec *spec; 671 int err; 672 673 if (get_codec_type(codec) == VT1708BCE) 674 return patch_vt1708S(codec); 675 676 /* create a codec specific record */ 677 spec = via_new_spec(codec); 678 if (spec == NULL) 679 return -ENOMEM; 680 681 spec->gen.mixer_nid = 0x16; 682 683 /* automatic parse from the BIOS config */ 684 err = via_parse_auto_config(codec); 685 if (err < 0) 686 goto error; 687 688 return 0; 689 690 error: 691 via_free(codec); 692 return err; 693 } 694 695 /* Patch for VT1708S */ 696 static const struct hda_verb vt1708S_init_verbs[] = { 697 /* Enable Mic Boost Volume backdoor */ 698 {0x1, 0xf98, 0x1}, 699 /* don't bybass mixer */ 700 {0x1, 0xf88, 0xc0}, 701 { } 702 }; 703 704 static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, 705 int offset, int num_steps, int step_size) 706 { 707 snd_hda_override_wcaps(codec, pin, 708 get_wcaps(codec, pin) | AC_WCAP_IN_AMP); 709 snd_hda_override_amp_caps(codec, pin, HDA_INPUT, 710 (offset << AC_AMPCAP_OFFSET_SHIFT) | 711 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) | 712 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) | 713 (0 << AC_AMPCAP_MUTE_SHIFT)); 714 } 715 716 static int patch_vt1708S(struct hda_codec *codec) 717 { 718 struct via_spec *spec; 719 int err; 720 721 /* create a codec specific record */ 722 spec = via_new_spec(codec); 723 if (spec == NULL) 724 return -ENOMEM; 725 726 spec->gen.mixer_nid = 0x16; 727 override_mic_boost(codec, 0x1a, 0, 3, 40); 728 override_mic_boost(codec, 0x1e, 0, 3, 40); 729 730 /* correct names for VT1708BCE */ 731 if (get_codec_type(codec) == VT1708BCE) 732 snd_hda_codec_set_name(codec, "VT1708BCE"); 733 /* correct names for VT1705 */ 734 if (codec->core.vendor_id == 0x11064397) 735 snd_hda_codec_set_name(codec, "VT1705"); 736 737 err = snd_hda_add_verbs(codec, vt1708S_init_verbs); 738 if (err < 0) 739 goto error; 740 741 /* automatic parse from the BIOS config */ 742 err = via_parse_auto_config(codec); 743 if (err < 0) 744 goto error; 745 746 return 0; 747 748 error: 749 via_free(codec); 750 return err; 751 } 752 753 /* Patch for VT1702 */ 754 755 static const struct hda_verb vt1702_init_verbs[] = { 756 /* mixer enable */ 757 {0x1, 0xF88, 0x3}, 758 /* GPIO 0~2 */ 759 {0x1, 0xF82, 0x3F}, 760 { } 761 }; 762 763 static int patch_vt1702(struct hda_codec *codec) 764 { 765 struct via_spec *spec; 766 int err; 767 768 /* create a codec specific record */ 769 spec = via_new_spec(codec); 770 if (spec == NULL) 771 return -ENOMEM; 772 773 spec->gen.mixer_nid = 0x1a; 774 775 /* limit AA path volume to 0 dB */ 776 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT, 777 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 778 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 779 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) | 780 (1 << AC_AMPCAP_MUTE_SHIFT)); 781 782 err = snd_hda_add_verbs(codec, vt1702_init_verbs); 783 if (err < 0) 784 goto error; 785 786 /* automatic parse from the BIOS config */ 787 err = via_parse_auto_config(codec); 788 if (err < 0) 789 goto error; 790 791 return 0; 792 793 error: 794 via_free(codec); 795 return err; 796 } 797 798 /* Patch for VT1718S */ 799 800 static const struct hda_verb vt1718S_init_verbs[] = { 801 /* Enable MW0 adjust Gain 5 */ 802 {0x1, 0xfb2, 0x10}, 803 /* Enable Boost Volume backdoor */ 804 {0x1, 0xf88, 0x8}, 805 806 { } 807 }; 808 809 /* Add a connection to the primary DAC from AA-mixer for some codecs 810 * This isn't listed from the raw info, but the chip has a secret connection. 811 */ 812 static int add_secret_dac_path(struct hda_codec *codec) 813 { 814 struct via_spec *spec = codec->spec; 815 int i, nums; 816 hda_nid_t conn[8]; 817 hda_nid_t nid; 818 819 if (!spec->gen.mixer_nid) 820 return 0; 821 nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn, 822 ARRAY_SIZE(conn) - 1); 823 for (i = 0; i < nums; i++) { 824 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT) 825 return 0; 826 } 827 828 /* find the primary DAC and add to the connection list */ 829 for_each_hda_codec_node(nid, codec) { 830 unsigned int caps = get_wcaps(codec, nid); 831 if (get_wcaps_type(caps) == AC_WID_AUD_OUT && 832 !(caps & AC_WCAP_DIGITAL)) { 833 conn[nums++] = nid; 834 return snd_hda_override_conn_list(codec, 835 spec->gen.mixer_nid, 836 nums, conn); 837 } 838 } 839 return 0; 840 } 841 842 843 static int patch_vt1718S(struct hda_codec *codec) 844 { 845 struct via_spec *spec; 846 int err; 847 848 /* create a codec specific record */ 849 spec = via_new_spec(codec); 850 if (spec == NULL) 851 return -ENOMEM; 852 853 spec->gen.mixer_nid = 0x21; 854 override_mic_boost(codec, 0x2b, 0, 3, 40); 855 override_mic_boost(codec, 0x29, 0, 3, 40); 856 add_secret_dac_path(codec); 857 858 err = snd_hda_add_verbs(codec, vt1718S_init_verbs); 859 if (err < 0) 860 goto error; 861 862 /* automatic parse from the BIOS config */ 863 err = via_parse_auto_config(codec); 864 if (err < 0) 865 goto error; 866 867 return 0; 868 869 error: 870 via_free(codec); 871 return err; 872 } 873 874 /* Patch for VT1716S */ 875 876 static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol, 877 struct snd_ctl_elem_info *uinfo) 878 { 879 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 880 uinfo->count = 1; 881 uinfo->value.integer.min = 0; 882 uinfo->value.integer.max = 1; 883 return 0; 884 } 885 886 static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol, 887 struct snd_ctl_elem_value *ucontrol) 888 { 889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 890 int index = 0; 891 892 index = snd_hda_codec_read(codec, 0x26, 0, 893 AC_VERB_GET_CONNECT_SEL, 0); 894 if (index != -1) 895 *ucontrol->value.integer.value = index; 896 897 return 0; 898 } 899 900 static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol, 901 struct snd_ctl_elem_value *ucontrol) 902 { 903 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 904 struct via_spec *spec = codec->spec; 905 int index = *ucontrol->value.integer.value; 906 907 snd_hda_codec_write(codec, 0x26, 0, 908 AC_VERB_SET_CONNECT_SEL, index); 909 spec->dmic_enabled = index; 910 return 1; 911 } 912 913 static const struct snd_kcontrol_new vt1716s_dmic_mixer_vol = 914 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT); 915 static const struct snd_kcontrol_new vt1716s_dmic_mixer_sw = { 916 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 917 .name = "Digital Mic Capture Switch", 918 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26, 919 .count = 1, 920 .info = vt1716s_dmic_info, 921 .get = vt1716s_dmic_get, 922 .put = vt1716s_dmic_put, 923 }; 924 925 926 /* mono-out mixer elements */ 927 static const struct snd_kcontrol_new vt1716S_mono_out_mixer = 928 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT); 929 930 static const struct hda_verb vt1716S_init_verbs[] = { 931 /* Enable Boost Volume backdoor */ 932 {0x1, 0xf8a, 0x80}, 933 /* don't bybass mixer */ 934 {0x1, 0xf88, 0xc0}, 935 /* Enable mono output */ 936 {0x1, 0xf90, 0x08}, 937 { } 938 }; 939 940 static int patch_vt1716S(struct hda_codec *codec) 941 { 942 struct via_spec *spec; 943 int err; 944 945 /* create a codec specific record */ 946 spec = via_new_spec(codec); 947 if (spec == NULL) 948 return -ENOMEM; 949 950 spec->gen.mixer_nid = 0x16; 951 override_mic_boost(codec, 0x1a, 0, 3, 40); 952 override_mic_boost(codec, 0x1e, 0, 3, 40); 953 954 err = snd_hda_add_verbs(codec, vt1716S_init_verbs); 955 if (err < 0) 956 goto error; 957 958 /* automatic parse from the BIOS config */ 959 err = via_parse_auto_config(codec); 960 if (err < 0) 961 goto error; 962 963 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716s_dmic_mixer_vol) || 964 !snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716s_dmic_mixer_sw) || 965 !snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716S_mono_out_mixer)) { 966 err = -ENOMEM; 967 goto error; 968 } 969 970 return 0; 971 972 error: 973 via_free(codec); 974 return err; 975 } 976 977 /* for vt2002P */ 978 979 static const struct hda_verb vt2002P_init_verbs[] = { 980 /* Class-D speaker related verbs */ 981 {0x1, 0xfe0, 0x4}, 982 {0x1, 0xfe9, 0x80}, 983 {0x1, 0xfe2, 0x22}, 984 /* Enable Boost Volume backdoor */ 985 {0x1, 0xfb9, 0x24}, 986 /* Enable AOW0 to MW9 */ 987 {0x1, 0xfb8, 0x88}, 988 { } 989 }; 990 991 static const struct hda_verb vt1802_init_verbs[] = { 992 /* Enable Boost Volume backdoor */ 993 {0x1, 0xfb9, 0x24}, 994 /* Enable AOW0 to MW9 */ 995 {0x1, 0xfb8, 0x88}, 996 { } 997 }; 998 999 /* 1000 * pin fix-up 1001 */ 1002 enum { 1003 VIA_FIXUP_INTMIC_BOOST, 1004 VIA_FIXUP_ASUS_G75, 1005 VIA_FIXUP_POWER_SAVE, 1006 }; 1007 1008 static void via_fixup_intmic_boost(struct hda_codec *codec, 1009 const struct hda_fixup *fix, int action) 1010 { 1011 if (action == HDA_FIXUP_ACT_PRE_PROBE) 1012 override_mic_boost(codec, 0x30, 0, 2, 40); 1013 } 1014 1015 static void via_fixup_power_save(struct hda_codec *codec, 1016 const struct hda_fixup *fix, int action) 1017 { 1018 if (action == HDA_FIXUP_ACT_PRE_PROBE) 1019 codec->power_save_node = 0; 1020 } 1021 1022 static const struct hda_fixup via_fixups[] = { 1023 [VIA_FIXUP_INTMIC_BOOST] = { 1024 .type = HDA_FIXUP_FUNC, 1025 .v.func = via_fixup_intmic_boost, 1026 }, 1027 [VIA_FIXUP_ASUS_G75] = { 1028 .type = HDA_FIXUP_PINS, 1029 .v.pins = (const struct hda_pintbl[]) { 1030 /* set 0x24 and 0x33 as speakers */ 1031 { 0x24, 0x991301f0 }, 1032 { 0x33, 0x991301f1 }, /* subwoofer */ 1033 { } 1034 } 1035 }, 1036 [VIA_FIXUP_POWER_SAVE] = { 1037 .type = HDA_FIXUP_FUNC, 1038 .v.func = via_fixup_power_save, 1039 }, 1040 }; 1041 1042 static const struct snd_pci_quirk vt2002p_fixups[] = { 1043 SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), 1044 SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), 1045 SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", VIA_FIXUP_POWER_SAVE), 1046 {} 1047 }; 1048 1049 /* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e 1050 * Replace this with mixer NID 0x1c 1051 */ 1052 static void fix_vt1802_connections(struct hda_codec *codec) 1053 { 1054 static const hda_nid_t conn_24[] = { 0x14, 0x1c }; 1055 static const hda_nid_t conn_33[] = { 0x1c }; 1056 1057 snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); 1058 snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); 1059 } 1060 1061 /* patch for vt2002P */ 1062 static int patch_vt2002P(struct hda_codec *codec) 1063 { 1064 struct via_spec *spec; 1065 int err; 1066 1067 /* create a codec specific record */ 1068 spec = via_new_spec(codec); 1069 if (spec == NULL) 1070 return -ENOMEM; 1071 1072 spec->gen.mixer_nid = 0x21; 1073 override_mic_boost(codec, 0x2b, 0, 3, 40); 1074 override_mic_boost(codec, 0x29, 0, 3, 40); 1075 if (spec->codec_type == VT1802) 1076 fix_vt1802_connections(codec); 1077 add_secret_dac_path(codec); 1078 1079 snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); 1080 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1081 1082 if (spec->codec_type == VT1802) 1083 err = snd_hda_add_verbs(codec, vt1802_init_verbs); 1084 else 1085 err = snd_hda_add_verbs(codec, vt2002P_init_verbs); 1086 if (err < 0) 1087 goto error; 1088 1089 /* automatic parse from the BIOS config */ 1090 err = via_parse_auto_config(codec); 1091 if (err < 0) 1092 goto error; 1093 1094 return 0; 1095 1096 error: 1097 via_free(codec); 1098 return err; 1099 } 1100 1101 /* for vt1812 */ 1102 1103 static const struct hda_verb vt1812_init_verbs[] = { 1104 /* Enable Boost Volume backdoor */ 1105 {0x1, 0xfb9, 0x24}, 1106 /* Enable AOW0 to MW9 */ 1107 {0x1, 0xfb8, 0xa8}, 1108 { } 1109 }; 1110 1111 /* patch for vt1812 */ 1112 static int patch_vt1812(struct hda_codec *codec) 1113 { 1114 struct via_spec *spec; 1115 int err; 1116 1117 /* create a codec specific record */ 1118 spec = via_new_spec(codec); 1119 if (spec == NULL) 1120 return -ENOMEM; 1121 1122 spec->gen.mixer_nid = 0x21; 1123 override_mic_boost(codec, 0x2b, 0, 3, 40); 1124 override_mic_boost(codec, 0x29, 0, 3, 40); 1125 add_secret_dac_path(codec); 1126 1127 err = snd_hda_add_verbs(codec, vt1812_init_verbs); 1128 if (err < 0) 1129 goto error; 1130 1131 /* automatic parse from the BIOS config */ 1132 err = via_parse_auto_config(codec); 1133 if (err < 0) 1134 goto error; 1135 1136 return 0; 1137 1138 error: 1139 via_free(codec); 1140 return err; 1141 } 1142 1143 /* patch for vt3476 */ 1144 1145 static const struct hda_verb vt3476_init_verbs[] = { 1146 /* Enable DMic 8/16/32K */ 1147 {0x1, 0xF7B, 0x30}, 1148 /* Enable Boost Volume backdoor */ 1149 {0x1, 0xFB9, 0x20}, 1150 /* Enable AOW-MW9 path */ 1151 {0x1, 0xFB8, 0x10}, 1152 { } 1153 }; 1154 1155 static int patch_vt3476(struct hda_codec *codec) 1156 { 1157 struct via_spec *spec; 1158 int err; 1159 1160 /* create a codec specific record */ 1161 spec = via_new_spec(codec); 1162 if (spec == NULL) 1163 return -ENOMEM; 1164 1165 spec->gen.mixer_nid = 0x3f; 1166 add_secret_dac_path(codec); 1167 1168 err = snd_hda_add_verbs(codec, vt3476_init_verbs); 1169 if (err < 0) 1170 goto error; 1171 1172 /* automatic parse from the BIOS config */ 1173 err = via_parse_auto_config(codec); 1174 if (err < 0) 1175 goto error; 1176 1177 return 0; 1178 1179 error: 1180 via_free(codec); 1181 return err; 1182 } 1183 1184 /* 1185 * patch entries 1186 */ 1187 static const struct hda_device_id snd_hda_id_via[] = { 1188 HDA_CODEC_ENTRY(0x11061708, "VT1708", patch_vt1708), 1189 HDA_CODEC_ENTRY(0x11061709, "VT1708", patch_vt1708), 1190 HDA_CODEC_ENTRY(0x1106170a, "VT1708", patch_vt1708), 1191 HDA_CODEC_ENTRY(0x1106170b, "VT1708", patch_vt1708), 1192 HDA_CODEC_ENTRY(0x1106e710, "VT1709 10-Ch", patch_vt1709), 1193 HDA_CODEC_ENTRY(0x1106e711, "VT1709 10-Ch", patch_vt1709), 1194 HDA_CODEC_ENTRY(0x1106e712, "VT1709 10-Ch", patch_vt1709), 1195 HDA_CODEC_ENTRY(0x1106e713, "VT1709 10-Ch", patch_vt1709), 1196 HDA_CODEC_ENTRY(0x1106e714, "VT1709 6-Ch", patch_vt1709), 1197 HDA_CODEC_ENTRY(0x1106e715, "VT1709 6-Ch", patch_vt1709), 1198 HDA_CODEC_ENTRY(0x1106e716, "VT1709 6-Ch", patch_vt1709), 1199 HDA_CODEC_ENTRY(0x1106e717, "VT1709 6-Ch", patch_vt1709), 1200 HDA_CODEC_ENTRY(0x1106e720, "VT1708B 8-Ch", patch_vt1708B), 1201 HDA_CODEC_ENTRY(0x1106e721, "VT1708B 8-Ch", patch_vt1708B), 1202 HDA_CODEC_ENTRY(0x1106e722, "VT1708B 8-Ch", patch_vt1708B), 1203 HDA_CODEC_ENTRY(0x1106e723, "VT1708B 8-Ch", patch_vt1708B), 1204 HDA_CODEC_ENTRY(0x1106e724, "VT1708B 4-Ch", patch_vt1708B), 1205 HDA_CODEC_ENTRY(0x1106e725, "VT1708B 4-Ch", patch_vt1708B), 1206 HDA_CODEC_ENTRY(0x1106e726, "VT1708B 4-Ch", patch_vt1708B), 1207 HDA_CODEC_ENTRY(0x1106e727, "VT1708B 4-Ch", patch_vt1708B), 1208 HDA_CODEC_ENTRY(0x11060397, "VT1708S", patch_vt1708S), 1209 HDA_CODEC_ENTRY(0x11061397, "VT1708S", patch_vt1708S), 1210 HDA_CODEC_ENTRY(0x11062397, "VT1708S", patch_vt1708S), 1211 HDA_CODEC_ENTRY(0x11063397, "VT1708S", patch_vt1708S), 1212 HDA_CODEC_ENTRY(0x11064397, "VT1705", patch_vt1708S), 1213 HDA_CODEC_ENTRY(0x11065397, "VT1708S", patch_vt1708S), 1214 HDA_CODEC_ENTRY(0x11066397, "VT1708S", patch_vt1708S), 1215 HDA_CODEC_ENTRY(0x11067397, "VT1708S", patch_vt1708S), 1216 HDA_CODEC_ENTRY(0x11060398, "VT1702", patch_vt1702), 1217 HDA_CODEC_ENTRY(0x11061398, "VT1702", patch_vt1702), 1218 HDA_CODEC_ENTRY(0x11062398, "VT1702", patch_vt1702), 1219 HDA_CODEC_ENTRY(0x11063398, "VT1702", patch_vt1702), 1220 HDA_CODEC_ENTRY(0x11064398, "VT1702", patch_vt1702), 1221 HDA_CODEC_ENTRY(0x11065398, "VT1702", patch_vt1702), 1222 HDA_CODEC_ENTRY(0x11066398, "VT1702", patch_vt1702), 1223 HDA_CODEC_ENTRY(0x11067398, "VT1702", patch_vt1702), 1224 HDA_CODEC_ENTRY(0x11060428, "VT1718S", patch_vt1718S), 1225 HDA_CODEC_ENTRY(0x11064428, "VT1718S", patch_vt1718S), 1226 HDA_CODEC_ENTRY(0x11060441, "VT2020", patch_vt1718S), 1227 HDA_CODEC_ENTRY(0x11064441, "VT1828S", patch_vt1718S), 1228 HDA_CODEC_ENTRY(0x11060433, "VT1716S", patch_vt1716S), 1229 HDA_CODEC_ENTRY(0x1106a721, "VT1716S", patch_vt1716S), 1230 HDA_CODEC_ENTRY(0x11060438, "VT2002P", patch_vt2002P), 1231 HDA_CODEC_ENTRY(0x11064438, "VT2002P", patch_vt2002P), 1232 HDA_CODEC_ENTRY(0x11060448, "VT1812", patch_vt1812), 1233 HDA_CODEC_ENTRY(0x11060440, "VT1818S", patch_vt1708S), 1234 HDA_CODEC_ENTRY(0x11060446, "VT1802", patch_vt2002P), 1235 HDA_CODEC_ENTRY(0x11068446, "VT1802", patch_vt2002P), 1236 HDA_CODEC_ENTRY(0x11064760, "VT1705CF", patch_vt3476), 1237 HDA_CODEC_ENTRY(0x11064761, "VT1708SCE", patch_vt3476), 1238 HDA_CODEC_ENTRY(0x11064762, "VT1808", patch_vt3476), 1239 {} /* terminator */ 1240 }; 1241 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_via); 1242 1243 static struct hda_codec_driver via_driver = { 1244 .id = snd_hda_id_via, 1245 }; 1246 1247 MODULE_LICENSE("GPL"); 1248 MODULE_DESCRIPTION("VIA HD-audio codec"); 1249 1250 module_hda_codec_driver(via_driver); 1251