1 /* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for SigmaTel STAC92xx 5 * 6 * Copyright (c) 2005 Embedded Alley Solutions, Inc. 7 * Matt Porter <mporter@embeddedalley.com> 8 * 9 * Based on patch_cmedia.c and patch_realtek.c 10 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de> 11 * 12 * This driver is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 * 17 * This driver is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 */ 26 27 #include <linux/init.h> 28 #include <linux/delay.h> 29 #include <linux/slab.h> 30 #include <linux/pci.h> 31 #include <linux/dmi.h> 32 #include <linux/module.h> 33 #include <sound/core.h> 34 #include <sound/jack.h> 35 #include <sound/tlv.h> 36 #include "hda_codec.h" 37 #include "hda_local.h" 38 #include "hda_auto_parser.h" 39 #include "hda_beep.h" 40 #include "hda_jack.h" 41 #include "hda_generic.h" 42 43 enum { 44 STAC_VREF_EVENT = 8, 45 STAC_PWR_EVENT, 46 }; 47 48 enum { 49 STAC_REF, 50 STAC_9200_OQO, 51 STAC_9200_DELL_D21, 52 STAC_9200_DELL_D22, 53 STAC_9200_DELL_D23, 54 STAC_9200_DELL_M21, 55 STAC_9200_DELL_M22, 56 STAC_9200_DELL_M23, 57 STAC_9200_DELL_M24, 58 STAC_9200_DELL_M25, 59 STAC_9200_DELL_M26, 60 STAC_9200_DELL_M27, 61 STAC_9200_M4, 62 STAC_9200_M4_2, 63 STAC_9200_PANASONIC, 64 STAC_9200_EAPD_INIT, 65 STAC_9200_MODELS 66 }; 67 68 enum { 69 STAC_9205_REF, 70 STAC_9205_DELL_M42, 71 STAC_9205_DELL_M43, 72 STAC_9205_DELL_M44, 73 STAC_9205_EAPD, 74 STAC_9205_MODELS 75 }; 76 77 enum { 78 STAC_92HD73XX_NO_JD, /* no jack-detection */ 79 STAC_92HD73XX_REF, 80 STAC_92HD73XX_INTEL, 81 STAC_DELL_M6_AMIC, 82 STAC_DELL_M6_DMIC, 83 STAC_DELL_M6_BOTH, 84 STAC_DELL_EQ, 85 STAC_ALIENWARE_M17X, 86 STAC_92HD73XX_MODELS 87 }; 88 89 enum { 90 STAC_92HD83XXX_REF, 91 STAC_92HD83XXX_PWR_REF, 92 STAC_DELL_S14, 93 STAC_DELL_VOSTRO_3500, 94 STAC_92HD83XXX_HP_cNB11_INTQUAD, 95 STAC_HP_DV7_4000, 96 STAC_HP_ZEPHYR, 97 STAC_92HD83XXX_HP_LED, 98 STAC_92HD83XXX_HP_INV_LED, 99 STAC_92HD83XXX_HP_MIC_LED, 100 STAC_92HD83XXX_HEADSET_JACK, 101 STAC_92HD83XXX_HP, 102 STAC_HP_ENVY_BASS, 103 STAC_HP_BNB13_EQ, 104 STAC_92HD83XXX_MODELS 105 }; 106 107 enum { 108 STAC_92HD71BXX_REF, 109 STAC_DELL_M4_1, 110 STAC_DELL_M4_2, 111 STAC_DELL_M4_3, 112 STAC_HP_M4, 113 STAC_HP_DV4, 114 STAC_HP_DV5, 115 STAC_HP_HDX, 116 STAC_92HD71BXX_HP, 117 STAC_92HD71BXX_NO_DMIC, 118 STAC_92HD71BXX_NO_SMUX, 119 STAC_92HD71BXX_MODELS 120 }; 121 122 enum { 123 STAC_925x_REF, 124 STAC_M1, 125 STAC_M1_2, 126 STAC_M2, 127 STAC_M2_2, 128 STAC_M3, 129 STAC_M5, 130 STAC_M6, 131 STAC_925x_MODELS 132 }; 133 134 enum { 135 STAC_D945_REF, 136 STAC_D945GTP3, 137 STAC_D945GTP5, 138 STAC_INTEL_MAC_V1, 139 STAC_INTEL_MAC_V2, 140 STAC_INTEL_MAC_V3, 141 STAC_INTEL_MAC_V4, 142 STAC_INTEL_MAC_V5, 143 STAC_INTEL_MAC_AUTO, 144 STAC_ECS_202, 145 STAC_922X_DELL_D81, 146 STAC_922X_DELL_D82, 147 STAC_922X_DELL_M81, 148 STAC_922X_DELL_M82, 149 STAC_922X_INTEL_MAC_GPIO, 150 STAC_922X_MODELS 151 }; 152 153 enum { 154 STAC_D965_REF_NO_JD, /* no jack-detection */ 155 STAC_D965_REF, 156 STAC_D965_3ST, 157 STAC_D965_5ST, 158 STAC_D965_5ST_NO_FP, 159 STAC_D965_VERBS, 160 STAC_DELL_3ST, 161 STAC_DELL_BIOS, 162 STAC_DELL_BIOS_AMIC, 163 STAC_DELL_BIOS_SPDIF, 164 STAC_927X_DELL_DMIC, 165 STAC_927X_VOLKNOB, 166 STAC_927X_MODELS 167 }; 168 169 enum { 170 STAC_9872_VAIO, 171 STAC_9872_MODELS 172 }; 173 174 struct sigmatel_spec { 175 struct hda_gen_spec gen; 176 177 unsigned int eapd_switch: 1; 178 unsigned int linear_tone_beep:1; 179 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */ 180 unsigned int volknob_init:1; /* special volume-knob initialization */ 181 unsigned int powerdown_adcs:1; 182 unsigned int have_spdif_mux:1; 183 184 /* gpio lines */ 185 unsigned int eapd_mask; 186 unsigned int gpio_mask; 187 unsigned int gpio_dir; 188 unsigned int gpio_data; 189 unsigned int gpio_mute; 190 unsigned int gpio_led; 191 unsigned int gpio_led_polarity; 192 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ 193 unsigned int vref_led; 194 int default_polarity; 195 196 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ 197 bool mic_mute_led_on; /* current mic mute state */ 198 199 /* stream */ 200 unsigned int stream_delay; 201 202 /* analog loopback */ 203 const struct snd_kcontrol_new *aloopback_ctl; 204 unsigned int aloopback; 205 unsigned char aloopback_mask; 206 unsigned char aloopback_shift; 207 208 /* power management */ 209 unsigned int power_map_bits; 210 unsigned int num_pwrs; 211 const hda_nid_t *pwr_nids; 212 unsigned int active_adcs; 213 214 /* beep widgets */ 215 hda_nid_t anabeep_nid; 216 217 /* SPDIF-out mux */ 218 const char * const *spdif_labels; 219 struct hda_input_mux spdif_mux; 220 unsigned int cur_smux[2]; 221 }; 222 223 #define AC_VERB_IDT_SET_POWER_MAP 0x7ec 224 #define AC_VERB_IDT_GET_POWER_MAP 0xfec 225 226 static const hda_nid_t stac92hd73xx_pwr_nids[8] = { 227 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 228 0x0f, 0x10, 0x11 229 }; 230 231 static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { 232 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 233 0x0f, 0x10 234 }; 235 236 static const hda_nid_t stac92hd71bxx_pwr_nids[3] = { 237 0x0a, 0x0d, 0x0f 238 }; 239 240 241 /* 242 * PCM hooks 243 */ 244 static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo, 245 struct hda_codec *codec, 246 struct snd_pcm_substream *substream, 247 int action) 248 { 249 struct sigmatel_spec *spec = codec->spec; 250 if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay) 251 msleep(spec->stream_delay); 252 } 253 254 static void stac_capture_pcm_hook(struct hda_pcm_stream *hinfo, 255 struct hda_codec *codec, 256 struct snd_pcm_substream *substream, 257 int action) 258 { 259 struct sigmatel_spec *spec = codec->spec; 260 int i, idx = 0; 261 262 if (!spec->powerdown_adcs) 263 return; 264 265 for (i = 0; i < spec->gen.num_all_adcs; i++) { 266 if (spec->gen.all_adcs[i] == hinfo->nid) { 267 idx = i; 268 break; 269 } 270 } 271 272 switch (action) { 273 case HDA_GEN_PCM_ACT_OPEN: 274 msleep(40); 275 snd_hda_codec_write(codec, hinfo->nid, 0, 276 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 277 spec->active_adcs |= (1 << idx); 278 break; 279 case HDA_GEN_PCM_ACT_CLOSE: 280 snd_hda_codec_write(codec, hinfo->nid, 0, 281 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 282 spec->active_adcs &= ~(1 << idx); 283 break; 284 } 285 } 286 287 /* 288 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a 289 * funky external mute control using GPIO pins. 290 */ 291 292 static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, 293 unsigned int dir_mask, unsigned int data) 294 { 295 unsigned int gpiostate, gpiomask, gpiodir; 296 297 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data); 298 299 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 300 AC_VERB_GET_GPIO_DATA, 0); 301 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); 302 303 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 304 AC_VERB_GET_GPIO_MASK, 0); 305 gpiomask |= mask; 306 307 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 308 AC_VERB_GET_GPIO_DIRECTION, 0); 309 gpiodir |= dir_mask; 310 311 /* Configure GPIOx as CMOS */ 312 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0); 313 314 snd_hda_codec_write(codec, codec->afg, 0, 315 AC_VERB_SET_GPIO_MASK, gpiomask); 316 snd_hda_codec_read(codec, codec->afg, 0, 317 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */ 318 319 msleep(1); 320 321 snd_hda_codec_read(codec, codec->afg, 0, 322 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ 323 } 324 325 /* hook for controlling mic-mute LED GPIO */ 326 static void stac_capture_led_hook(struct hda_codec *codec, 327 struct snd_ctl_elem_value *ucontrol) 328 { 329 struct sigmatel_spec *spec = codec->spec; 330 bool mute; 331 332 if (!ucontrol) 333 return; 334 335 mute = !(ucontrol->value.integer.value[0] || 336 ucontrol->value.integer.value[1]); 337 if (spec->mic_mute_led_on != mute) { 338 spec->mic_mute_led_on = mute; 339 if (mute) 340 spec->gpio_data |= spec->mic_mute_led_gpio; 341 else 342 spec->gpio_data &= ~spec->mic_mute_led_gpio; 343 stac_gpio_set(codec, spec->gpio_mask, 344 spec->gpio_dir, spec->gpio_data); 345 } 346 } 347 348 static int stac_vrefout_set(struct hda_codec *codec, 349 hda_nid_t nid, unsigned int new_vref) 350 { 351 int error, pinctl; 352 353 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref); 354 pinctl = snd_hda_codec_read(codec, nid, 0, 355 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 356 357 if (pinctl < 0) 358 return pinctl; 359 360 pinctl &= 0xff; 361 pinctl &= ~AC_PINCTL_VREFEN; 362 pinctl |= (new_vref & AC_PINCTL_VREFEN); 363 364 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl); 365 if (error < 0) 366 return error; 367 368 return 1; 369 } 370 371 /* update mute-LED accoring to the master switch */ 372 static void stac_update_led_status(struct hda_codec *codec, int enabled) 373 { 374 struct sigmatel_spec *spec = codec->spec; 375 int muted = !enabled; 376 377 if (!spec->gpio_led) 378 return; 379 380 /* LED state is inverted on these systems */ 381 if (spec->gpio_led_polarity) 382 muted = !muted; 383 384 if (!spec->vref_mute_led_nid) { 385 if (muted) 386 spec->gpio_data |= spec->gpio_led; 387 else 388 spec->gpio_data &= ~spec->gpio_led; 389 stac_gpio_set(codec, spec->gpio_mask, 390 spec->gpio_dir, spec->gpio_data); 391 } else { 392 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD; 393 stac_vrefout_set(codec, spec->vref_mute_led_nid, 394 spec->vref_led); 395 } 396 } 397 398 /* vmaster hook to update mute LED */ 399 static void stac_vmaster_hook(void *private_data, int val) 400 { 401 stac_update_led_status(private_data, val); 402 } 403 404 /* automute hook to handle GPIO mute and EAPD updates */ 405 static void stac_update_outputs(struct hda_codec *codec) 406 { 407 struct sigmatel_spec *spec = codec->spec; 408 409 if (spec->gpio_mute) 410 spec->gen.master_mute = 411 !(snd_hda_codec_read(codec, codec->afg, 0, 412 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute); 413 414 snd_hda_gen_update_outputs(codec); 415 416 if (spec->eapd_mask && spec->eapd_switch) { 417 unsigned int val = spec->gpio_data; 418 if (spec->gen.speaker_muted) 419 val &= ~spec->eapd_mask; 420 else 421 val |= spec->eapd_mask; 422 if (spec->gpio_data != val) { 423 spec->gpio_data = val; 424 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, 425 val); 426 } 427 } 428 } 429 430 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, 431 bool enable, bool do_write) 432 { 433 struct sigmatel_spec *spec = codec->spec; 434 unsigned int idx, val; 435 436 for (idx = 0; idx < spec->num_pwrs; idx++) { 437 if (spec->pwr_nids[idx] == nid) 438 break; 439 } 440 if (idx >= spec->num_pwrs) 441 return; 442 443 idx = 1 << idx; 444 445 val = spec->power_map_bits; 446 if (enable) 447 val &= ~idx; 448 else 449 val |= idx; 450 451 /* power down unused output ports */ 452 if (val != spec->power_map_bits) { 453 spec->power_map_bits = val; 454 if (do_write) 455 snd_hda_codec_write(codec, codec->afg, 0, 456 AC_VERB_IDT_SET_POWER_MAP, val); 457 } 458 } 459 460 /* update power bit per jack plug/unplug */ 461 static void jack_update_power(struct hda_codec *codec, 462 struct hda_jack_tbl *jack) 463 { 464 struct sigmatel_spec *spec = codec->spec; 465 int i; 466 467 if (!spec->num_pwrs) 468 return; 469 470 if (jack && jack->nid) { 471 stac_toggle_power_map(codec, jack->nid, 472 snd_hda_jack_detect(codec, jack->nid), 473 true); 474 return; 475 } 476 477 /* update all jacks */ 478 for (i = 0; i < spec->num_pwrs; i++) { 479 hda_nid_t nid = spec->pwr_nids[i]; 480 jack = snd_hda_jack_tbl_get(codec, nid); 481 if (!jack || !jack->action) 482 continue; 483 if (jack->action == STAC_PWR_EVENT || 484 jack->action <= HDA_GEN_LAST_EVENT) 485 stac_toggle_power_map(codec, nid, 486 snd_hda_jack_detect(codec, nid), 487 false); 488 } 489 490 snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_IDT_SET_POWER_MAP, 491 spec->power_map_bits); 492 } 493 494 static void stac_hp_automute(struct hda_codec *codec, 495 struct hda_jack_tbl *jack) 496 { 497 snd_hda_gen_hp_automute(codec, jack); 498 jack_update_power(codec, jack); 499 } 500 501 static void stac_line_automute(struct hda_codec *codec, 502 struct hda_jack_tbl *jack) 503 { 504 snd_hda_gen_line_automute(codec, jack); 505 jack_update_power(codec, jack); 506 } 507 508 static void stac_mic_autoswitch(struct hda_codec *codec, 509 struct hda_jack_tbl *jack) 510 { 511 snd_hda_gen_mic_autoswitch(codec, jack); 512 jack_update_power(codec, jack); 513 } 514 515 static void stac_vref_event(struct hda_codec *codec, struct hda_jack_tbl *event) 516 { 517 unsigned int data; 518 519 data = snd_hda_codec_read(codec, codec->afg, 0, 520 AC_VERB_GET_GPIO_DATA, 0); 521 /* toggle VREF state based on GPIOx status */ 522 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, 523 !!(data & (1 << event->private_data))); 524 } 525 526 /* initialize the power map and enable the power event to jacks that 527 * haven't been assigned to automute 528 */ 529 static void stac_init_power_map(struct hda_codec *codec) 530 { 531 struct sigmatel_spec *spec = codec->spec; 532 int i; 533 534 for (i = 0; i < spec->num_pwrs; i++) { 535 hda_nid_t nid = spec->pwr_nids[i]; 536 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); 537 def_conf = get_defcfg_connect(def_conf); 538 if (snd_hda_jack_tbl_get(codec, nid)) 539 continue; 540 if (def_conf == AC_JACK_PORT_COMPLEX && 541 !(spec->vref_mute_led_nid == nid || 542 is_jack_detectable(codec, nid))) { 543 snd_hda_jack_detect_enable_callback(codec, nid, 544 STAC_PWR_EVENT, 545 jack_update_power); 546 } else { 547 if (def_conf == AC_JACK_PORT_NONE) 548 stac_toggle_power_map(codec, nid, false, false); 549 else 550 stac_toggle_power_map(codec, nid, true, false); 551 } 552 } 553 } 554 555 /* 556 */ 557 558 static inline bool get_int_hint(struct hda_codec *codec, const char *key, 559 int *valp) 560 { 561 return !snd_hda_get_int_hint(codec, key, valp); 562 } 563 564 /* override some hints from the hwdep entry */ 565 static void stac_store_hints(struct hda_codec *codec) 566 { 567 struct sigmatel_spec *spec = codec->spec; 568 int val; 569 570 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) { 571 spec->eapd_mask = spec->gpio_dir = spec->gpio_data = 572 spec->gpio_mask; 573 } 574 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) 575 spec->gpio_mask &= spec->gpio_mask; 576 if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) 577 spec->gpio_dir &= spec->gpio_mask; 578 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) 579 spec->eapd_mask &= spec->gpio_mask; 580 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) 581 spec->gpio_mute &= spec->gpio_mask; 582 val = snd_hda_get_bool_hint(codec, "eapd_switch"); 583 if (val >= 0) 584 spec->eapd_switch = val; 585 } 586 587 /* 588 * loopback controls 589 */ 590 591 #define stac_aloopback_info snd_ctl_boolean_mono_info 592 593 static int stac_aloopback_get(struct snd_kcontrol *kcontrol, 594 struct snd_ctl_elem_value *ucontrol) 595 { 596 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 597 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 598 struct sigmatel_spec *spec = codec->spec; 599 600 ucontrol->value.integer.value[0] = !!(spec->aloopback & 601 (spec->aloopback_mask << idx)); 602 return 0; 603 } 604 605 static int stac_aloopback_put(struct snd_kcontrol *kcontrol, 606 struct snd_ctl_elem_value *ucontrol) 607 { 608 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 609 struct sigmatel_spec *spec = codec->spec; 610 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 611 unsigned int dac_mode; 612 unsigned int val, idx_val; 613 614 idx_val = spec->aloopback_mask << idx; 615 if (ucontrol->value.integer.value[0]) 616 val = spec->aloopback | idx_val; 617 else 618 val = spec->aloopback & ~idx_val; 619 if (spec->aloopback == val) 620 return 0; 621 622 spec->aloopback = val; 623 624 /* Only return the bits defined by the shift value of the 625 * first two bytes of the mask 626 */ 627 dac_mode = snd_hda_codec_read(codec, codec->afg, 0, 628 kcontrol->private_value & 0xFFFF, 0x0); 629 dac_mode >>= spec->aloopback_shift; 630 631 if (spec->aloopback & idx_val) { 632 snd_hda_power_up(codec); 633 dac_mode |= idx_val; 634 } else { 635 snd_hda_power_down(codec); 636 dac_mode &= ~idx_val; 637 } 638 639 snd_hda_codec_write_cache(codec, codec->afg, 0, 640 kcontrol->private_value >> 16, dac_mode); 641 642 return 1; 643 } 644 645 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ 646 { \ 647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 648 .name = "Analog Loopback", \ 649 .count = cnt, \ 650 .info = stac_aloopback_info, \ 651 .get = stac_aloopback_get, \ 652 .put = stac_aloopback_put, \ 653 .private_value = verb_read | (verb_write << 16), \ 654 } 655 656 /* 657 * Mute LED handling on HP laptops 658 */ 659 660 /* check whether it's a HP laptop with a docking port */ 661 static bool hp_bnb2011_with_dock(struct hda_codec *codec) 662 { 663 if (codec->vendor_id != 0x111d7605 && 664 codec->vendor_id != 0x111d76d1) 665 return false; 666 667 switch (codec->subsystem_id) { 668 case 0x103c1618: 669 case 0x103c1619: 670 case 0x103c161a: 671 case 0x103c161b: 672 case 0x103c161c: 673 case 0x103c161d: 674 case 0x103c161e: 675 case 0x103c161f: 676 677 case 0x103c162a: 678 case 0x103c162b: 679 680 case 0x103c1630: 681 case 0x103c1631: 682 683 case 0x103c1633: 684 case 0x103c1634: 685 case 0x103c1635: 686 687 case 0x103c3587: 688 case 0x103c3588: 689 case 0x103c3589: 690 case 0x103c358a: 691 692 case 0x103c3667: 693 case 0x103c3668: 694 case 0x103c3669: 695 696 return true; 697 } 698 return false; 699 } 700 701 static bool hp_blike_system(u32 subsystem_id) 702 { 703 switch (subsystem_id) { 704 case 0x103c1520: 705 case 0x103c1521: 706 case 0x103c1523: 707 case 0x103c1524: 708 case 0x103c1525: 709 case 0x103c1722: 710 case 0x103c1723: 711 case 0x103c1724: 712 case 0x103c1725: 713 case 0x103c1726: 714 case 0x103c1727: 715 case 0x103c1728: 716 case 0x103c1729: 717 case 0x103c172a: 718 case 0x103c172b: 719 case 0x103c307e: 720 case 0x103c307f: 721 case 0x103c3080: 722 case 0x103c3081: 723 case 0x103c7007: 724 case 0x103c7008: 725 return true; 726 } 727 return false; 728 } 729 730 static void set_hp_led_gpio(struct hda_codec *codec) 731 { 732 struct sigmatel_spec *spec = codec->spec; 733 unsigned int gpio; 734 735 if (spec->gpio_led) 736 return; 737 738 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); 739 gpio &= AC_GPIO_IO_COUNT; 740 if (gpio > 3) 741 spec->gpio_led = 0x08; /* GPIO 3 */ 742 else 743 spec->gpio_led = 0x01; /* GPIO 0 */ 744 } 745 746 /* 747 * This method searches for the mute LED GPIO configuration 748 * provided as OEM string in SMBIOS. The format of that string 749 * is HP_Mute_LED_P_G or HP_Mute_LED_P 750 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high) 751 * that corresponds to the NOT muted state of the master volume 752 * and G is the index of the GPIO to use as the mute LED control (0..9) 753 * If _G portion is missing it is assigned based on the codec ID 754 * 755 * So, HP B-series like systems may have HP_Mute_LED_0 (current models) 756 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings 757 * 758 * 759 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in 760 * SMBIOS - at least the ones I have seen do not have them - which include 761 * my own system (HP Pavilion dv6-1110ax) and my cousin's 762 * HP Pavilion dv9500t CTO. 763 * Need more information on whether it is true across the entire series. 764 * -- kunal 765 */ 766 static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) 767 { 768 struct sigmatel_spec *spec = codec->spec; 769 const struct dmi_device *dev = NULL; 770 771 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { 772 get_int_hint(codec, "gpio_led_polarity", 773 &spec->gpio_led_polarity); 774 return 1; 775 } 776 777 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { 778 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", 779 &spec->gpio_led_polarity, 780 &spec->gpio_led) == 2) { 781 unsigned int max_gpio; 782 max_gpio = snd_hda_param_read(codec, codec->afg, 783 AC_PAR_GPIO_CAP); 784 max_gpio &= AC_GPIO_IO_COUNT; 785 if (spec->gpio_led < max_gpio) 786 spec->gpio_led = 1 << spec->gpio_led; 787 else 788 spec->vref_mute_led_nid = spec->gpio_led; 789 return 1; 790 } 791 if (sscanf(dev->name, "HP_Mute_LED_%d", 792 &spec->gpio_led_polarity) == 1) { 793 set_hp_led_gpio(codec); 794 return 1; 795 } 796 /* BIOS bug: unfilled OEM string */ 797 if (strstr(dev->name, "HP_Mute_LED_P_G")) { 798 set_hp_led_gpio(codec); 799 if (default_polarity >= 0) 800 spec->gpio_led_polarity = default_polarity; 801 else 802 spec->gpio_led_polarity = 1; 803 return 1; 804 } 805 } 806 807 /* 808 * Fallback case - if we don't find the DMI strings, 809 * we statically set the GPIO - if not a B-series system 810 * and default polarity is provided 811 */ 812 if (!hp_blike_system(codec->subsystem_id) && 813 (default_polarity == 0 || default_polarity == 1)) { 814 set_hp_led_gpio(codec); 815 spec->gpio_led_polarity = default_polarity; 816 return 1; 817 } 818 return 0; 819 } 820 821 /* check whether a built-in speaker is included in parsed pins */ 822 static bool has_builtin_speaker(struct hda_codec *codec) 823 { 824 struct sigmatel_spec *spec = codec->spec; 825 hda_nid_t *nid_pin; 826 int nids, i; 827 828 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) { 829 nid_pin = spec->gen.autocfg.line_out_pins; 830 nids = spec->gen.autocfg.line_outs; 831 } else { 832 nid_pin = spec->gen.autocfg.speaker_pins; 833 nids = spec->gen.autocfg.speaker_outs; 834 } 835 836 for (i = 0; i < nids; i++) { 837 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]); 838 if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT) 839 return true; 840 } 841 return false; 842 } 843 844 /* 845 * PC beep controls 846 */ 847 848 /* create PC beep volume controls */ 849 static int stac_auto_create_beep_ctls(struct hda_codec *codec, 850 hda_nid_t nid) 851 { 852 struct sigmatel_spec *spec = codec->spec; 853 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); 854 struct snd_kcontrol_new *knew; 855 static struct snd_kcontrol_new abeep_mute_ctl = 856 HDA_CODEC_MUTE(NULL, 0, 0, 0); 857 static struct snd_kcontrol_new dbeep_mute_ctl = 858 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0); 859 static struct snd_kcontrol_new beep_vol_ctl = 860 HDA_CODEC_VOLUME(NULL, 0, 0, 0); 861 862 /* check for mute support for the the amp */ 863 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { 864 const struct snd_kcontrol_new *temp; 865 if (spec->anabeep_nid == nid) 866 temp = &abeep_mute_ctl; 867 else 868 temp = &dbeep_mute_ctl; 869 knew = snd_hda_gen_add_kctl(&spec->gen, 870 "Beep Playback Switch", temp); 871 if (!knew) 872 return -ENOMEM; 873 knew->private_value = 874 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT); 875 } 876 877 /* check to see if there is volume support for the amp */ 878 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { 879 knew = snd_hda_gen_add_kctl(&spec->gen, 880 "Beep Playback Volume", 881 &beep_vol_ctl); 882 if (!knew) 883 return -ENOMEM; 884 knew->private_value = 885 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT); 886 } 887 return 0; 888 } 889 890 #ifdef CONFIG_SND_HDA_INPUT_BEEP 891 #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info 892 893 static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol, 894 struct snd_ctl_elem_value *ucontrol) 895 { 896 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 897 ucontrol->value.integer.value[0] = codec->beep->enabled; 898 return 0; 899 } 900 901 static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol, 902 struct snd_ctl_elem_value *ucontrol) 903 { 904 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 905 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); 906 } 907 908 static const struct snd_kcontrol_new stac_dig_beep_ctrl = { 909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 910 .name = "Beep Playback Switch", 911 .info = stac_dig_beep_switch_info, 912 .get = stac_dig_beep_switch_get, 913 .put = stac_dig_beep_switch_put, 914 }; 915 916 static int stac_beep_switch_ctl(struct hda_codec *codec) 917 { 918 struct sigmatel_spec *spec = codec->spec; 919 920 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl)) 921 return -ENOMEM; 922 return 0; 923 } 924 #endif 925 926 /* 927 * SPDIF-out mux controls 928 */ 929 930 static int stac_smux_enum_info(struct snd_kcontrol *kcontrol, 931 struct snd_ctl_elem_info *uinfo) 932 { 933 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 934 struct sigmatel_spec *spec = codec->spec; 935 return snd_hda_input_mux_info(&spec->spdif_mux, uinfo); 936 } 937 938 static int stac_smux_enum_get(struct snd_kcontrol *kcontrol, 939 struct snd_ctl_elem_value *ucontrol) 940 { 941 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 942 struct sigmatel_spec *spec = codec->spec; 943 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 944 945 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; 946 return 0; 947 } 948 949 static int stac_smux_enum_put(struct snd_kcontrol *kcontrol, 950 struct snd_ctl_elem_value *ucontrol) 951 { 952 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 953 struct sigmatel_spec *spec = codec->spec; 954 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 955 956 return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol, 957 spec->gen.autocfg.dig_out_pins[smux_idx], 958 &spec->cur_smux[smux_idx]); 959 } 960 961 static struct snd_kcontrol_new stac_smux_mixer = { 962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 963 .name = "IEC958 Playback Source", 964 /* count set later */ 965 .info = stac_smux_enum_info, 966 .get = stac_smux_enum_get, 967 .put = stac_smux_enum_put, 968 }; 969 970 static const char * const stac_spdif_labels[] = { 971 "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL 972 }; 973 974 static int stac_create_spdif_mux_ctls(struct hda_codec *codec) 975 { 976 struct sigmatel_spec *spec = codec->spec; 977 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 978 const char * const *labels = spec->spdif_labels; 979 struct snd_kcontrol_new *kctl; 980 int i, num_cons; 981 982 if (cfg->dig_outs < 1) 983 return 0; 984 985 num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]); 986 if (num_cons <= 1) 987 return 0; 988 989 if (!labels) 990 labels = stac_spdif_labels; 991 for (i = 0; i < num_cons; i++) { 992 if (snd_BUG_ON(!labels[i])) 993 return -EINVAL; 994 snd_hda_add_imux_item(&spec->spdif_mux, labels[i], i, NULL); 995 } 996 997 kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer); 998 if (!kctl) 999 return -ENOMEM; 1000 kctl->count = cfg->dig_outs; 1001 1002 return 0; 1003 } 1004 1005 /* 1006 */ 1007 1008 static const struct hda_verb stac9200_core_init[] = { 1009 /* set dac0mux for dac converter */ 1010 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1011 {} 1012 }; 1013 1014 static const struct hda_verb stac9200_eapd_init[] = { 1015 /* set dac0mux for dac converter */ 1016 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 1017 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 1018 {} 1019 }; 1020 1021 static const struct hda_verb dell_eq_core_init[] = { 1022 /* set master volume to max value without distortion 1023 * and direct control */ 1024 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 1025 {} 1026 }; 1027 1028 static const struct hda_verb stac92hd73xx_core_init[] = { 1029 /* set master volume and direct control */ 1030 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 1031 {} 1032 }; 1033 1034 static const struct hda_verb stac92hd83xxx_core_init[] = { 1035 /* power state controls amps */ 1036 { 0x01, AC_VERB_SET_EAPD, 1 << 2}, 1037 {} 1038 }; 1039 1040 static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = { 1041 { 0x22, 0x785, 0x43 }, 1042 { 0x22, 0x782, 0xe0 }, 1043 { 0x22, 0x795, 0x00 }, 1044 {} 1045 }; 1046 1047 static const struct hda_verb stac92hd71bxx_core_init[] = { 1048 /* set master volume and direct control */ 1049 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 1050 {} 1051 }; 1052 1053 static const struct hda_verb stac92hd71bxx_unmute_core_init[] = { 1054 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ 1055 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1056 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1057 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1058 {} 1059 }; 1060 1061 static const struct hda_verb stac925x_core_init[] = { 1062 /* set dac0mux for dac converter */ 1063 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, 1064 /* mute the master volume */ 1065 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1066 {} 1067 }; 1068 1069 static const struct hda_verb stac922x_core_init[] = { 1070 /* set master volume and direct control */ 1071 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 1072 {} 1073 }; 1074 1075 static const struct hda_verb d965_core_init[] = { 1076 /* unmute node 0x1b */ 1077 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1078 /* select node 0x03 as DAC */ 1079 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, 1080 {} 1081 }; 1082 1083 static const struct hda_verb dell_3st_core_init[] = { 1084 /* don't set delta bit */ 1085 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, 1086 /* unmute node 0x1b */ 1087 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1088 /* select node 0x03 as DAC */ 1089 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, 1090 {} 1091 }; 1092 1093 static const struct hda_verb stac927x_core_init[] = { 1094 /* set master volume and direct control */ 1095 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 1096 /* enable analog pc beep path */ 1097 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, 1098 {} 1099 }; 1100 1101 static const struct hda_verb stac927x_volknob_core_init[] = { 1102 /* don't set delta bit */ 1103 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, 1104 /* enable analog pc beep path */ 1105 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, 1106 {} 1107 }; 1108 1109 static const struct hda_verb stac9205_core_init[] = { 1110 /* set master volume and direct control */ 1111 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 1112 /* enable analog pc beep path */ 1113 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, 1114 {} 1115 }; 1116 1117 static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback = 1118 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3); 1119 1120 static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback = 1121 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4); 1122 1123 static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback = 1124 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5); 1125 1126 static const struct snd_kcontrol_new stac92hd71bxx_loopback = 1127 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2); 1128 1129 static const struct snd_kcontrol_new stac9205_loopback = 1130 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1); 1131 1132 static const struct snd_kcontrol_new stac927x_loopback = 1133 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1); 1134 1135 static const struct hda_pintbl ref9200_pin_configs[] = { 1136 { 0x08, 0x01c47010 }, 1137 { 0x09, 0x01447010 }, 1138 { 0x0d, 0x0221401f }, 1139 { 0x0e, 0x01114010 }, 1140 { 0x0f, 0x02a19020 }, 1141 { 0x10, 0x01a19021 }, 1142 { 0x11, 0x90100140 }, 1143 { 0x12, 0x01813122 }, 1144 {} 1145 }; 1146 1147 static const struct hda_pintbl gateway9200_m4_pin_configs[] = { 1148 { 0x08, 0x400000fe }, 1149 { 0x09, 0x404500f4 }, 1150 { 0x0d, 0x400100f0 }, 1151 { 0x0e, 0x90110010 }, 1152 { 0x0f, 0x400100f1 }, 1153 { 0x10, 0x02a1902e }, 1154 { 0x11, 0x500000f2 }, 1155 { 0x12, 0x500000f3 }, 1156 {} 1157 }; 1158 1159 static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = { 1160 { 0x08, 0x400000fe }, 1161 { 0x09, 0x404500f4 }, 1162 { 0x0d, 0x400100f0 }, 1163 { 0x0e, 0x90110010 }, 1164 { 0x0f, 0x400100f1 }, 1165 { 0x10, 0x02a1902e }, 1166 { 0x11, 0x500000f2 }, 1167 { 0x12, 0x500000f3 }, 1168 {} 1169 }; 1170 1171 /* 1172 STAC 9200 pin configs for 1173 102801A8 1174 102801DE 1175 102801E8 1176 */ 1177 static const struct hda_pintbl dell9200_d21_pin_configs[] = { 1178 { 0x08, 0x400001f0 }, 1179 { 0x09, 0x400001f1 }, 1180 { 0x0d, 0x02214030 }, 1181 { 0x0e, 0x01014010 }, 1182 { 0x0f, 0x02a19020 }, 1183 { 0x10, 0x01a19021 }, 1184 { 0x11, 0x90100140 }, 1185 { 0x12, 0x01813122 }, 1186 {} 1187 }; 1188 1189 /* 1190 STAC 9200 pin configs for 1191 102801C0 1192 102801C1 1193 */ 1194 static const struct hda_pintbl dell9200_d22_pin_configs[] = { 1195 { 0x08, 0x400001f0 }, 1196 { 0x09, 0x400001f1 }, 1197 { 0x0d, 0x0221401f }, 1198 { 0x0e, 0x01014010 }, 1199 { 0x0f, 0x01813020 }, 1200 { 0x10, 0x02a19021 }, 1201 { 0x11, 0x90100140 }, 1202 { 0x12, 0x400001f2 }, 1203 {} 1204 }; 1205 1206 /* 1207 STAC 9200 pin configs for 1208 102801C4 (Dell Dimension E310) 1209 102801C5 1210 102801C7 1211 102801D9 1212 102801DA 1213 102801E3 1214 */ 1215 static const struct hda_pintbl dell9200_d23_pin_configs[] = { 1216 { 0x08, 0x400001f0 }, 1217 { 0x09, 0x400001f1 }, 1218 { 0x0d, 0x0221401f }, 1219 { 0x0e, 0x01014010 }, 1220 { 0x0f, 0x01813020 }, 1221 { 0x10, 0x01a19021 }, 1222 { 0x11, 0x90100140 }, 1223 { 0x12, 0x400001f2 }, 1224 {} 1225 }; 1226 1227 1228 /* 1229 STAC 9200-32 pin configs for 1230 102801B5 (Dell Inspiron 630m) 1231 102801D8 (Dell Inspiron 640m) 1232 */ 1233 static const struct hda_pintbl dell9200_m21_pin_configs[] = { 1234 { 0x08, 0x40c003fa }, 1235 { 0x09, 0x03441340 }, 1236 { 0x0d, 0x0321121f }, 1237 { 0x0e, 0x90170310 }, 1238 { 0x0f, 0x408003fb }, 1239 { 0x10, 0x03a11020 }, 1240 { 0x11, 0x401003fc }, 1241 { 0x12, 0x403003fd }, 1242 {} 1243 }; 1244 1245 /* 1246 STAC 9200-32 pin configs for 1247 102801C2 (Dell Latitude D620) 1248 102801C8 1249 102801CC (Dell Latitude D820) 1250 102801D4 1251 102801D6 1252 */ 1253 static const struct hda_pintbl dell9200_m22_pin_configs[] = { 1254 { 0x08, 0x40c003fa }, 1255 { 0x09, 0x0144131f }, 1256 { 0x0d, 0x0321121f }, 1257 { 0x0e, 0x90170310 }, 1258 { 0x0f, 0x90a70321 }, 1259 { 0x10, 0x03a11020 }, 1260 { 0x11, 0x401003fb }, 1261 { 0x12, 0x40f000fc }, 1262 {} 1263 }; 1264 1265 /* 1266 STAC 9200-32 pin configs for 1267 102801CE (Dell XPS M1710) 1268 102801CF (Dell Precision M90) 1269 */ 1270 static const struct hda_pintbl dell9200_m23_pin_configs[] = { 1271 { 0x08, 0x40c003fa }, 1272 { 0x09, 0x01441340 }, 1273 { 0x0d, 0x0421421f }, 1274 { 0x0e, 0x90170310 }, 1275 { 0x0f, 0x408003fb }, 1276 { 0x10, 0x04a1102e }, 1277 { 0x11, 0x90170311 }, 1278 { 0x12, 0x403003fc }, 1279 {} 1280 }; 1281 1282 /* 1283 STAC 9200-32 pin configs for 1284 102801C9 1285 102801CA 1286 102801CB (Dell Latitude 120L) 1287 102801D3 1288 */ 1289 static const struct hda_pintbl dell9200_m24_pin_configs[] = { 1290 { 0x08, 0x40c003fa }, 1291 { 0x09, 0x404003fb }, 1292 { 0x0d, 0x0321121f }, 1293 { 0x0e, 0x90170310 }, 1294 { 0x0f, 0x408003fc }, 1295 { 0x10, 0x03a11020 }, 1296 { 0x11, 0x401003fd }, 1297 { 0x12, 0x403003fe }, 1298 {} 1299 }; 1300 1301 /* 1302 STAC 9200-32 pin configs for 1303 102801BD (Dell Inspiron E1505n) 1304 102801EE 1305 102801EF 1306 */ 1307 static const struct hda_pintbl dell9200_m25_pin_configs[] = { 1308 { 0x08, 0x40c003fa }, 1309 { 0x09, 0x01441340 }, 1310 { 0x0d, 0x0421121f }, 1311 { 0x0e, 0x90170310 }, 1312 { 0x0f, 0x408003fb }, 1313 { 0x10, 0x04a11020 }, 1314 { 0x11, 0x401003fc }, 1315 { 0x12, 0x403003fd }, 1316 {} 1317 }; 1318 1319 /* 1320 STAC 9200-32 pin configs for 1321 102801F5 (Dell Inspiron 1501) 1322 102801F6 1323 */ 1324 static const struct hda_pintbl dell9200_m26_pin_configs[] = { 1325 { 0x08, 0x40c003fa }, 1326 { 0x09, 0x404003fb }, 1327 { 0x0d, 0x0421121f }, 1328 { 0x0e, 0x90170310 }, 1329 { 0x0f, 0x408003fc }, 1330 { 0x10, 0x04a11020 }, 1331 { 0x11, 0x401003fd }, 1332 { 0x12, 0x403003fe }, 1333 {} 1334 }; 1335 1336 /* 1337 STAC 9200-32 1338 102801CD (Dell Inspiron E1705/9400) 1339 */ 1340 static const struct hda_pintbl dell9200_m27_pin_configs[] = { 1341 { 0x08, 0x40c003fa }, 1342 { 0x09, 0x01441340 }, 1343 { 0x0d, 0x0421121f }, 1344 { 0x0e, 0x90170310 }, 1345 { 0x0f, 0x90170310 }, 1346 { 0x10, 0x04a11020 }, 1347 { 0x11, 0x90170310 }, 1348 { 0x12, 0x40f003fc }, 1349 {} 1350 }; 1351 1352 static const struct hda_pintbl oqo9200_pin_configs[] = { 1353 { 0x08, 0x40c000f0 }, 1354 { 0x09, 0x404000f1 }, 1355 { 0x0d, 0x0221121f }, 1356 { 0x0e, 0x02211210 }, 1357 { 0x0f, 0x90170111 }, 1358 { 0x10, 0x90a70120 }, 1359 { 0x11, 0x400000f2 }, 1360 { 0x12, 0x400000f3 }, 1361 {} 1362 }; 1363 1364 1365 static void stac9200_fixup_panasonic(struct hda_codec *codec, 1366 const struct hda_fixup *fix, int action) 1367 { 1368 struct sigmatel_spec *spec = codec->spec; 1369 1370 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1371 spec->gpio_mask = spec->gpio_dir = 0x09; 1372 spec->gpio_data = 0x00; 1373 /* CF-74 has no headphone detection, and the driver should *NOT* 1374 * do detection and HP/speaker toggle because the hardware does it. 1375 */ 1376 spec->gen.suppress_auto_mute = 1; 1377 } 1378 } 1379 1380 1381 static const struct hda_fixup stac9200_fixups[] = { 1382 [STAC_REF] = { 1383 .type = HDA_FIXUP_PINS, 1384 .v.pins = ref9200_pin_configs, 1385 }, 1386 [STAC_9200_OQO] = { 1387 .type = HDA_FIXUP_PINS, 1388 .v.pins = oqo9200_pin_configs, 1389 .chained = true, 1390 .chain_id = STAC_9200_EAPD_INIT, 1391 }, 1392 [STAC_9200_DELL_D21] = { 1393 .type = HDA_FIXUP_PINS, 1394 .v.pins = dell9200_d21_pin_configs, 1395 }, 1396 [STAC_9200_DELL_D22] = { 1397 .type = HDA_FIXUP_PINS, 1398 .v.pins = dell9200_d22_pin_configs, 1399 }, 1400 [STAC_9200_DELL_D23] = { 1401 .type = HDA_FIXUP_PINS, 1402 .v.pins = dell9200_d23_pin_configs, 1403 }, 1404 [STAC_9200_DELL_M21] = { 1405 .type = HDA_FIXUP_PINS, 1406 .v.pins = dell9200_m21_pin_configs, 1407 }, 1408 [STAC_9200_DELL_M22] = { 1409 .type = HDA_FIXUP_PINS, 1410 .v.pins = dell9200_m22_pin_configs, 1411 }, 1412 [STAC_9200_DELL_M23] = { 1413 .type = HDA_FIXUP_PINS, 1414 .v.pins = dell9200_m23_pin_configs, 1415 }, 1416 [STAC_9200_DELL_M24] = { 1417 .type = HDA_FIXUP_PINS, 1418 .v.pins = dell9200_m24_pin_configs, 1419 }, 1420 [STAC_9200_DELL_M25] = { 1421 .type = HDA_FIXUP_PINS, 1422 .v.pins = dell9200_m25_pin_configs, 1423 }, 1424 [STAC_9200_DELL_M26] = { 1425 .type = HDA_FIXUP_PINS, 1426 .v.pins = dell9200_m26_pin_configs, 1427 }, 1428 [STAC_9200_DELL_M27] = { 1429 .type = HDA_FIXUP_PINS, 1430 .v.pins = dell9200_m27_pin_configs, 1431 }, 1432 [STAC_9200_M4] = { 1433 .type = HDA_FIXUP_PINS, 1434 .v.pins = gateway9200_m4_pin_configs, 1435 .chained = true, 1436 .chain_id = STAC_9200_EAPD_INIT, 1437 }, 1438 [STAC_9200_M4_2] = { 1439 .type = HDA_FIXUP_PINS, 1440 .v.pins = gateway9200_m4_2_pin_configs, 1441 .chained = true, 1442 .chain_id = STAC_9200_EAPD_INIT, 1443 }, 1444 [STAC_9200_PANASONIC] = { 1445 .type = HDA_FIXUP_FUNC, 1446 .v.func = stac9200_fixup_panasonic, 1447 }, 1448 [STAC_9200_EAPD_INIT] = { 1449 .type = HDA_FIXUP_VERBS, 1450 .v.verbs = (const struct hda_verb[]) { 1451 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 1452 {} 1453 }, 1454 }, 1455 }; 1456 1457 static const struct hda_model_fixup stac9200_models[] = { 1458 { .id = STAC_REF, .name = "ref" }, 1459 { .id = STAC_9200_OQO, .name = "oqo" }, 1460 { .id = STAC_9200_DELL_D21, .name = "dell-d21" }, 1461 { .id = STAC_9200_DELL_D22, .name = "dell-d22" }, 1462 { .id = STAC_9200_DELL_D23, .name = "dell-d23" }, 1463 { .id = STAC_9200_DELL_M21, .name = "dell-m21" }, 1464 { .id = STAC_9200_DELL_M22, .name = "dell-m22" }, 1465 { .id = STAC_9200_DELL_M23, .name = "dell-m23" }, 1466 { .id = STAC_9200_DELL_M24, .name = "dell-m24" }, 1467 { .id = STAC_9200_DELL_M25, .name = "dell-m25" }, 1468 { .id = STAC_9200_DELL_M26, .name = "dell-m26" }, 1469 { .id = STAC_9200_DELL_M27, .name = "dell-m27" }, 1470 { .id = STAC_9200_M4, .name = "gateway-m4" }, 1471 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" }, 1472 { .id = STAC_9200_PANASONIC, .name = "panasonic" }, 1473 {} 1474 }; 1475 1476 static const struct snd_pci_quirk stac9200_fixup_tbl[] = { 1477 /* SigmaTel reference board */ 1478 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1479 "DFI LanParty", STAC_REF), 1480 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 1481 "DFI LanParty", STAC_REF), 1482 /* Dell laptops have BIOS problem */ 1483 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, 1484 "unknown Dell", STAC_9200_DELL_D21), 1485 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5, 1486 "Dell Inspiron 630m", STAC_9200_DELL_M21), 1487 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd, 1488 "Dell Inspiron E1505n", STAC_9200_DELL_M25), 1489 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0, 1490 "unknown Dell", STAC_9200_DELL_D22), 1491 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1, 1492 "unknown Dell", STAC_9200_DELL_D22), 1493 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2, 1494 "Dell Latitude D620", STAC_9200_DELL_M22), 1495 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5, 1496 "unknown Dell", STAC_9200_DELL_D23), 1497 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7, 1498 "unknown Dell", STAC_9200_DELL_D23), 1499 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8, 1500 "unknown Dell", STAC_9200_DELL_M22), 1501 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9, 1502 "unknown Dell", STAC_9200_DELL_M24), 1503 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca, 1504 "unknown Dell", STAC_9200_DELL_M24), 1505 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb, 1506 "Dell Latitude 120L", STAC_9200_DELL_M24), 1507 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc, 1508 "Dell Latitude D820", STAC_9200_DELL_M22), 1509 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd, 1510 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27), 1511 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce, 1512 "Dell XPS M1710", STAC_9200_DELL_M23), 1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf, 1514 "Dell Precision M90", STAC_9200_DELL_M23), 1515 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3, 1516 "unknown Dell", STAC_9200_DELL_M22), 1517 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4, 1518 "unknown Dell", STAC_9200_DELL_M22), 1519 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6, 1520 "unknown Dell", STAC_9200_DELL_M22), 1521 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8, 1522 "Dell Inspiron 640m", STAC_9200_DELL_M21), 1523 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9, 1524 "unknown Dell", STAC_9200_DELL_D23), 1525 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da, 1526 "unknown Dell", STAC_9200_DELL_D23), 1527 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de, 1528 "unknown Dell", STAC_9200_DELL_D21), 1529 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3, 1530 "unknown Dell", STAC_9200_DELL_D23), 1531 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8, 1532 "unknown Dell", STAC_9200_DELL_D21), 1533 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee, 1534 "unknown Dell", STAC_9200_DELL_M25), 1535 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef, 1536 "unknown Dell", STAC_9200_DELL_M25), 1537 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5, 1538 "Dell Inspiron 1501", STAC_9200_DELL_M26), 1539 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, 1540 "unknown Dell", STAC_9200_DELL_M26), 1541 /* Panasonic */ 1542 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), 1543 /* Gateway machines needs EAPD to be set on resume */ 1544 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), 1545 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), 1546 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), 1547 /* OQO Mobile */ 1548 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), 1549 {} /* terminator */ 1550 }; 1551 1552 static const struct hda_pintbl ref925x_pin_configs[] = { 1553 { 0x07, 0x40c003f0 }, 1554 { 0x08, 0x424503f2 }, 1555 { 0x0a, 0x01813022 }, 1556 { 0x0b, 0x02a19021 }, 1557 { 0x0c, 0x90a70320 }, 1558 { 0x0d, 0x02214210 }, 1559 { 0x10, 0x01019020 }, 1560 { 0x11, 0x9033032e }, 1561 {} 1562 }; 1563 1564 static const struct hda_pintbl stac925xM1_pin_configs[] = { 1565 { 0x07, 0x40c003f4 }, 1566 { 0x08, 0x424503f2 }, 1567 { 0x0a, 0x400000f3 }, 1568 { 0x0b, 0x02a19020 }, 1569 { 0x0c, 0x40a000f0 }, 1570 { 0x0d, 0x90100210 }, 1571 { 0x10, 0x400003f1 }, 1572 { 0x11, 0x9033032e }, 1573 {} 1574 }; 1575 1576 static const struct hda_pintbl stac925xM1_2_pin_configs[] = { 1577 { 0x07, 0x40c003f4 }, 1578 { 0x08, 0x424503f2 }, 1579 { 0x0a, 0x400000f3 }, 1580 { 0x0b, 0x02a19020 }, 1581 { 0x0c, 0x40a000f0 }, 1582 { 0x0d, 0x90100210 }, 1583 { 0x10, 0x400003f1 }, 1584 { 0x11, 0x9033032e }, 1585 {} 1586 }; 1587 1588 static const struct hda_pintbl stac925xM2_pin_configs[] = { 1589 { 0x07, 0x40c003f4 }, 1590 { 0x08, 0x424503f2 }, 1591 { 0x0a, 0x400000f3 }, 1592 { 0x0b, 0x02a19020 }, 1593 { 0x0c, 0x40a000f0 }, 1594 { 0x0d, 0x90100210 }, 1595 { 0x10, 0x400003f1 }, 1596 { 0x11, 0x9033032e }, 1597 {} 1598 }; 1599 1600 static const struct hda_pintbl stac925xM2_2_pin_configs[] = { 1601 { 0x07, 0x40c003f4 }, 1602 { 0x08, 0x424503f2 }, 1603 { 0x0a, 0x400000f3 }, 1604 { 0x0b, 0x02a19020 }, 1605 { 0x0c, 0x40a000f0 }, 1606 { 0x0d, 0x90100210 }, 1607 { 0x10, 0x400003f1 }, 1608 { 0x11, 0x9033032e }, 1609 {} 1610 }; 1611 1612 static const struct hda_pintbl stac925xM3_pin_configs[] = { 1613 { 0x07, 0x40c003f4 }, 1614 { 0x08, 0x424503f2 }, 1615 { 0x0a, 0x400000f3 }, 1616 { 0x0b, 0x02a19020 }, 1617 { 0x0c, 0x40a000f0 }, 1618 { 0x0d, 0x90100210 }, 1619 { 0x10, 0x400003f1 }, 1620 { 0x11, 0x503303f3 }, 1621 {} 1622 }; 1623 1624 static const struct hda_pintbl stac925xM5_pin_configs[] = { 1625 { 0x07, 0x40c003f4 }, 1626 { 0x08, 0x424503f2 }, 1627 { 0x0a, 0x400000f3 }, 1628 { 0x0b, 0x02a19020 }, 1629 { 0x0c, 0x40a000f0 }, 1630 { 0x0d, 0x90100210 }, 1631 { 0x10, 0x400003f1 }, 1632 { 0x11, 0x9033032e }, 1633 {} 1634 }; 1635 1636 static const struct hda_pintbl stac925xM6_pin_configs[] = { 1637 { 0x07, 0x40c003f4 }, 1638 { 0x08, 0x424503f2 }, 1639 { 0x0a, 0x400000f3 }, 1640 { 0x0b, 0x02a19020 }, 1641 { 0x0c, 0x40a000f0 }, 1642 { 0x0d, 0x90100210 }, 1643 { 0x10, 0x400003f1 }, 1644 { 0x11, 0x90330320 }, 1645 {} 1646 }; 1647 1648 static const struct hda_fixup stac925x_fixups[] = { 1649 [STAC_REF] = { 1650 .type = HDA_FIXUP_PINS, 1651 .v.pins = ref925x_pin_configs, 1652 }, 1653 [STAC_M1] = { 1654 .type = HDA_FIXUP_PINS, 1655 .v.pins = stac925xM1_pin_configs, 1656 }, 1657 [STAC_M1_2] = { 1658 .type = HDA_FIXUP_PINS, 1659 .v.pins = stac925xM1_2_pin_configs, 1660 }, 1661 [STAC_M2] = { 1662 .type = HDA_FIXUP_PINS, 1663 .v.pins = stac925xM2_pin_configs, 1664 }, 1665 [STAC_M2_2] = { 1666 .type = HDA_FIXUP_PINS, 1667 .v.pins = stac925xM2_2_pin_configs, 1668 }, 1669 [STAC_M3] = { 1670 .type = HDA_FIXUP_PINS, 1671 .v.pins = stac925xM3_pin_configs, 1672 }, 1673 [STAC_M5] = { 1674 .type = HDA_FIXUP_PINS, 1675 .v.pins = stac925xM5_pin_configs, 1676 }, 1677 [STAC_M6] = { 1678 .type = HDA_FIXUP_PINS, 1679 .v.pins = stac925xM6_pin_configs, 1680 }, 1681 }; 1682 1683 static const struct hda_model_fixup stac925x_models[] = { 1684 { .id = STAC_REF, .name = "ref" }, 1685 { .id = STAC_M1, .name = "m1" }, 1686 { .id = STAC_M1_2, .name = "m1-2" }, 1687 { .id = STAC_M2, .name = "m2" }, 1688 { .id = STAC_M2_2, .name = "m2-2" }, 1689 { .id = STAC_M3, .name = "m3" }, 1690 { .id = STAC_M5, .name = "m5" }, 1691 { .id = STAC_M6, .name = "m6" }, 1692 {} 1693 }; 1694 1695 static const struct snd_pci_quirk stac925x_fixup_tbl[] = { 1696 /* SigmaTel reference board */ 1697 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), 1698 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), 1699 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), 1700 1701 /* Default table for unknown ID */ 1702 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), 1703 1704 /* gateway machines are checked via codec ssid */ 1705 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), 1706 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), 1707 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), 1708 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2), 1709 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), 1710 /* Not sure about the brand name for those */ 1711 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), 1712 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), 1713 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), 1714 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), 1715 {} /* terminator */ 1716 }; 1717 1718 static const struct hda_pintbl ref92hd73xx_pin_configs[] = { 1719 { 0x0a, 0x02214030 }, 1720 { 0x0b, 0x02a19040 }, 1721 { 0x0c, 0x01a19020 }, 1722 { 0x0d, 0x02214030 }, 1723 { 0x0e, 0x0181302e }, 1724 { 0x0f, 0x01014010 }, 1725 { 0x10, 0x01014020 }, 1726 { 0x11, 0x01014030 }, 1727 { 0x12, 0x02319040 }, 1728 { 0x13, 0x90a000f0 }, 1729 { 0x14, 0x90a000f0 }, 1730 { 0x22, 0x01452050 }, 1731 { 0x23, 0x01452050 }, 1732 {} 1733 }; 1734 1735 static const struct hda_pintbl dell_m6_pin_configs[] = { 1736 { 0x0a, 0x0321101f }, 1737 { 0x0b, 0x4f00000f }, 1738 { 0x0c, 0x4f0000f0 }, 1739 { 0x0d, 0x90170110 }, 1740 { 0x0e, 0x03a11020 }, 1741 { 0x0f, 0x0321101f }, 1742 { 0x10, 0x4f0000f0 }, 1743 { 0x11, 0x4f0000f0 }, 1744 { 0x12, 0x4f0000f0 }, 1745 { 0x13, 0x90a60160 }, 1746 { 0x14, 0x4f0000f0 }, 1747 { 0x22, 0x4f0000f0 }, 1748 { 0x23, 0x4f0000f0 }, 1749 {} 1750 }; 1751 1752 static const struct hda_pintbl alienware_m17x_pin_configs[] = { 1753 { 0x0a, 0x0321101f }, 1754 { 0x0b, 0x0321101f }, 1755 { 0x0c, 0x03a11020 }, 1756 { 0x0d, 0x03014020 }, 1757 { 0x0e, 0x90170110 }, 1758 { 0x0f, 0x4f0000f0 }, 1759 { 0x10, 0x4f0000f0 }, 1760 { 0x11, 0x4f0000f0 }, 1761 { 0x12, 0x4f0000f0 }, 1762 { 0x13, 0x90a60160 }, 1763 { 0x14, 0x4f0000f0 }, 1764 { 0x22, 0x4f0000f0 }, 1765 { 0x23, 0x904601b0 }, 1766 {} 1767 }; 1768 1769 static const struct hda_pintbl intel_dg45id_pin_configs[] = { 1770 { 0x0a, 0x02214230 }, 1771 { 0x0b, 0x02A19240 }, 1772 { 0x0c, 0x01013214 }, 1773 { 0x0d, 0x01014210 }, 1774 { 0x0e, 0x01A19250 }, 1775 { 0x0f, 0x01011212 }, 1776 { 0x10, 0x01016211 }, 1777 {} 1778 }; 1779 1780 static void stac92hd73xx_fixup_ref(struct hda_codec *codec, 1781 const struct hda_fixup *fix, int action) 1782 { 1783 struct sigmatel_spec *spec = codec->spec; 1784 1785 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1786 return; 1787 1788 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs); 1789 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0; 1790 } 1791 1792 static void stac92hd73xx_fixup_dell(struct hda_codec *codec) 1793 { 1794 struct sigmatel_spec *spec = codec->spec; 1795 1796 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs); 1797 spec->eapd_switch = 0; 1798 } 1799 1800 static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec, 1801 const struct hda_fixup *fix, int action) 1802 { 1803 struct sigmatel_spec *spec = codec->spec; 1804 1805 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1806 return; 1807 1808 stac92hd73xx_fixup_dell(codec); 1809 snd_hda_add_verbs(codec, dell_eq_core_init); 1810 spec->volknob_init = 1; 1811 } 1812 1813 /* Analog Mics */ 1814 static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec, 1815 const struct hda_fixup *fix, int action) 1816 { 1817 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1818 return; 1819 1820 stac92hd73xx_fixup_dell(codec); 1821 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); 1822 } 1823 1824 /* Digital Mics */ 1825 static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec, 1826 const struct hda_fixup *fix, int action) 1827 { 1828 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1829 return; 1830 1831 stac92hd73xx_fixup_dell(codec); 1832 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); 1833 } 1834 1835 /* Both */ 1836 static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec, 1837 const struct hda_fixup *fix, int action) 1838 { 1839 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1840 return; 1841 1842 stac92hd73xx_fixup_dell(codec); 1843 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); 1844 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); 1845 } 1846 1847 static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec, 1848 const struct hda_fixup *fix, int action) 1849 { 1850 struct sigmatel_spec *spec = codec->spec; 1851 1852 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1853 return; 1854 1855 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs); 1856 spec->eapd_switch = 0; 1857 } 1858 1859 static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec, 1860 const struct hda_fixup *fix, int action) 1861 { 1862 if (action == HDA_FIXUP_ACT_PRE_PROBE) 1863 codec->no_jack_detect = 1; 1864 } 1865 1866 static const struct hda_fixup stac92hd73xx_fixups[] = { 1867 [STAC_92HD73XX_REF] = { 1868 .type = HDA_FIXUP_FUNC, 1869 .v.func = stac92hd73xx_fixup_ref, 1870 }, 1871 [STAC_DELL_M6_AMIC] = { 1872 .type = HDA_FIXUP_FUNC, 1873 .v.func = stac92hd73xx_fixup_dell_m6_amic, 1874 }, 1875 [STAC_DELL_M6_DMIC] = { 1876 .type = HDA_FIXUP_FUNC, 1877 .v.func = stac92hd73xx_fixup_dell_m6_dmic, 1878 }, 1879 [STAC_DELL_M6_BOTH] = { 1880 .type = HDA_FIXUP_FUNC, 1881 .v.func = stac92hd73xx_fixup_dell_m6_both, 1882 }, 1883 [STAC_DELL_EQ] = { 1884 .type = HDA_FIXUP_FUNC, 1885 .v.func = stac92hd73xx_fixup_dell_eq, 1886 }, 1887 [STAC_ALIENWARE_M17X] = { 1888 .type = HDA_FIXUP_FUNC, 1889 .v.func = stac92hd73xx_fixup_alienware_m17x, 1890 }, 1891 [STAC_92HD73XX_INTEL] = { 1892 .type = HDA_FIXUP_PINS, 1893 .v.pins = intel_dg45id_pin_configs, 1894 }, 1895 [STAC_92HD73XX_NO_JD] = { 1896 .type = HDA_FIXUP_FUNC, 1897 .v.func = stac92hd73xx_fixup_no_jd, 1898 } 1899 }; 1900 1901 static const struct hda_model_fixup stac92hd73xx_models[] = { 1902 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" }, 1903 { .id = STAC_92HD73XX_REF, .name = "ref" }, 1904 { .id = STAC_92HD73XX_INTEL, .name = "intel" }, 1905 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" }, 1906 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" }, 1907 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, 1908 { .id = STAC_DELL_EQ, .name = "dell-eq" }, 1909 { .id = STAC_ALIENWARE_M17X, .name = "alienware" }, 1910 {} 1911 }; 1912 1913 static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { 1914 /* SigmaTel reference board */ 1915 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1916 "DFI LanParty", STAC_92HD73XX_REF), 1917 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 1918 "DFI LanParty", STAC_92HD73XX_REF), 1919 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002, 1920 "Intel DG45ID", STAC_92HD73XX_INTEL), 1921 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003, 1922 "Intel DG45FC", STAC_92HD73XX_INTEL), 1923 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, 1924 "Dell Studio 1535", STAC_DELL_M6_DMIC), 1925 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, 1926 "unknown Dell", STAC_DELL_M6_DMIC), 1927 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, 1928 "unknown Dell", STAC_DELL_M6_BOTH), 1929 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, 1930 "unknown Dell", STAC_DELL_M6_BOTH), 1931 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, 1932 "unknown Dell", STAC_DELL_M6_AMIC), 1933 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, 1934 "unknown Dell", STAC_DELL_M6_AMIC), 1935 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, 1936 "unknown Dell", STAC_DELL_M6_DMIC), 1937 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272, 1938 "unknown Dell", STAC_DELL_M6_DMIC), 1939 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, 1940 "Dell Studio 1537", STAC_DELL_M6_DMIC), 1941 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0, 1942 "Dell Studio 17", STAC_DELL_M6_DMIC), 1943 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be, 1944 "Dell Studio 1555", STAC_DELL_M6_DMIC), 1945 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, 1946 "Dell Studio 1557", STAC_DELL_M6_DMIC), 1947 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, 1948 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC), 1949 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, 1950 "Dell Studio 1558", STAC_DELL_M6_DMIC), 1951 /* codec SSID matching */ 1952 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, 1953 "Alienware M17x", STAC_ALIENWARE_M17X), 1954 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, 1955 "Alienware M17x", STAC_ALIENWARE_M17X), 1956 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, 1957 "Alienware M17x R3", STAC_DELL_EQ), 1958 {} /* terminator */ 1959 }; 1960 1961 static const struct hda_pintbl ref92hd83xxx_pin_configs[] = { 1962 { 0x0a, 0x02214030 }, 1963 { 0x0b, 0x02211010 }, 1964 { 0x0c, 0x02a19020 }, 1965 { 0x0d, 0x02170130 }, 1966 { 0x0e, 0x01014050 }, 1967 { 0x0f, 0x01819040 }, 1968 { 0x10, 0x01014020 }, 1969 { 0x11, 0x90a3014e }, 1970 { 0x1f, 0x01451160 }, 1971 { 0x20, 0x98560170 }, 1972 {} 1973 }; 1974 1975 static const struct hda_pintbl dell_s14_pin_configs[] = { 1976 { 0x0a, 0x0221403f }, 1977 { 0x0b, 0x0221101f }, 1978 { 0x0c, 0x02a19020 }, 1979 { 0x0d, 0x90170110 }, 1980 { 0x0e, 0x40f000f0 }, 1981 { 0x0f, 0x40f000f0 }, 1982 { 0x10, 0x40f000f0 }, 1983 { 0x11, 0x90a60160 }, 1984 { 0x1f, 0x40f000f0 }, 1985 { 0x20, 0x40f000f0 }, 1986 {} 1987 }; 1988 1989 static const struct hda_pintbl dell_vostro_3500_pin_configs[] = { 1990 { 0x0a, 0x02a11020 }, 1991 { 0x0b, 0x0221101f }, 1992 { 0x0c, 0x400000f0 }, 1993 { 0x0d, 0x90170110 }, 1994 { 0x0e, 0x400000f1 }, 1995 { 0x0f, 0x400000f2 }, 1996 { 0x10, 0x400000f3 }, 1997 { 0x11, 0x90a60160 }, 1998 { 0x1f, 0x400000f4 }, 1999 { 0x20, 0x400000f5 }, 2000 {} 2001 }; 2002 2003 static const struct hda_pintbl hp_dv7_4000_pin_configs[] = { 2004 { 0x0a, 0x03a12050 }, 2005 { 0x0b, 0x0321201f }, 2006 { 0x0c, 0x40f000f0 }, 2007 { 0x0d, 0x90170110 }, 2008 { 0x0e, 0x40f000f0 }, 2009 { 0x0f, 0x40f000f0 }, 2010 { 0x10, 0x90170110 }, 2011 { 0x11, 0xd5a30140 }, 2012 { 0x1f, 0x40f000f0 }, 2013 { 0x20, 0x40f000f0 }, 2014 {} 2015 }; 2016 2017 static const struct hda_pintbl hp_zephyr_pin_configs[] = { 2018 { 0x0a, 0x01813050 }, 2019 { 0x0b, 0x0421201f }, 2020 { 0x0c, 0x04a1205e }, 2021 { 0x0d, 0x96130310 }, 2022 { 0x0e, 0x96130310 }, 2023 { 0x0f, 0x0101401f }, 2024 { 0x10, 0x1111611f }, 2025 { 0x11, 0xd5a30130 }, 2026 {} 2027 }; 2028 2029 static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = { 2030 { 0x0a, 0x40f000f0 }, 2031 { 0x0b, 0x0221101f }, 2032 { 0x0c, 0x02a11020 }, 2033 { 0x0d, 0x92170110 }, 2034 { 0x0e, 0x40f000f0 }, 2035 { 0x0f, 0x92170110 }, 2036 { 0x10, 0x40f000f0 }, 2037 { 0x11, 0xd5a30130 }, 2038 { 0x1f, 0x40f000f0 }, 2039 { 0x20, 0x40f000f0 }, 2040 {} 2041 }; 2042 2043 static void stac92hd83xxx_fixup_hp(struct hda_codec *codec, 2044 const struct hda_fixup *fix, int action) 2045 { 2046 struct sigmatel_spec *spec = codec->spec; 2047 2048 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2049 return; 2050 2051 if (hp_bnb2011_with_dock(codec)) { 2052 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f); 2053 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); 2054 } 2055 2056 if (find_mute_led_cfg(codec, spec->default_polarity)) 2057 snd_printd("mute LED gpio %d polarity %d\n", 2058 spec->gpio_led, 2059 spec->gpio_led_polarity); 2060 } 2061 2062 static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec, 2063 const struct hda_fixup *fix, int action) 2064 { 2065 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2066 return; 2067 2068 snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs); 2069 snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init); 2070 } 2071 2072 static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec, 2073 const struct hda_fixup *fix, int action) 2074 { 2075 struct sigmatel_spec *spec = codec->spec; 2076 2077 if (action == HDA_FIXUP_ACT_PRE_PROBE) 2078 spec->default_polarity = 0; 2079 } 2080 2081 static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec, 2082 const struct hda_fixup *fix, int action) 2083 { 2084 struct sigmatel_spec *spec = codec->spec; 2085 2086 if (action == HDA_FIXUP_ACT_PRE_PROBE) 2087 spec->default_polarity = 1; 2088 } 2089 2090 static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec, 2091 const struct hda_fixup *fix, int action) 2092 { 2093 struct sigmatel_spec *spec = codec->spec; 2094 2095 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2096 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ 2097 /* resetting controller clears GPIO, so we need to keep on */ 2098 codec->bus->power_keep_link_on = 1; 2099 } 2100 } 2101 2102 static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, 2103 const struct hda_fixup *fix, int action) 2104 { 2105 struct sigmatel_spec *spec = codec->spec; 2106 2107 if (action == HDA_FIXUP_ACT_PRE_PROBE) 2108 spec->headset_jack = 1; 2109 } 2110 2111 static const struct hda_verb hp_bnb13_eq_verbs[] = { 2112 /* 44.1KHz base */ 2113 { 0x22, 0x7A6, 0x3E }, 2114 { 0x22, 0x7A7, 0x68 }, 2115 { 0x22, 0x7A8, 0x17 }, 2116 { 0x22, 0x7A9, 0x3E }, 2117 { 0x22, 0x7AA, 0x68 }, 2118 { 0x22, 0x7AB, 0x17 }, 2119 { 0x22, 0x7AC, 0x00 }, 2120 { 0x22, 0x7AD, 0x80 }, 2121 { 0x22, 0x7A6, 0x83 }, 2122 { 0x22, 0x7A7, 0x2F }, 2123 { 0x22, 0x7A8, 0xD1 }, 2124 { 0x22, 0x7A9, 0x83 }, 2125 { 0x22, 0x7AA, 0x2F }, 2126 { 0x22, 0x7AB, 0xD1 }, 2127 { 0x22, 0x7AC, 0x01 }, 2128 { 0x22, 0x7AD, 0x80 }, 2129 { 0x22, 0x7A6, 0x3E }, 2130 { 0x22, 0x7A7, 0x68 }, 2131 { 0x22, 0x7A8, 0x17 }, 2132 { 0x22, 0x7A9, 0x3E }, 2133 { 0x22, 0x7AA, 0x68 }, 2134 { 0x22, 0x7AB, 0x17 }, 2135 { 0x22, 0x7AC, 0x02 }, 2136 { 0x22, 0x7AD, 0x80 }, 2137 { 0x22, 0x7A6, 0x7C }, 2138 { 0x22, 0x7A7, 0xC6 }, 2139 { 0x22, 0x7A8, 0x0C }, 2140 { 0x22, 0x7A9, 0x7C }, 2141 { 0x22, 0x7AA, 0xC6 }, 2142 { 0x22, 0x7AB, 0x0C }, 2143 { 0x22, 0x7AC, 0x03 }, 2144 { 0x22, 0x7AD, 0x80 }, 2145 { 0x22, 0x7A6, 0xC3 }, 2146 { 0x22, 0x7A7, 0x25 }, 2147 { 0x22, 0x7A8, 0xAF }, 2148 { 0x22, 0x7A9, 0xC3 }, 2149 { 0x22, 0x7AA, 0x25 }, 2150 { 0x22, 0x7AB, 0xAF }, 2151 { 0x22, 0x7AC, 0x04 }, 2152 { 0x22, 0x7AD, 0x80 }, 2153 { 0x22, 0x7A6, 0x3E }, 2154 { 0x22, 0x7A7, 0x85 }, 2155 { 0x22, 0x7A8, 0x73 }, 2156 { 0x22, 0x7A9, 0x3E }, 2157 { 0x22, 0x7AA, 0x85 }, 2158 { 0x22, 0x7AB, 0x73 }, 2159 { 0x22, 0x7AC, 0x05 }, 2160 { 0x22, 0x7AD, 0x80 }, 2161 { 0x22, 0x7A6, 0x85 }, 2162 { 0x22, 0x7A7, 0x39 }, 2163 { 0x22, 0x7A8, 0xC7 }, 2164 { 0x22, 0x7A9, 0x85 }, 2165 { 0x22, 0x7AA, 0x39 }, 2166 { 0x22, 0x7AB, 0xC7 }, 2167 { 0x22, 0x7AC, 0x06 }, 2168 { 0x22, 0x7AD, 0x80 }, 2169 { 0x22, 0x7A6, 0x3C }, 2170 { 0x22, 0x7A7, 0x90 }, 2171 { 0x22, 0x7A8, 0xB0 }, 2172 { 0x22, 0x7A9, 0x3C }, 2173 { 0x22, 0x7AA, 0x90 }, 2174 { 0x22, 0x7AB, 0xB0 }, 2175 { 0x22, 0x7AC, 0x07 }, 2176 { 0x22, 0x7AD, 0x80 }, 2177 { 0x22, 0x7A6, 0x7A }, 2178 { 0x22, 0x7A7, 0xC6 }, 2179 { 0x22, 0x7A8, 0x39 }, 2180 { 0x22, 0x7A9, 0x7A }, 2181 { 0x22, 0x7AA, 0xC6 }, 2182 { 0x22, 0x7AB, 0x39 }, 2183 { 0x22, 0x7AC, 0x08 }, 2184 { 0x22, 0x7AD, 0x80 }, 2185 { 0x22, 0x7A6, 0xC4 }, 2186 { 0x22, 0x7A7, 0xE9 }, 2187 { 0x22, 0x7A8, 0xDC }, 2188 { 0x22, 0x7A9, 0xC4 }, 2189 { 0x22, 0x7AA, 0xE9 }, 2190 { 0x22, 0x7AB, 0xDC }, 2191 { 0x22, 0x7AC, 0x09 }, 2192 { 0x22, 0x7AD, 0x80 }, 2193 { 0x22, 0x7A6, 0x3D }, 2194 { 0x22, 0x7A7, 0xE1 }, 2195 { 0x22, 0x7A8, 0x0D }, 2196 { 0x22, 0x7A9, 0x3D }, 2197 { 0x22, 0x7AA, 0xE1 }, 2198 { 0x22, 0x7AB, 0x0D }, 2199 { 0x22, 0x7AC, 0x0A }, 2200 { 0x22, 0x7AD, 0x80 }, 2201 { 0x22, 0x7A6, 0x89 }, 2202 { 0x22, 0x7A7, 0xB6 }, 2203 { 0x22, 0x7A8, 0xEB }, 2204 { 0x22, 0x7A9, 0x89 }, 2205 { 0x22, 0x7AA, 0xB6 }, 2206 { 0x22, 0x7AB, 0xEB }, 2207 { 0x22, 0x7AC, 0x0B }, 2208 { 0x22, 0x7AD, 0x80 }, 2209 { 0x22, 0x7A6, 0x39 }, 2210 { 0x22, 0x7A7, 0x9D }, 2211 { 0x22, 0x7A8, 0xFE }, 2212 { 0x22, 0x7A9, 0x39 }, 2213 { 0x22, 0x7AA, 0x9D }, 2214 { 0x22, 0x7AB, 0xFE }, 2215 { 0x22, 0x7AC, 0x0C }, 2216 { 0x22, 0x7AD, 0x80 }, 2217 { 0x22, 0x7A6, 0x76 }, 2218 { 0x22, 0x7A7, 0x49 }, 2219 { 0x22, 0x7A8, 0x15 }, 2220 { 0x22, 0x7A9, 0x76 }, 2221 { 0x22, 0x7AA, 0x49 }, 2222 { 0x22, 0x7AB, 0x15 }, 2223 { 0x22, 0x7AC, 0x0D }, 2224 { 0x22, 0x7AD, 0x80 }, 2225 { 0x22, 0x7A6, 0xC8 }, 2226 { 0x22, 0x7A7, 0x80 }, 2227 { 0x22, 0x7A8, 0xF5 }, 2228 { 0x22, 0x7A9, 0xC8 }, 2229 { 0x22, 0x7AA, 0x80 }, 2230 { 0x22, 0x7AB, 0xF5 }, 2231 { 0x22, 0x7AC, 0x0E }, 2232 { 0x22, 0x7AD, 0x80 }, 2233 { 0x22, 0x7A6, 0x40 }, 2234 { 0x22, 0x7A7, 0x00 }, 2235 { 0x22, 0x7A8, 0x00 }, 2236 { 0x22, 0x7A9, 0x40 }, 2237 { 0x22, 0x7AA, 0x00 }, 2238 { 0x22, 0x7AB, 0x00 }, 2239 { 0x22, 0x7AC, 0x0F }, 2240 { 0x22, 0x7AD, 0x80 }, 2241 { 0x22, 0x7A6, 0x90 }, 2242 { 0x22, 0x7A7, 0x68 }, 2243 { 0x22, 0x7A8, 0xF1 }, 2244 { 0x22, 0x7A9, 0x90 }, 2245 { 0x22, 0x7AA, 0x68 }, 2246 { 0x22, 0x7AB, 0xF1 }, 2247 { 0x22, 0x7AC, 0x10 }, 2248 { 0x22, 0x7AD, 0x80 }, 2249 { 0x22, 0x7A6, 0x34 }, 2250 { 0x22, 0x7A7, 0x47 }, 2251 { 0x22, 0x7A8, 0x6C }, 2252 { 0x22, 0x7A9, 0x34 }, 2253 { 0x22, 0x7AA, 0x47 }, 2254 { 0x22, 0x7AB, 0x6C }, 2255 { 0x22, 0x7AC, 0x11 }, 2256 { 0x22, 0x7AD, 0x80 }, 2257 { 0x22, 0x7A6, 0x6F }, 2258 { 0x22, 0x7A7, 0x97 }, 2259 { 0x22, 0x7A8, 0x0F }, 2260 { 0x22, 0x7A9, 0x6F }, 2261 { 0x22, 0x7AA, 0x97 }, 2262 { 0x22, 0x7AB, 0x0F }, 2263 { 0x22, 0x7AC, 0x12 }, 2264 { 0x22, 0x7AD, 0x80 }, 2265 { 0x22, 0x7A6, 0xCB }, 2266 { 0x22, 0x7A7, 0xB8 }, 2267 { 0x22, 0x7A8, 0x94 }, 2268 { 0x22, 0x7A9, 0xCB }, 2269 { 0x22, 0x7AA, 0xB8 }, 2270 { 0x22, 0x7AB, 0x94 }, 2271 { 0x22, 0x7AC, 0x13 }, 2272 { 0x22, 0x7AD, 0x80 }, 2273 { 0x22, 0x7A6, 0x40 }, 2274 { 0x22, 0x7A7, 0x00 }, 2275 { 0x22, 0x7A8, 0x00 }, 2276 { 0x22, 0x7A9, 0x40 }, 2277 { 0x22, 0x7AA, 0x00 }, 2278 { 0x22, 0x7AB, 0x00 }, 2279 { 0x22, 0x7AC, 0x14 }, 2280 { 0x22, 0x7AD, 0x80 }, 2281 { 0x22, 0x7A6, 0x95 }, 2282 { 0x22, 0x7A7, 0x76 }, 2283 { 0x22, 0x7A8, 0x5B }, 2284 { 0x22, 0x7A9, 0x95 }, 2285 { 0x22, 0x7AA, 0x76 }, 2286 { 0x22, 0x7AB, 0x5B }, 2287 { 0x22, 0x7AC, 0x15 }, 2288 { 0x22, 0x7AD, 0x80 }, 2289 { 0x22, 0x7A6, 0x31 }, 2290 { 0x22, 0x7A7, 0xAC }, 2291 { 0x22, 0x7A8, 0x31 }, 2292 { 0x22, 0x7A9, 0x31 }, 2293 { 0x22, 0x7AA, 0xAC }, 2294 { 0x22, 0x7AB, 0x31 }, 2295 { 0x22, 0x7AC, 0x16 }, 2296 { 0x22, 0x7AD, 0x80 }, 2297 { 0x22, 0x7A6, 0x6A }, 2298 { 0x22, 0x7A7, 0x89 }, 2299 { 0x22, 0x7A8, 0xA5 }, 2300 { 0x22, 0x7A9, 0x6A }, 2301 { 0x22, 0x7AA, 0x89 }, 2302 { 0x22, 0x7AB, 0xA5 }, 2303 { 0x22, 0x7AC, 0x17 }, 2304 { 0x22, 0x7AD, 0x80 }, 2305 { 0x22, 0x7A6, 0xCE }, 2306 { 0x22, 0x7A7, 0x53 }, 2307 { 0x22, 0x7A8, 0xCF }, 2308 { 0x22, 0x7A9, 0xCE }, 2309 { 0x22, 0x7AA, 0x53 }, 2310 { 0x22, 0x7AB, 0xCF }, 2311 { 0x22, 0x7AC, 0x18 }, 2312 { 0x22, 0x7AD, 0x80 }, 2313 { 0x22, 0x7A6, 0x40 }, 2314 { 0x22, 0x7A7, 0x00 }, 2315 { 0x22, 0x7A8, 0x00 }, 2316 { 0x22, 0x7A9, 0x40 }, 2317 { 0x22, 0x7AA, 0x00 }, 2318 { 0x22, 0x7AB, 0x00 }, 2319 { 0x22, 0x7AC, 0x19 }, 2320 { 0x22, 0x7AD, 0x80 }, 2321 /* 48KHz base */ 2322 { 0x22, 0x7A6, 0x3E }, 2323 { 0x22, 0x7A7, 0x88 }, 2324 { 0x22, 0x7A8, 0xDC }, 2325 { 0x22, 0x7A9, 0x3E }, 2326 { 0x22, 0x7AA, 0x88 }, 2327 { 0x22, 0x7AB, 0xDC }, 2328 { 0x22, 0x7AC, 0x1A }, 2329 { 0x22, 0x7AD, 0x80 }, 2330 { 0x22, 0x7A6, 0x82 }, 2331 { 0x22, 0x7A7, 0xEE }, 2332 { 0x22, 0x7A8, 0x46 }, 2333 { 0x22, 0x7A9, 0x82 }, 2334 { 0x22, 0x7AA, 0xEE }, 2335 { 0x22, 0x7AB, 0x46 }, 2336 { 0x22, 0x7AC, 0x1B }, 2337 { 0x22, 0x7AD, 0x80 }, 2338 { 0x22, 0x7A6, 0x3E }, 2339 { 0x22, 0x7A7, 0x88 }, 2340 { 0x22, 0x7A8, 0xDC }, 2341 { 0x22, 0x7A9, 0x3E }, 2342 { 0x22, 0x7AA, 0x88 }, 2343 { 0x22, 0x7AB, 0xDC }, 2344 { 0x22, 0x7AC, 0x1C }, 2345 { 0x22, 0x7AD, 0x80 }, 2346 { 0x22, 0x7A6, 0x7D }, 2347 { 0x22, 0x7A7, 0x09 }, 2348 { 0x22, 0x7A8, 0x28 }, 2349 { 0x22, 0x7A9, 0x7D }, 2350 { 0x22, 0x7AA, 0x09 }, 2351 { 0x22, 0x7AB, 0x28 }, 2352 { 0x22, 0x7AC, 0x1D }, 2353 { 0x22, 0x7AD, 0x80 }, 2354 { 0x22, 0x7A6, 0xC2 }, 2355 { 0x22, 0x7A7, 0xE5 }, 2356 { 0x22, 0x7A8, 0xB4 }, 2357 { 0x22, 0x7A9, 0xC2 }, 2358 { 0x22, 0x7AA, 0xE5 }, 2359 { 0x22, 0x7AB, 0xB4 }, 2360 { 0x22, 0x7AC, 0x1E }, 2361 { 0x22, 0x7AD, 0x80 }, 2362 { 0x22, 0x7A6, 0x3E }, 2363 { 0x22, 0x7A7, 0xA3 }, 2364 { 0x22, 0x7A8, 0x1F }, 2365 { 0x22, 0x7A9, 0x3E }, 2366 { 0x22, 0x7AA, 0xA3 }, 2367 { 0x22, 0x7AB, 0x1F }, 2368 { 0x22, 0x7AC, 0x1F }, 2369 { 0x22, 0x7AD, 0x80 }, 2370 { 0x22, 0x7A6, 0x84 }, 2371 { 0x22, 0x7A7, 0xCA }, 2372 { 0x22, 0x7A8, 0xF1 }, 2373 { 0x22, 0x7A9, 0x84 }, 2374 { 0x22, 0x7AA, 0xCA }, 2375 { 0x22, 0x7AB, 0xF1 }, 2376 { 0x22, 0x7AC, 0x20 }, 2377 { 0x22, 0x7AD, 0x80 }, 2378 { 0x22, 0x7A6, 0x3C }, 2379 { 0x22, 0x7A7, 0xD5 }, 2380 { 0x22, 0x7A8, 0x9C }, 2381 { 0x22, 0x7A9, 0x3C }, 2382 { 0x22, 0x7AA, 0xD5 }, 2383 { 0x22, 0x7AB, 0x9C }, 2384 { 0x22, 0x7AC, 0x21 }, 2385 { 0x22, 0x7AD, 0x80 }, 2386 { 0x22, 0x7A6, 0x7B }, 2387 { 0x22, 0x7A7, 0x35 }, 2388 { 0x22, 0x7A8, 0x0F }, 2389 { 0x22, 0x7A9, 0x7B }, 2390 { 0x22, 0x7AA, 0x35 }, 2391 { 0x22, 0x7AB, 0x0F }, 2392 { 0x22, 0x7AC, 0x22 }, 2393 { 0x22, 0x7AD, 0x80 }, 2394 { 0x22, 0x7A6, 0xC4 }, 2395 { 0x22, 0x7A7, 0x87 }, 2396 { 0x22, 0x7A8, 0x45 }, 2397 { 0x22, 0x7A9, 0xC4 }, 2398 { 0x22, 0x7AA, 0x87 }, 2399 { 0x22, 0x7AB, 0x45 }, 2400 { 0x22, 0x7AC, 0x23 }, 2401 { 0x22, 0x7AD, 0x80 }, 2402 { 0x22, 0x7A6, 0x3E }, 2403 { 0x22, 0x7A7, 0x0A }, 2404 { 0x22, 0x7A8, 0x78 }, 2405 { 0x22, 0x7A9, 0x3E }, 2406 { 0x22, 0x7AA, 0x0A }, 2407 { 0x22, 0x7AB, 0x78 }, 2408 { 0x22, 0x7AC, 0x24 }, 2409 { 0x22, 0x7AD, 0x80 }, 2410 { 0x22, 0x7A6, 0x88 }, 2411 { 0x22, 0x7A7, 0xE2 }, 2412 { 0x22, 0x7A8, 0x05 }, 2413 { 0x22, 0x7A9, 0x88 }, 2414 { 0x22, 0x7AA, 0xE2 }, 2415 { 0x22, 0x7AB, 0x05 }, 2416 { 0x22, 0x7AC, 0x25 }, 2417 { 0x22, 0x7AD, 0x80 }, 2418 { 0x22, 0x7A6, 0x3A }, 2419 { 0x22, 0x7A7, 0x1A }, 2420 { 0x22, 0x7A8, 0xA3 }, 2421 { 0x22, 0x7A9, 0x3A }, 2422 { 0x22, 0x7AA, 0x1A }, 2423 { 0x22, 0x7AB, 0xA3 }, 2424 { 0x22, 0x7AC, 0x26 }, 2425 { 0x22, 0x7AD, 0x80 }, 2426 { 0x22, 0x7A6, 0x77 }, 2427 { 0x22, 0x7A7, 0x1D }, 2428 { 0x22, 0x7A8, 0xFB }, 2429 { 0x22, 0x7A9, 0x77 }, 2430 { 0x22, 0x7AA, 0x1D }, 2431 { 0x22, 0x7AB, 0xFB }, 2432 { 0x22, 0x7AC, 0x27 }, 2433 { 0x22, 0x7AD, 0x80 }, 2434 { 0x22, 0x7A6, 0xC7 }, 2435 { 0x22, 0x7A7, 0xDA }, 2436 { 0x22, 0x7A8, 0xE5 }, 2437 { 0x22, 0x7A9, 0xC7 }, 2438 { 0x22, 0x7AA, 0xDA }, 2439 { 0x22, 0x7AB, 0xE5 }, 2440 { 0x22, 0x7AC, 0x28 }, 2441 { 0x22, 0x7AD, 0x80 }, 2442 { 0x22, 0x7A6, 0x40 }, 2443 { 0x22, 0x7A7, 0x00 }, 2444 { 0x22, 0x7A8, 0x00 }, 2445 { 0x22, 0x7A9, 0x40 }, 2446 { 0x22, 0x7AA, 0x00 }, 2447 { 0x22, 0x7AB, 0x00 }, 2448 { 0x22, 0x7AC, 0x29 }, 2449 { 0x22, 0x7AD, 0x80 }, 2450 { 0x22, 0x7A6, 0x8E }, 2451 { 0x22, 0x7A7, 0xD7 }, 2452 { 0x22, 0x7A8, 0x22 }, 2453 { 0x22, 0x7A9, 0x8E }, 2454 { 0x22, 0x7AA, 0xD7 }, 2455 { 0x22, 0x7AB, 0x22 }, 2456 { 0x22, 0x7AC, 0x2A }, 2457 { 0x22, 0x7AD, 0x80 }, 2458 { 0x22, 0x7A6, 0x35 }, 2459 { 0x22, 0x7A7, 0x26 }, 2460 { 0x22, 0x7A8, 0xC6 }, 2461 { 0x22, 0x7A9, 0x35 }, 2462 { 0x22, 0x7AA, 0x26 }, 2463 { 0x22, 0x7AB, 0xC6 }, 2464 { 0x22, 0x7AC, 0x2B }, 2465 { 0x22, 0x7AD, 0x80 }, 2466 { 0x22, 0x7A6, 0x71 }, 2467 { 0x22, 0x7A7, 0x28 }, 2468 { 0x22, 0x7A8, 0xDE }, 2469 { 0x22, 0x7A9, 0x71 }, 2470 { 0x22, 0x7AA, 0x28 }, 2471 { 0x22, 0x7AB, 0xDE }, 2472 { 0x22, 0x7AC, 0x2C }, 2473 { 0x22, 0x7AD, 0x80 }, 2474 { 0x22, 0x7A6, 0xCA }, 2475 { 0x22, 0x7A7, 0xD9 }, 2476 { 0x22, 0x7A8, 0x3A }, 2477 { 0x22, 0x7A9, 0xCA }, 2478 { 0x22, 0x7AA, 0xD9 }, 2479 { 0x22, 0x7AB, 0x3A }, 2480 { 0x22, 0x7AC, 0x2D }, 2481 { 0x22, 0x7AD, 0x80 }, 2482 { 0x22, 0x7A6, 0x40 }, 2483 { 0x22, 0x7A7, 0x00 }, 2484 { 0x22, 0x7A8, 0x00 }, 2485 { 0x22, 0x7A9, 0x40 }, 2486 { 0x22, 0x7AA, 0x00 }, 2487 { 0x22, 0x7AB, 0x00 }, 2488 { 0x22, 0x7AC, 0x2E }, 2489 { 0x22, 0x7AD, 0x80 }, 2490 { 0x22, 0x7A6, 0x93 }, 2491 { 0x22, 0x7A7, 0x5E }, 2492 { 0x22, 0x7A8, 0xD8 }, 2493 { 0x22, 0x7A9, 0x93 }, 2494 { 0x22, 0x7AA, 0x5E }, 2495 { 0x22, 0x7AB, 0xD8 }, 2496 { 0x22, 0x7AC, 0x2F }, 2497 { 0x22, 0x7AD, 0x80 }, 2498 { 0x22, 0x7A6, 0x32 }, 2499 { 0x22, 0x7A7, 0xB7 }, 2500 { 0x22, 0x7A8, 0xB1 }, 2501 { 0x22, 0x7A9, 0x32 }, 2502 { 0x22, 0x7AA, 0xB7 }, 2503 { 0x22, 0x7AB, 0xB1 }, 2504 { 0x22, 0x7AC, 0x30 }, 2505 { 0x22, 0x7AD, 0x80 }, 2506 { 0x22, 0x7A6, 0x6C }, 2507 { 0x22, 0x7A7, 0xA1 }, 2508 { 0x22, 0x7A8, 0x28 }, 2509 { 0x22, 0x7A9, 0x6C }, 2510 { 0x22, 0x7AA, 0xA1 }, 2511 { 0x22, 0x7AB, 0x28 }, 2512 { 0x22, 0x7AC, 0x31 }, 2513 { 0x22, 0x7AD, 0x80 }, 2514 { 0x22, 0x7A6, 0xCD }, 2515 { 0x22, 0x7A7, 0x48 }, 2516 { 0x22, 0x7A8, 0x4F }, 2517 { 0x22, 0x7A9, 0xCD }, 2518 { 0x22, 0x7AA, 0x48 }, 2519 { 0x22, 0x7AB, 0x4F }, 2520 { 0x22, 0x7AC, 0x32 }, 2521 { 0x22, 0x7AD, 0x80 }, 2522 { 0x22, 0x7A6, 0x40 }, 2523 { 0x22, 0x7A7, 0x00 }, 2524 { 0x22, 0x7A8, 0x00 }, 2525 { 0x22, 0x7A9, 0x40 }, 2526 { 0x22, 0x7AA, 0x00 }, 2527 { 0x22, 0x7AB, 0x00 }, 2528 { 0x22, 0x7AC, 0x33 }, 2529 { 0x22, 0x7AD, 0x80 }, 2530 /* common */ 2531 { 0x22, 0x782, 0xC1 }, 2532 { 0x22, 0x771, 0x2C }, 2533 { 0x22, 0x772, 0x2C }, 2534 { 0x22, 0x788, 0x04 }, 2535 { 0x01, 0x7B0, 0x08 }, 2536 {} 2537 }; 2538 2539 static const struct hda_fixup stac92hd83xxx_fixups[] = { 2540 [STAC_92HD83XXX_REF] = { 2541 .type = HDA_FIXUP_PINS, 2542 .v.pins = ref92hd83xxx_pin_configs, 2543 }, 2544 [STAC_92HD83XXX_PWR_REF] = { 2545 .type = HDA_FIXUP_PINS, 2546 .v.pins = ref92hd83xxx_pin_configs, 2547 }, 2548 [STAC_DELL_S14] = { 2549 .type = HDA_FIXUP_PINS, 2550 .v.pins = dell_s14_pin_configs, 2551 }, 2552 [STAC_DELL_VOSTRO_3500] = { 2553 .type = HDA_FIXUP_PINS, 2554 .v.pins = dell_vostro_3500_pin_configs, 2555 }, 2556 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = { 2557 .type = HDA_FIXUP_PINS, 2558 .v.pins = hp_cNB11_intquad_pin_configs, 2559 .chained = true, 2560 .chain_id = STAC_92HD83XXX_HP, 2561 }, 2562 [STAC_92HD83XXX_HP] = { 2563 .type = HDA_FIXUP_FUNC, 2564 .v.func = stac92hd83xxx_fixup_hp, 2565 }, 2566 [STAC_HP_DV7_4000] = { 2567 .type = HDA_FIXUP_PINS, 2568 .v.pins = hp_dv7_4000_pin_configs, 2569 .chained = true, 2570 .chain_id = STAC_92HD83XXX_HP, 2571 }, 2572 [STAC_HP_ZEPHYR] = { 2573 .type = HDA_FIXUP_FUNC, 2574 .v.func = stac92hd83xxx_fixup_hp_zephyr, 2575 .chained = true, 2576 .chain_id = STAC_92HD83XXX_HP, 2577 }, 2578 [STAC_92HD83XXX_HP_LED] = { 2579 .type = HDA_FIXUP_FUNC, 2580 .v.func = stac92hd83xxx_fixup_hp_led, 2581 .chained = true, 2582 .chain_id = STAC_92HD83XXX_HP, 2583 }, 2584 [STAC_92HD83XXX_HP_INV_LED] = { 2585 .type = HDA_FIXUP_FUNC, 2586 .v.func = stac92hd83xxx_fixup_hp_inv_led, 2587 .chained = true, 2588 .chain_id = STAC_92HD83XXX_HP, 2589 }, 2590 [STAC_92HD83XXX_HP_MIC_LED] = { 2591 .type = HDA_FIXUP_FUNC, 2592 .v.func = stac92hd83xxx_fixup_hp_mic_led, 2593 .chained = true, 2594 .chain_id = STAC_92HD83XXX_HP, 2595 }, 2596 [STAC_92HD83XXX_HEADSET_JACK] = { 2597 .type = HDA_FIXUP_FUNC, 2598 .v.func = stac92hd83xxx_fixup_headset_jack, 2599 }, 2600 [STAC_HP_ENVY_BASS] = { 2601 .type = HDA_FIXUP_PINS, 2602 .v.pins = (const struct hda_pintbl[]) { 2603 { 0x0f, 0x90170111 }, 2604 {} 2605 }, 2606 }, 2607 [STAC_HP_BNB13_EQ] = { 2608 .type = HDA_FIXUP_VERBS, 2609 .v.verbs = hp_bnb13_eq_verbs, 2610 .chained = true, 2611 .chain_id = STAC_92HD83XXX_HP_MIC_LED, 2612 }, 2613 }; 2614 2615 static const struct hda_model_fixup stac92hd83xxx_models[] = { 2616 { .id = STAC_92HD83XXX_REF, .name = "ref" }, 2617 { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" }, 2618 { .id = STAC_DELL_S14, .name = "dell-s14" }, 2619 { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" }, 2620 { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" }, 2621 { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" }, 2622 { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" }, 2623 { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" }, 2624 { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" }, 2625 { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" }, 2626 { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" }, 2627 { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" }, 2628 { .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" }, 2629 {} 2630 }; 2631 2632 static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = { 2633 /* SigmaTel reference board */ 2634 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 2635 "DFI LanParty", STAC_92HD83XXX_REF), 2636 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 2637 "DFI LanParty", STAC_92HD83XXX_REF), 2638 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 2639 "unknown Dell", STAC_DELL_S14), 2640 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532, 2641 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK), 2642 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533, 2643 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK), 2644 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534, 2645 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK), 2646 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535, 2647 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK), 2648 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c, 2649 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK), 2650 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d, 2651 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK), 2652 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549, 2653 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK), 2654 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d, 2655 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK), 2656 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584, 2657 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK), 2658 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, 2659 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), 2660 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, 2661 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2662 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657, 2663 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2664 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658, 2665 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2666 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659, 2667 "HP Pavilion dv7", STAC_HP_DV7_4000), 2668 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A, 2669 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2670 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, 2671 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2672 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, 2673 "HP Envy Spectre", STAC_HP_ENVY_BASS), 2674 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, 2675 "HP Folio", STAC_HP_BNB13_EQ), 2676 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8, 2677 "HP bNB13", STAC_HP_BNB13_EQ), 2678 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1909, 2679 "HP bNB13", STAC_HP_BNB13_EQ), 2680 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A, 2681 "HP bNB13", STAC_HP_BNB13_EQ), 2682 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940, 2683 "HP bNB13", STAC_HP_BNB13_EQ), 2684 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941, 2685 "HP bNB13", STAC_HP_BNB13_EQ), 2686 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1942, 2687 "HP bNB13", STAC_HP_BNB13_EQ), 2688 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1943, 2689 "HP bNB13", STAC_HP_BNB13_EQ), 2690 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1944, 2691 "HP bNB13", STAC_HP_BNB13_EQ), 2692 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1945, 2693 "HP bNB13", STAC_HP_BNB13_EQ), 2694 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1946, 2695 "HP bNB13", STAC_HP_BNB13_EQ), 2696 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1948, 2697 "HP bNB13", STAC_HP_BNB13_EQ), 2698 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1949, 2699 "HP bNB13", STAC_HP_BNB13_EQ), 2700 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194A, 2701 "HP bNB13", STAC_HP_BNB13_EQ), 2702 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194B, 2703 "HP bNB13", STAC_HP_BNB13_EQ), 2704 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194C, 2705 "HP bNB13", STAC_HP_BNB13_EQ), 2706 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194E, 2707 "HP bNB13", STAC_HP_BNB13_EQ), 2708 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194F, 2709 "HP bNB13", STAC_HP_BNB13_EQ), 2710 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1950, 2711 "HP bNB13", STAC_HP_BNB13_EQ), 2712 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1951, 2713 "HP bNB13", STAC_HP_BNB13_EQ), 2714 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195A, 2715 "HP bNB13", STAC_HP_BNB13_EQ), 2716 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195B, 2717 "HP bNB13", STAC_HP_BNB13_EQ), 2718 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195C, 2719 "HP bNB13", STAC_HP_BNB13_EQ), 2720 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1991, 2721 "HP bNB13", STAC_HP_BNB13_EQ), 2722 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2103, 2723 "HP bNB13", STAC_HP_BNB13_EQ), 2724 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2104, 2725 "HP bNB13", STAC_HP_BNB13_EQ), 2726 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2105, 2727 "HP bNB13", STAC_HP_BNB13_EQ), 2728 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2106, 2729 "HP bNB13", STAC_HP_BNB13_EQ), 2730 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2107, 2731 "HP bNB13", STAC_HP_BNB13_EQ), 2732 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2108, 2733 "HP bNB13", STAC_HP_BNB13_EQ), 2734 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2109, 2735 "HP bNB13", STAC_HP_BNB13_EQ), 2736 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210A, 2737 "HP bNB13", STAC_HP_BNB13_EQ), 2738 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210B, 2739 "HP bNB13", STAC_HP_BNB13_EQ), 2740 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211C, 2741 "HP bNB13", STAC_HP_BNB13_EQ), 2742 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211D, 2743 "HP bNB13", STAC_HP_BNB13_EQ), 2744 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211E, 2745 "HP bNB13", STAC_HP_BNB13_EQ), 2746 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211F, 2747 "HP bNB13", STAC_HP_BNB13_EQ), 2748 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2120, 2749 "HP bNB13", STAC_HP_BNB13_EQ), 2750 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2121, 2751 "HP bNB13", STAC_HP_BNB13_EQ), 2752 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2122, 2753 "HP bNB13", STAC_HP_BNB13_EQ), 2754 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2123, 2755 "HP bNB13", STAC_HP_BNB13_EQ), 2756 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213E, 2757 "HP bNB13", STAC_HP_BNB13_EQ), 2758 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213F, 2759 "HP bNB13", STAC_HP_BNB13_EQ), 2760 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2140, 2761 "HP bNB13", STAC_HP_BNB13_EQ), 2762 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B2, 2763 "HP bNB13", STAC_HP_BNB13_EQ), 2764 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B3, 2765 "HP bNB13", STAC_HP_BNB13_EQ), 2766 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B5, 2767 "HP bNB13", STAC_HP_BNB13_EQ), 2768 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B6, 2769 "HP bNB13", STAC_HP_BNB13_EQ), 2770 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900, 2771 "HP", STAC_92HD83XXX_HP_MIC_LED), 2772 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000, 2773 "HP", STAC_92HD83XXX_HP_MIC_LED), 2774 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100, 2775 "HP", STAC_92HD83XXX_HP_MIC_LED), 2776 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388, 2777 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2778 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389, 2779 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2780 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B, 2781 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2782 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C, 2783 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2784 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D, 2785 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2786 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E, 2787 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2788 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F, 2789 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2790 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560, 2791 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2792 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B, 2793 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2794 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C, 2795 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2796 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D, 2797 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2798 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591, 2799 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2800 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592, 2801 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2802 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, 2803 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2804 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, 2805 "HP", STAC_HP_ZEPHYR), 2806 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660, 2807 "HP Mini", STAC_92HD83XXX_HP_LED), 2808 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E, 2809 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED), 2810 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a, 2811 "HP Mini", STAC_92HD83XXX_HP_LED), 2812 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP), 2813 {} /* terminator */ 2814 }; 2815 2816 /* HP dv7 bass switch - GPIO5 */ 2817 #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info 2818 static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol, 2819 struct snd_ctl_elem_value *ucontrol) 2820 { 2821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2822 struct sigmatel_spec *spec = codec->spec; 2823 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20); 2824 return 0; 2825 } 2826 2827 static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, 2828 struct snd_ctl_elem_value *ucontrol) 2829 { 2830 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2831 struct sigmatel_spec *spec = codec->spec; 2832 unsigned int gpio_data; 2833 2834 gpio_data = (spec->gpio_data & ~0x20) | 2835 (ucontrol->value.integer.value[0] ? 0x20 : 0); 2836 if (gpio_data == spec->gpio_data) 2837 return 0; 2838 spec->gpio_data = gpio_data; 2839 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 2840 return 1; 2841 } 2842 2843 static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { 2844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2845 .info = stac_hp_bass_gpio_info, 2846 .get = stac_hp_bass_gpio_get, 2847 .put = stac_hp_bass_gpio_put, 2848 }; 2849 2850 static int stac_add_hp_bass_switch(struct hda_codec *codec) 2851 { 2852 struct sigmatel_spec *spec = codec->spec; 2853 2854 if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch", 2855 &stac_hp_bass_sw_ctrl)) 2856 return -ENOMEM; 2857 2858 spec->gpio_mask |= 0x20; 2859 spec->gpio_dir |= 0x20; 2860 spec->gpio_data |= 0x20; 2861 return 0; 2862 } 2863 2864 static const struct hda_pintbl ref92hd71bxx_pin_configs[] = { 2865 { 0x0a, 0x02214030 }, 2866 { 0x0b, 0x02a19040 }, 2867 { 0x0c, 0x01a19020 }, 2868 { 0x0d, 0x01014010 }, 2869 { 0x0e, 0x0181302e }, 2870 { 0x0f, 0x01014010 }, 2871 { 0x14, 0x01019020 }, 2872 { 0x18, 0x90a000f0 }, 2873 { 0x19, 0x90a000f0 }, 2874 { 0x1e, 0x01452050 }, 2875 { 0x1f, 0x01452050 }, 2876 {} 2877 }; 2878 2879 static const struct hda_pintbl dell_m4_1_pin_configs[] = { 2880 { 0x0a, 0x0421101f }, 2881 { 0x0b, 0x04a11221 }, 2882 { 0x0c, 0x40f000f0 }, 2883 { 0x0d, 0x90170110 }, 2884 { 0x0e, 0x23a1902e }, 2885 { 0x0f, 0x23014250 }, 2886 { 0x14, 0x40f000f0 }, 2887 { 0x18, 0x90a000f0 }, 2888 { 0x19, 0x40f000f0 }, 2889 { 0x1e, 0x4f0000f0 }, 2890 { 0x1f, 0x4f0000f0 }, 2891 {} 2892 }; 2893 2894 static const struct hda_pintbl dell_m4_2_pin_configs[] = { 2895 { 0x0a, 0x0421101f }, 2896 { 0x0b, 0x04a11221 }, 2897 { 0x0c, 0x90a70330 }, 2898 { 0x0d, 0x90170110 }, 2899 { 0x0e, 0x23a1902e }, 2900 { 0x0f, 0x23014250 }, 2901 { 0x14, 0x40f000f0 }, 2902 { 0x18, 0x40f000f0 }, 2903 { 0x19, 0x40f000f0 }, 2904 { 0x1e, 0x044413b0 }, 2905 { 0x1f, 0x044413b0 }, 2906 {} 2907 }; 2908 2909 static const struct hda_pintbl dell_m4_3_pin_configs[] = { 2910 { 0x0a, 0x0421101f }, 2911 { 0x0b, 0x04a11221 }, 2912 { 0x0c, 0x90a70330 }, 2913 { 0x0d, 0x90170110 }, 2914 { 0x0e, 0x40f000f0 }, 2915 { 0x0f, 0x40f000f0 }, 2916 { 0x14, 0x40f000f0 }, 2917 { 0x18, 0x90a000f0 }, 2918 { 0x19, 0x40f000f0 }, 2919 { 0x1e, 0x044413b0 }, 2920 { 0x1f, 0x044413b0 }, 2921 {} 2922 }; 2923 2924 static void stac92hd71bxx_fixup_ref(struct hda_codec *codec, 2925 const struct hda_fixup *fix, int action) 2926 { 2927 struct sigmatel_spec *spec = codec->spec; 2928 2929 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2930 return; 2931 2932 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs); 2933 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0; 2934 } 2935 2936 static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec, 2937 const struct hda_fixup *fix, int action) 2938 { 2939 struct sigmatel_spec *spec = codec->spec; 2940 struct hda_jack_tbl *jack; 2941 2942 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2943 return; 2944 2945 /* Enable VREF power saving on GPIO1 detect */ 2946 snd_hda_codec_write_cache(codec, codec->afg, 0, 2947 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 2948 snd_hda_jack_detect_enable_callback(codec, codec->afg, 2949 STAC_VREF_EVENT, 2950 stac_vref_event); 2951 jack = snd_hda_jack_tbl_get(codec, codec->afg); 2952 if (jack) 2953 jack->private_data = 0x02; 2954 2955 spec->gpio_mask |= 0x02; 2956 2957 /* enable internal microphone */ 2958 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040); 2959 } 2960 2961 static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec, 2962 const struct hda_fixup *fix, int action) 2963 { 2964 struct sigmatel_spec *spec = codec->spec; 2965 2966 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2967 return; 2968 spec->gpio_led = 0x01; 2969 } 2970 2971 static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec, 2972 const struct hda_fixup *fix, int action) 2973 { 2974 unsigned int cap; 2975 2976 switch (action) { 2977 case HDA_FIXUP_ACT_PRE_PROBE: 2978 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 2979 break; 2980 2981 case HDA_FIXUP_ACT_PROBE: 2982 /* enable bass on HP dv7 */ 2983 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); 2984 cap &= AC_GPIO_IO_COUNT; 2985 if (cap >= 6) 2986 stac_add_hp_bass_switch(codec); 2987 break; 2988 } 2989 } 2990 2991 static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec, 2992 const struct hda_fixup *fix, int action) 2993 { 2994 struct sigmatel_spec *spec = codec->spec; 2995 2996 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2997 return; 2998 spec->gpio_led = 0x08; 2999 } 3000 3001 3002 static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, 3003 const struct hda_fixup *fix, int action) 3004 { 3005 struct sigmatel_spec *spec = codec->spec; 3006 3007 if (action != HDA_FIXUP_ACT_PRE_PROBE) 3008 return; 3009 3010 if (hp_blike_system(codec->subsystem_id)) { 3011 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); 3012 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || 3013 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || 3014 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { 3015 /* It was changed in the BIOS to just satisfy MS DTM. 3016 * Lets turn it back into slaved HP 3017 */ 3018 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) 3019 | (AC_JACK_HP_OUT << 3020 AC_DEFCFG_DEVICE_SHIFT); 3021 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC 3022 | AC_DEFCFG_SEQUENCE))) 3023 | 0x1f; 3024 snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); 3025 } 3026 } 3027 3028 if (find_mute_led_cfg(codec, 1)) 3029 snd_printd("mute LED gpio %d polarity %d\n", 3030 spec->gpio_led, 3031 spec->gpio_led_polarity); 3032 3033 } 3034 3035 static const struct hda_fixup stac92hd71bxx_fixups[] = { 3036 [STAC_92HD71BXX_REF] = { 3037 .type = HDA_FIXUP_FUNC, 3038 .v.func = stac92hd71bxx_fixup_ref, 3039 }, 3040 [STAC_DELL_M4_1] = { 3041 .type = HDA_FIXUP_PINS, 3042 .v.pins = dell_m4_1_pin_configs, 3043 }, 3044 [STAC_DELL_M4_2] = { 3045 .type = HDA_FIXUP_PINS, 3046 .v.pins = dell_m4_2_pin_configs, 3047 }, 3048 [STAC_DELL_M4_3] = { 3049 .type = HDA_FIXUP_PINS, 3050 .v.pins = dell_m4_3_pin_configs, 3051 }, 3052 [STAC_HP_M4] = { 3053 .type = HDA_FIXUP_FUNC, 3054 .v.func = stac92hd71bxx_fixup_hp_m4, 3055 .chained = true, 3056 .chain_id = STAC_92HD71BXX_HP, 3057 }, 3058 [STAC_HP_DV4] = { 3059 .type = HDA_FIXUP_FUNC, 3060 .v.func = stac92hd71bxx_fixup_hp_dv4, 3061 .chained = true, 3062 .chain_id = STAC_HP_DV5, 3063 }, 3064 [STAC_HP_DV5] = { 3065 .type = HDA_FIXUP_FUNC, 3066 .v.func = stac92hd71bxx_fixup_hp_dv5, 3067 .chained = true, 3068 .chain_id = STAC_92HD71BXX_HP, 3069 }, 3070 [STAC_HP_HDX] = { 3071 .type = HDA_FIXUP_FUNC, 3072 .v.func = stac92hd71bxx_fixup_hp_hdx, 3073 .chained = true, 3074 .chain_id = STAC_92HD71BXX_HP, 3075 }, 3076 [STAC_92HD71BXX_HP] = { 3077 .type = HDA_FIXUP_FUNC, 3078 .v.func = stac92hd71bxx_fixup_hp, 3079 }, 3080 }; 3081 3082 static const struct hda_model_fixup stac92hd71bxx_models[] = { 3083 { .id = STAC_92HD71BXX_REF, .name = "ref" }, 3084 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" }, 3085 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" }, 3086 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" }, 3087 { .id = STAC_HP_M4, .name = "hp-m4" }, 3088 { .id = STAC_HP_DV4, .name = "hp-dv4" }, 3089 { .id = STAC_HP_DV5, .name = "hp-dv5" }, 3090 { .id = STAC_HP_HDX, .name = "hp-hdx" }, 3091 { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" }, 3092 {} 3093 }; 3094 3095 static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = { 3096 /* SigmaTel reference board */ 3097 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 3098 "DFI LanParty", STAC_92HD71BXX_REF), 3099 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 3100 "DFI LanParty", STAC_92HD71BXX_REF), 3101 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720, 3102 "HP", STAC_HP_DV5), 3103 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, 3104 "HP", STAC_HP_DV5), 3105 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, 3106 "HP dv4-7", STAC_HP_DV4), 3107 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, 3108 "HP dv4-7", STAC_HP_DV5), 3109 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, 3110 "HP HDX", STAC_HP_HDX), /* HDX18 */ 3111 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 3112 "HP mini 1000", STAC_HP_M4), 3113 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, 3114 "HP HDX", STAC_HP_HDX), /* HDX16 */ 3115 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, 3116 "HP dv6", STAC_HP_DV5), 3117 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, 3118 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ 3119 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e, 3120 "HP DV6", STAC_HP_DV5), 3121 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, 3122 "HP", STAC_HP_DV5), 3123 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP), 3124 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 3125 "unknown Dell", STAC_DELL_M4_1), 3126 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, 3127 "unknown Dell", STAC_DELL_M4_1), 3128 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250, 3129 "unknown Dell", STAC_DELL_M4_1), 3130 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f, 3131 "unknown Dell", STAC_DELL_M4_1), 3132 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d, 3133 "unknown Dell", STAC_DELL_M4_1), 3134 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251, 3135 "unknown Dell", STAC_DELL_M4_1), 3136 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277, 3137 "unknown Dell", STAC_DELL_M4_1), 3138 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263, 3139 "unknown Dell", STAC_DELL_M4_2), 3140 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265, 3141 "unknown Dell", STAC_DELL_M4_2), 3142 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262, 3143 "unknown Dell", STAC_DELL_M4_2), 3144 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264, 3145 "unknown Dell", STAC_DELL_M4_2), 3146 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa, 3147 "unknown Dell", STAC_DELL_M4_3), 3148 {} /* terminator */ 3149 }; 3150 3151 static const struct hda_pintbl ref922x_pin_configs[] = { 3152 { 0x0a, 0x01014010 }, 3153 { 0x0b, 0x01016011 }, 3154 { 0x0c, 0x01012012 }, 3155 { 0x0d, 0x0221401f }, 3156 { 0x0e, 0x01813122 }, 3157 { 0x0f, 0x01011014 }, 3158 { 0x10, 0x01441030 }, 3159 { 0x11, 0x01c41030 }, 3160 { 0x15, 0x40000100 }, 3161 { 0x1b, 0x40000100 }, 3162 {} 3163 }; 3164 3165 /* 3166 STAC 922X pin configs for 3167 102801A7 3168 102801AB 3169 102801A9 3170 102801D1 3171 102801D2 3172 */ 3173 static const struct hda_pintbl dell_922x_d81_pin_configs[] = { 3174 { 0x0a, 0x02214030 }, 3175 { 0x0b, 0x01a19021 }, 3176 { 0x0c, 0x01111012 }, 3177 { 0x0d, 0x01114010 }, 3178 { 0x0e, 0x02a19020 }, 3179 { 0x0f, 0x01117011 }, 3180 { 0x10, 0x400001f0 }, 3181 { 0x11, 0x400001f1 }, 3182 { 0x15, 0x01813122 }, 3183 { 0x1b, 0x400001f2 }, 3184 {} 3185 }; 3186 3187 /* 3188 STAC 922X pin configs for 3189 102801AC 3190 102801D0 3191 */ 3192 static const struct hda_pintbl dell_922x_d82_pin_configs[] = { 3193 { 0x0a, 0x02214030 }, 3194 { 0x0b, 0x01a19021 }, 3195 { 0x0c, 0x01111012 }, 3196 { 0x0d, 0x01114010 }, 3197 { 0x0e, 0x02a19020 }, 3198 { 0x0f, 0x01117011 }, 3199 { 0x10, 0x01451140 }, 3200 { 0x11, 0x400001f0 }, 3201 { 0x15, 0x01813122 }, 3202 { 0x1b, 0x400001f1 }, 3203 {} 3204 }; 3205 3206 /* 3207 STAC 922X pin configs for 3208 102801BF 3209 */ 3210 static const struct hda_pintbl dell_922x_m81_pin_configs[] = { 3211 { 0x0a, 0x0321101f }, 3212 { 0x0b, 0x01112024 }, 3213 { 0x0c, 0x01111222 }, 3214 { 0x0d, 0x91174220 }, 3215 { 0x0e, 0x03a11050 }, 3216 { 0x0f, 0x01116221 }, 3217 { 0x10, 0x90a70330 }, 3218 { 0x11, 0x01452340 }, 3219 { 0x15, 0x40C003f1 }, 3220 { 0x1b, 0x405003f0 }, 3221 {} 3222 }; 3223 3224 /* 3225 STAC 9221 A1 pin configs for 3226 102801D7 (Dell XPS M1210) 3227 */ 3228 static const struct hda_pintbl dell_922x_m82_pin_configs[] = { 3229 { 0x0a, 0x02211211 }, 3230 { 0x0b, 0x408103ff }, 3231 { 0x0c, 0x02a1123e }, 3232 { 0x0d, 0x90100310 }, 3233 { 0x0e, 0x408003f1 }, 3234 { 0x0f, 0x0221121f }, 3235 { 0x10, 0x03451340 }, 3236 { 0x11, 0x40c003f2 }, 3237 { 0x15, 0x508003f3 }, 3238 { 0x1b, 0x405003f4 }, 3239 {} 3240 }; 3241 3242 static const struct hda_pintbl d945gtp3_pin_configs[] = { 3243 { 0x0a, 0x0221401f }, 3244 { 0x0b, 0x01a19022 }, 3245 { 0x0c, 0x01813021 }, 3246 { 0x0d, 0x01014010 }, 3247 { 0x0e, 0x40000100 }, 3248 { 0x0f, 0x40000100 }, 3249 { 0x10, 0x40000100 }, 3250 { 0x11, 0x40000100 }, 3251 { 0x15, 0x02a19120 }, 3252 { 0x1b, 0x40000100 }, 3253 {} 3254 }; 3255 3256 static const struct hda_pintbl d945gtp5_pin_configs[] = { 3257 { 0x0a, 0x0221401f }, 3258 { 0x0b, 0x01011012 }, 3259 { 0x0c, 0x01813024 }, 3260 { 0x0d, 0x01014010 }, 3261 { 0x0e, 0x01a19021 }, 3262 { 0x0f, 0x01016011 }, 3263 { 0x10, 0x01452130 }, 3264 { 0x11, 0x40000100 }, 3265 { 0x15, 0x02a19320 }, 3266 { 0x1b, 0x40000100 }, 3267 {} 3268 }; 3269 3270 static const struct hda_pintbl intel_mac_v1_pin_configs[] = { 3271 { 0x0a, 0x0121e21f }, 3272 { 0x0b, 0x400000ff }, 3273 { 0x0c, 0x9017e110 }, 3274 { 0x0d, 0x400000fd }, 3275 { 0x0e, 0x400000fe }, 3276 { 0x0f, 0x0181e020 }, 3277 { 0x10, 0x1145e030 }, 3278 { 0x11, 0x11c5e240 }, 3279 { 0x15, 0x400000fc }, 3280 { 0x1b, 0x400000fb }, 3281 {} 3282 }; 3283 3284 static const struct hda_pintbl intel_mac_v2_pin_configs[] = { 3285 { 0x0a, 0x0121e21f }, 3286 { 0x0b, 0x90a7012e }, 3287 { 0x0c, 0x9017e110 }, 3288 { 0x0d, 0x400000fd }, 3289 { 0x0e, 0x400000fe }, 3290 { 0x0f, 0x0181e020 }, 3291 { 0x10, 0x1145e230 }, 3292 { 0x11, 0x500000fa }, 3293 { 0x15, 0x400000fc }, 3294 { 0x1b, 0x400000fb }, 3295 {} 3296 }; 3297 3298 static const struct hda_pintbl intel_mac_v3_pin_configs[] = { 3299 { 0x0a, 0x0121e21f }, 3300 { 0x0b, 0x90a7012e }, 3301 { 0x0c, 0x9017e110 }, 3302 { 0x0d, 0x400000fd }, 3303 { 0x0e, 0x400000fe }, 3304 { 0x0f, 0x0181e020 }, 3305 { 0x10, 0x1145e230 }, 3306 { 0x11, 0x11c5e240 }, 3307 { 0x15, 0x400000fc }, 3308 { 0x1b, 0x400000fb }, 3309 {} 3310 }; 3311 3312 static const struct hda_pintbl intel_mac_v4_pin_configs[] = { 3313 { 0x0a, 0x0321e21f }, 3314 { 0x0b, 0x03a1e02e }, 3315 { 0x0c, 0x9017e110 }, 3316 { 0x0d, 0x9017e11f }, 3317 { 0x0e, 0x400000fe }, 3318 { 0x0f, 0x0381e020 }, 3319 { 0x10, 0x1345e230 }, 3320 { 0x11, 0x13c5e240 }, 3321 { 0x15, 0x400000fc }, 3322 { 0x1b, 0x400000fb }, 3323 {} 3324 }; 3325 3326 static const struct hda_pintbl intel_mac_v5_pin_configs[] = { 3327 { 0x0a, 0x0321e21f }, 3328 { 0x0b, 0x03a1e02e }, 3329 { 0x0c, 0x9017e110 }, 3330 { 0x0d, 0x9017e11f }, 3331 { 0x0e, 0x400000fe }, 3332 { 0x0f, 0x0381e020 }, 3333 { 0x10, 0x1345e230 }, 3334 { 0x11, 0x13c5e240 }, 3335 { 0x15, 0x400000fc }, 3336 { 0x1b, 0x400000fb }, 3337 {} 3338 }; 3339 3340 static const struct hda_pintbl ecs202_pin_configs[] = { 3341 { 0x0a, 0x0221401f }, 3342 { 0x0b, 0x02a19020 }, 3343 { 0x0c, 0x01a19020 }, 3344 { 0x0d, 0x01114010 }, 3345 { 0x0e, 0x408000f0 }, 3346 { 0x0f, 0x01813022 }, 3347 { 0x10, 0x074510a0 }, 3348 { 0x11, 0x40c400f1 }, 3349 { 0x15, 0x9037012e }, 3350 { 0x1b, 0x40e000f2 }, 3351 {} 3352 }; 3353 3354 /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */ 3355 static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = { 3356 SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3), 3357 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1), 3358 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2), 3359 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2), 3360 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3), 3361 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3), 3362 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3), 3363 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3), 3364 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3), 3365 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3), 3366 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4), 3367 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5), 3368 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5), 3369 {} 3370 }; 3371 3372 static const struct hda_fixup stac922x_fixups[]; 3373 3374 /* remap the fixup from codec SSID and apply it */ 3375 static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec, 3376 const struct hda_fixup *fix, 3377 int action) 3378 { 3379 if (action != HDA_FIXUP_ACT_PRE_PROBE) 3380 return; 3381 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl, 3382 stac922x_fixups); 3383 if (codec->fixup_id != STAC_INTEL_MAC_AUTO) 3384 snd_hda_apply_fixup(codec, action); 3385 } 3386 3387 static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec, 3388 const struct hda_fixup *fix, 3389 int action) 3390 { 3391 struct sigmatel_spec *spec = codec->spec; 3392 3393 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3394 spec->gpio_mask = spec->gpio_dir = 0x03; 3395 spec->gpio_data = 0x03; 3396 } 3397 } 3398 3399 static const struct hda_fixup stac922x_fixups[] = { 3400 [STAC_D945_REF] = { 3401 .type = HDA_FIXUP_PINS, 3402 .v.pins = ref922x_pin_configs, 3403 }, 3404 [STAC_D945GTP3] = { 3405 .type = HDA_FIXUP_PINS, 3406 .v.pins = d945gtp3_pin_configs, 3407 }, 3408 [STAC_D945GTP5] = { 3409 .type = HDA_FIXUP_PINS, 3410 .v.pins = d945gtp5_pin_configs, 3411 }, 3412 [STAC_INTEL_MAC_AUTO] = { 3413 .type = HDA_FIXUP_FUNC, 3414 .v.func = stac922x_fixup_intel_mac_auto, 3415 }, 3416 [STAC_INTEL_MAC_V1] = { 3417 .type = HDA_FIXUP_PINS, 3418 .v.pins = intel_mac_v1_pin_configs, 3419 .chained = true, 3420 .chain_id = STAC_922X_INTEL_MAC_GPIO, 3421 }, 3422 [STAC_INTEL_MAC_V2] = { 3423 .type = HDA_FIXUP_PINS, 3424 .v.pins = intel_mac_v2_pin_configs, 3425 .chained = true, 3426 .chain_id = STAC_922X_INTEL_MAC_GPIO, 3427 }, 3428 [STAC_INTEL_MAC_V3] = { 3429 .type = HDA_FIXUP_PINS, 3430 .v.pins = intel_mac_v3_pin_configs, 3431 .chained = true, 3432 .chain_id = STAC_922X_INTEL_MAC_GPIO, 3433 }, 3434 [STAC_INTEL_MAC_V4] = { 3435 .type = HDA_FIXUP_PINS, 3436 .v.pins = intel_mac_v4_pin_configs, 3437 .chained = true, 3438 .chain_id = STAC_922X_INTEL_MAC_GPIO, 3439 }, 3440 [STAC_INTEL_MAC_V5] = { 3441 .type = HDA_FIXUP_PINS, 3442 .v.pins = intel_mac_v5_pin_configs, 3443 .chained = true, 3444 .chain_id = STAC_922X_INTEL_MAC_GPIO, 3445 }, 3446 [STAC_922X_INTEL_MAC_GPIO] = { 3447 .type = HDA_FIXUP_FUNC, 3448 .v.func = stac922x_fixup_intel_mac_gpio, 3449 }, 3450 [STAC_ECS_202] = { 3451 .type = HDA_FIXUP_PINS, 3452 .v.pins = ecs202_pin_configs, 3453 }, 3454 [STAC_922X_DELL_D81] = { 3455 .type = HDA_FIXUP_PINS, 3456 .v.pins = dell_922x_d81_pin_configs, 3457 }, 3458 [STAC_922X_DELL_D82] = { 3459 .type = HDA_FIXUP_PINS, 3460 .v.pins = dell_922x_d82_pin_configs, 3461 }, 3462 [STAC_922X_DELL_M81] = { 3463 .type = HDA_FIXUP_PINS, 3464 .v.pins = dell_922x_m81_pin_configs, 3465 }, 3466 [STAC_922X_DELL_M82] = { 3467 .type = HDA_FIXUP_PINS, 3468 .v.pins = dell_922x_m82_pin_configs, 3469 }, 3470 }; 3471 3472 static const struct hda_model_fixup stac922x_models[] = { 3473 { .id = STAC_D945_REF, .name = "ref" }, 3474 { .id = STAC_D945GTP5, .name = "5stack" }, 3475 { .id = STAC_D945GTP3, .name = "3stack" }, 3476 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" }, 3477 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" }, 3478 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" }, 3479 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" }, 3480 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" }, 3481 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" }, 3482 { .id = STAC_ECS_202, .name = "ecs202" }, 3483 { .id = STAC_922X_DELL_D81, .name = "dell-d81" }, 3484 { .id = STAC_922X_DELL_D82, .name = "dell-d82" }, 3485 { .id = STAC_922X_DELL_M81, .name = "dell-m81" }, 3486 { .id = STAC_922X_DELL_M82, .name = "dell-m82" }, 3487 /* for backward compatibility */ 3488 { .id = STAC_INTEL_MAC_V3, .name = "macmini" }, 3489 { .id = STAC_INTEL_MAC_V5, .name = "macbook" }, 3490 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" }, 3491 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" }, 3492 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" }, 3493 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" }, 3494 {} 3495 }; 3496 3497 static const struct snd_pci_quirk stac922x_fixup_tbl[] = { 3498 /* SigmaTel reference board */ 3499 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 3500 "DFI LanParty", STAC_D945_REF), 3501 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 3502 "DFI LanParty", STAC_D945_REF), 3503 /* Intel 945G based systems */ 3504 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, 3505 "Intel D945G", STAC_D945GTP3), 3506 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202, 3507 "Intel D945G", STAC_D945GTP3), 3508 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606, 3509 "Intel D945G", STAC_D945GTP3), 3510 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601, 3511 "Intel D945G", STAC_D945GTP3), 3512 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111, 3513 "Intel D945G", STAC_D945GTP3), 3514 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115, 3515 "Intel D945G", STAC_D945GTP3), 3516 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116, 3517 "Intel D945G", STAC_D945GTP3), 3518 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117, 3519 "Intel D945G", STAC_D945GTP3), 3520 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118, 3521 "Intel D945G", STAC_D945GTP3), 3522 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119, 3523 "Intel D945G", STAC_D945GTP3), 3524 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826, 3525 "Intel D945G", STAC_D945GTP3), 3526 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049, 3527 "Intel D945G", STAC_D945GTP3), 3528 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055, 3529 "Intel D945G", STAC_D945GTP3), 3530 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048, 3531 "Intel D945G", STAC_D945GTP3), 3532 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110, 3533 "Intel D945G", STAC_D945GTP3), 3534 /* Intel D945G 5-stack systems */ 3535 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404, 3536 "Intel D945G", STAC_D945GTP5), 3537 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303, 3538 "Intel D945G", STAC_D945GTP5), 3539 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013, 3540 "Intel D945G", STAC_D945GTP5), 3541 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417, 3542 "Intel D945G", STAC_D945GTP5), 3543 /* Intel 945P based systems */ 3544 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b, 3545 "Intel D945P", STAC_D945GTP3), 3546 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112, 3547 "Intel D945P", STAC_D945GTP3), 3548 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d, 3549 "Intel D945P", STAC_D945GTP3), 3550 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909, 3551 "Intel D945P", STAC_D945GTP3), 3552 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505, 3553 "Intel D945P", STAC_D945GTP3), 3554 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, 3555 "Intel D945P", STAC_D945GTP5), 3556 /* other intel */ 3557 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204, 3558 "Intel D945", STAC_D945_REF), 3559 /* other systems */ 3560 3561 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ 3562 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO), 3563 3564 /* Dell systems */ 3565 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, 3566 "unknown Dell", STAC_922X_DELL_D81), 3567 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9, 3568 "unknown Dell", STAC_922X_DELL_D81), 3569 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab, 3570 "unknown Dell", STAC_922X_DELL_D81), 3571 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac, 3572 "unknown Dell", STAC_922X_DELL_D82), 3573 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf, 3574 "unknown Dell", STAC_922X_DELL_M81), 3575 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0, 3576 "unknown Dell", STAC_922X_DELL_D82), 3577 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1, 3578 "unknown Dell", STAC_922X_DELL_D81), 3579 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2, 3580 "unknown Dell", STAC_922X_DELL_D81), 3581 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, 3582 "Dell XPS M1210", STAC_922X_DELL_M82), 3583 /* ECS/PC Chips boards */ 3584 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000, 3585 "ECS/PC chips", STAC_ECS_202), 3586 {} /* terminator */ 3587 }; 3588 3589 static const struct hda_pintbl ref927x_pin_configs[] = { 3590 { 0x0a, 0x02214020 }, 3591 { 0x0b, 0x02a19080 }, 3592 { 0x0c, 0x0181304e }, 3593 { 0x0d, 0x01014010 }, 3594 { 0x0e, 0x01a19040 }, 3595 { 0x0f, 0x01011012 }, 3596 { 0x10, 0x01016011 }, 3597 { 0x11, 0x0101201f }, 3598 { 0x12, 0x183301f0 }, 3599 { 0x13, 0x18a001f0 }, 3600 { 0x14, 0x18a001f0 }, 3601 { 0x21, 0x01442070 }, 3602 { 0x22, 0x01c42190 }, 3603 { 0x23, 0x40000100 }, 3604 {} 3605 }; 3606 3607 static const struct hda_pintbl d965_3st_pin_configs[] = { 3608 { 0x0a, 0x0221401f }, 3609 { 0x0b, 0x02a19120 }, 3610 { 0x0c, 0x40000100 }, 3611 { 0x0d, 0x01014011 }, 3612 { 0x0e, 0x01a19021 }, 3613 { 0x0f, 0x01813024 }, 3614 { 0x10, 0x40000100 }, 3615 { 0x11, 0x40000100 }, 3616 { 0x12, 0x40000100 }, 3617 { 0x13, 0x40000100 }, 3618 { 0x14, 0x40000100 }, 3619 { 0x21, 0x40000100 }, 3620 { 0x22, 0x40000100 }, 3621 { 0x23, 0x40000100 }, 3622 {} 3623 }; 3624 3625 static const struct hda_pintbl d965_5st_pin_configs[] = { 3626 { 0x0a, 0x02214020 }, 3627 { 0x0b, 0x02a19080 }, 3628 { 0x0c, 0x0181304e }, 3629 { 0x0d, 0x01014010 }, 3630 { 0x0e, 0x01a19040 }, 3631 { 0x0f, 0x01011012 }, 3632 { 0x10, 0x01016011 }, 3633 { 0x11, 0x40000100 }, 3634 { 0x12, 0x40000100 }, 3635 { 0x13, 0x40000100 }, 3636 { 0x14, 0x40000100 }, 3637 { 0x21, 0x01442070 }, 3638 { 0x22, 0x40000100 }, 3639 { 0x23, 0x40000100 }, 3640 {} 3641 }; 3642 3643 static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = { 3644 { 0x0a, 0x40000100 }, 3645 { 0x0b, 0x40000100 }, 3646 { 0x0c, 0x0181304e }, 3647 { 0x0d, 0x01014010 }, 3648 { 0x0e, 0x01a19040 }, 3649 { 0x0f, 0x01011012 }, 3650 { 0x10, 0x01016011 }, 3651 { 0x11, 0x40000100 }, 3652 { 0x12, 0x40000100 }, 3653 { 0x13, 0x40000100 }, 3654 { 0x14, 0x40000100 }, 3655 { 0x21, 0x01442070 }, 3656 { 0x22, 0x40000100 }, 3657 { 0x23, 0x40000100 }, 3658 {} 3659 }; 3660 3661 static const struct hda_pintbl dell_3st_pin_configs[] = { 3662 { 0x0a, 0x02211230 }, 3663 { 0x0b, 0x02a11220 }, 3664 { 0x0c, 0x01a19040 }, 3665 { 0x0d, 0x01114210 }, 3666 { 0x0e, 0x01111212 }, 3667 { 0x0f, 0x01116211 }, 3668 { 0x10, 0x01813050 }, 3669 { 0x11, 0x01112214 }, 3670 { 0x12, 0x403003fa }, 3671 { 0x13, 0x90a60040 }, 3672 { 0x14, 0x90a60040 }, 3673 { 0x21, 0x404003fb }, 3674 { 0x22, 0x40c003fc }, 3675 { 0x23, 0x40000100 }, 3676 {} 3677 }; 3678 3679 static void stac927x_fixup_ref_no_jd(struct hda_codec *codec, 3680 const struct hda_fixup *fix, int action) 3681 { 3682 /* no jack detecion for ref-no-jd model */ 3683 if (action == HDA_FIXUP_ACT_PRE_PROBE) 3684 codec->no_jack_detect = 1; 3685 } 3686 3687 static void stac927x_fixup_ref(struct hda_codec *codec, 3688 const struct hda_fixup *fix, int action) 3689 { 3690 struct sigmatel_spec *spec = codec->spec; 3691 3692 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3693 snd_hda_apply_pincfgs(codec, ref927x_pin_configs); 3694 spec->eapd_mask = spec->gpio_mask = 0; 3695 spec->gpio_dir = spec->gpio_data = 0; 3696 } 3697 } 3698 3699 static void stac927x_fixup_dell_dmic(struct hda_codec *codec, 3700 const struct hda_fixup *fix, int action) 3701 { 3702 struct sigmatel_spec *spec = codec->spec; 3703 3704 if (action != HDA_FIXUP_ACT_PRE_PROBE) 3705 return; 3706 3707 if (codec->subsystem_id != 0x1028022f) { 3708 /* GPIO2 High = Enable EAPD */ 3709 spec->eapd_mask = spec->gpio_mask = 0x04; 3710 spec->gpio_dir = spec->gpio_data = 0x04; 3711 } 3712 3713 snd_hda_add_verbs(codec, dell_3st_core_init); 3714 spec->volknob_init = 1; 3715 } 3716 3717 static void stac927x_fixup_volknob(struct hda_codec *codec, 3718 const struct hda_fixup *fix, int action) 3719 { 3720 struct sigmatel_spec *spec = codec->spec; 3721 3722 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3723 snd_hda_add_verbs(codec, stac927x_volknob_core_init); 3724 spec->volknob_init = 1; 3725 } 3726 } 3727 3728 static const struct hda_fixup stac927x_fixups[] = { 3729 [STAC_D965_REF_NO_JD] = { 3730 .type = HDA_FIXUP_FUNC, 3731 .v.func = stac927x_fixup_ref_no_jd, 3732 .chained = true, 3733 .chain_id = STAC_D965_REF, 3734 }, 3735 [STAC_D965_REF] = { 3736 .type = HDA_FIXUP_FUNC, 3737 .v.func = stac927x_fixup_ref, 3738 }, 3739 [STAC_D965_3ST] = { 3740 .type = HDA_FIXUP_PINS, 3741 .v.pins = d965_3st_pin_configs, 3742 .chained = true, 3743 .chain_id = STAC_D965_VERBS, 3744 }, 3745 [STAC_D965_5ST] = { 3746 .type = HDA_FIXUP_PINS, 3747 .v.pins = d965_5st_pin_configs, 3748 .chained = true, 3749 .chain_id = STAC_D965_VERBS, 3750 }, 3751 [STAC_D965_VERBS] = { 3752 .type = HDA_FIXUP_VERBS, 3753 .v.verbs = d965_core_init, 3754 }, 3755 [STAC_D965_5ST_NO_FP] = { 3756 .type = HDA_FIXUP_PINS, 3757 .v.pins = d965_5st_no_fp_pin_configs, 3758 }, 3759 [STAC_DELL_3ST] = { 3760 .type = HDA_FIXUP_PINS, 3761 .v.pins = dell_3st_pin_configs, 3762 .chained = true, 3763 .chain_id = STAC_927X_DELL_DMIC, 3764 }, 3765 [STAC_DELL_BIOS] = { 3766 .type = HDA_FIXUP_PINS, 3767 .v.pins = (const struct hda_pintbl[]) { 3768 /* correct the front output jack as a hp out */ 3769 { 0x0f, 0x0221101f }, 3770 /* correct the front input jack as a mic */ 3771 { 0x0e, 0x02a79130 }, 3772 {} 3773 }, 3774 .chained = true, 3775 .chain_id = STAC_927X_DELL_DMIC, 3776 }, 3777 [STAC_DELL_BIOS_AMIC] = { 3778 .type = HDA_FIXUP_PINS, 3779 .v.pins = (const struct hda_pintbl[]) { 3780 /* configure the analog microphone on some laptops */ 3781 { 0x0c, 0x90a79130 }, 3782 {} 3783 }, 3784 .chained = true, 3785 .chain_id = STAC_DELL_BIOS, 3786 }, 3787 [STAC_DELL_BIOS_SPDIF] = { 3788 .type = HDA_FIXUP_PINS, 3789 .v.pins = (const struct hda_pintbl[]) { 3790 /* correct the device field to SPDIF out */ 3791 { 0x21, 0x01442070 }, 3792 {} 3793 }, 3794 .chained = true, 3795 .chain_id = STAC_DELL_BIOS, 3796 }, 3797 [STAC_927X_DELL_DMIC] = { 3798 .type = HDA_FIXUP_FUNC, 3799 .v.func = stac927x_fixup_dell_dmic, 3800 }, 3801 [STAC_927X_VOLKNOB] = { 3802 .type = HDA_FIXUP_FUNC, 3803 .v.func = stac927x_fixup_volknob, 3804 }, 3805 }; 3806 3807 static const struct hda_model_fixup stac927x_models[] = { 3808 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" }, 3809 { .id = STAC_D965_REF, .name = "ref" }, 3810 { .id = STAC_D965_3ST, .name = "3stack" }, 3811 { .id = STAC_D965_5ST, .name = "5stack" }, 3812 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" }, 3813 { .id = STAC_DELL_3ST, .name = "dell-3stack" }, 3814 { .id = STAC_DELL_BIOS, .name = "dell-bios" }, 3815 { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" }, 3816 { .id = STAC_927X_VOLKNOB, .name = "volknob" }, 3817 {} 3818 }; 3819 3820 static const struct snd_pci_quirk stac927x_fixup_tbl[] = { 3821 /* SigmaTel reference board */ 3822 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 3823 "DFI LanParty", STAC_D965_REF), 3824 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 3825 "DFI LanParty", STAC_D965_REF), 3826 /* Intel 946 based systems */ 3827 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), 3828 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), 3829 /* 965 based 3 stack systems */ 3830 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100, 3831 "Intel D965", STAC_D965_3ST), 3832 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, 3833 "Intel D965", STAC_D965_3ST), 3834 /* Dell 3 stack systems */ 3835 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), 3836 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), 3837 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), 3838 /* Dell 3 stack systems with verb table in BIOS */ 3839 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), 3840 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS), 3841 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), 3842 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF), 3843 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), 3844 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), 3845 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), 3846 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), 3847 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF), 3848 /* 965 based 5 stack systems */ 3849 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, 3850 "Intel D965", STAC_D965_5ST), 3851 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500, 3852 "Intel D965", STAC_D965_5ST), 3853 /* volume-knob fixes */ 3854 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB), 3855 {} /* terminator */ 3856 }; 3857 3858 static const struct hda_pintbl ref9205_pin_configs[] = { 3859 { 0x0a, 0x40000100 }, 3860 { 0x0b, 0x40000100 }, 3861 { 0x0c, 0x01016011 }, 3862 { 0x0d, 0x01014010 }, 3863 { 0x0e, 0x01813122 }, 3864 { 0x0f, 0x01a19021 }, 3865 { 0x14, 0x01019020 }, 3866 { 0x16, 0x40000100 }, 3867 { 0x17, 0x90a000f0 }, 3868 { 0x18, 0x90a000f0 }, 3869 { 0x21, 0x01441030 }, 3870 { 0x22, 0x01c41030 }, 3871 {} 3872 }; 3873 3874 /* 3875 STAC 9205 pin configs for 3876 102801F1 3877 102801F2 3878 102801FC 3879 102801FD 3880 10280204 3881 1028021F 3882 10280228 (Dell Vostro 1500) 3883 10280229 (Dell Vostro 1700) 3884 */ 3885 static const struct hda_pintbl dell_9205_m42_pin_configs[] = { 3886 { 0x0a, 0x0321101F }, 3887 { 0x0b, 0x03A11020 }, 3888 { 0x0c, 0x400003FA }, 3889 { 0x0d, 0x90170310 }, 3890 { 0x0e, 0x400003FB }, 3891 { 0x0f, 0x400003FC }, 3892 { 0x14, 0x400003FD }, 3893 { 0x16, 0x40F000F9 }, 3894 { 0x17, 0x90A60330 }, 3895 { 0x18, 0x400003FF }, 3896 { 0x21, 0x0144131F }, 3897 { 0x22, 0x40C003FE }, 3898 {} 3899 }; 3900 3901 /* 3902 STAC 9205 pin configs for 3903 102801F9 3904 102801FA 3905 102801FE 3906 102801FF (Dell Precision M4300) 3907 10280206 3908 10280200 3909 10280201 3910 */ 3911 static const struct hda_pintbl dell_9205_m43_pin_configs[] = { 3912 { 0x0a, 0x0321101f }, 3913 { 0x0b, 0x03a11020 }, 3914 { 0x0c, 0x90a70330 }, 3915 { 0x0d, 0x90170310 }, 3916 { 0x0e, 0x400000fe }, 3917 { 0x0f, 0x400000ff }, 3918 { 0x14, 0x400000fd }, 3919 { 0x16, 0x40f000f9 }, 3920 { 0x17, 0x400000fa }, 3921 { 0x18, 0x400000fc }, 3922 { 0x21, 0x0144131f }, 3923 { 0x22, 0x40c003f8 }, 3924 /* Enable SPDIF in/out */ 3925 { 0x1f, 0x01441030 }, 3926 { 0x20, 0x1c410030 }, 3927 {} 3928 }; 3929 3930 static const struct hda_pintbl dell_9205_m44_pin_configs[] = { 3931 { 0x0a, 0x0421101f }, 3932 { 0x0b, 0x04a11020 }, 3933 { 0x0c, 0x400003fa }, 3934 { 0x0d, 0x90170310 }, 3935 { 0x0e, 0x400003fb }, 3936 { 0x0f, 0x400003fc }, 3937 { 0x14, 0x400003fd }, 3938 { 0x16, 0x400003f9 }, 3939 { 0x17, 0x90a60330 }, 3940 { 0x18, 0x400003ff }, 3941 { 0x21, 0x01441340 }, 3942 { 0x22, 0x40c003fe }, 3943 {} 3944 }; 3945 3946 static void stac9205_fixup_ref(struct hda_codec *codec, 3947 const struct hda_fixup *fix, int action) 3948 { 3949 struct sigmatel_spec *spec = codec->spec; 3950 3951 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3952 snd_hda_apply_pincfgs(codec, ref9205_pin_configs); 3953 /* SPDIF-In enabled */ 3954 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0; 3955 } 3956 } 3957 3958 static void stac9205_fixup_dell_m43(struct hda_codec *codec, 3959 const struct hda_fixup *fix, int action) 3960 { 3961 struct sigmatel_spec *spec = codec->spec; 3962 struct hda_jack_tbl *jack; 3963 3964 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3965 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs); 3966 3967 /* Enable unsol response for GPIO4/Dock HP connection */ 3968 snd_hda_codec_write_cache(codec, codec->afg, 0, 3969 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 3970 snd_hda_jack_detect_enable_callback(codec, codec->afg, 3971 STAC_VREF_EVENT, 3972 stac_vref_event); 3973 jack = snd_hda_jack_tbl_get(codec, codec->afg); 3974 if (jack) 3975 jack->private_data = 0x01; 3976 3977 spec->gpio_dir = 0x0b; 3978 spec->eapd_mask = 0x01; 3979 spec->gpio_mask = 0x1b; 3980 spec->gpio_mute = 0x10; 3981 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute, 3982 * GPIO3 Low = DRM 3983 */ 3984 spec->gpio_data = 0x01; 3985 } 3986 } 3987 3988 static void stac9205_fixup_eapd(struct hda_codec *codec, 3989 const struct hda_fixup *fix, int action) 3990 { 3991 struct sigmatel_spec *spec = codec->spec; 3992 3993 if (action == HDA_FIXUP_ACT_PRE_PROBE) 3994 spec->eapd_switch = 0; 3995 } 3996 3997 static const struct hda_fixup stac9205_fixups[] = { 3998 [STAC_9205_REF] = { 3999 .type = HDA_FIXUP_FUNC, 4000 .v.func = stac9205_fixup_ref, 4001 }, 4002 [STAC_9205_DELL_M42] = { 4003 .type = HDA_FIXUP_PINS, 4004 .v.pins = dell_9205_m42_pin_configs, 4005 }, 4006 [STAC_9205_DELL_M43] = { 4007 .type = HDA_FIXUP_FUNC, 4008 .v.func = stac9205_fixup_dell_m43, 4009 }, 4010 [STAC_9205_DELL_M44] = { 4011 .type = HDA_FIXUP_PINS, 4012 .v.pins = dell_9205_m44_pin_configs, 4013 }, 4014 [STAC_9205_EAPD] = { 4015 .type = HDA_FIXUP_FUNC, 4016 .v.func = stac9205_fixup_eapd, 4017 }, 4018 {} 4019 }; 4020 4021 static const struct hda_model_fixup stac9205_models[] = { 4022 { .id = STAC_9205_REF, .name = "ref" }, 4023 { .id = STAC_9205_DELL_M42, .name = "dell-m42" }, 4024 { .id = STAC_9205_DELL_M43, .name = "dell-m43" }, 4025 { .id = STAC_9205_DELL_M44, .name = "dell-m44" }, 4026 { .id = STAC_9205_EAPD, .name = "eapd" }, 4027 {} 4028 }; 4029 4030 static const struct snd_pci_quirk stac9205_fixup_tbl[] = { 4031 /* SigmaTel reference board */ 4032 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 4033 "DFI LanParty", STAC_9205_REF), 4034 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30, 4035 "SigmaTel", STAC_9205_REF), 4036 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 4037 "DFI LanParty", STAC_9205_REF), 4038 /* Dell */ 4039 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, 4040 "unknown Dell", STAC_9205_DELL_M42), 4041 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, 4042 "unknown Dell", STAC_9205_DELL_M42), 4043 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, 4044 "Dell Precision", STAC_9205_DELL_M43), 4045 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, 4046 "Dell Precision", STAC_9205_DELL_M43), 4047 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, 4048 "Dell Precision", STAC_9205_DELL_M43), 4049 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, 4050 "unknown Dell", STAC_9205_DELL_M42), 4051 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, 4052 "unknown Dell", STAC_9205_DELL_M42), 4053 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe, 4054 "Dell Precision", STAC_9205_DELL_M43), 4055 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, 4056 "Dell Precision M4300", STAC_9205_DELL_M43), 4057 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, 4058 "unknown Dell", STAC_9205_DELL_M42), 4059 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, 4060 "Dell Precision", STAC_9205_DELL_M43), 4061 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, 4062 "Dell Precision", STAC_9205_DELL_M43), 4063 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, 4064 "Dell Precision", STAC_9205_DELL_M43), 4065 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, 4066 "Dell Inspiron", STAC_9205_DELL_M44), 4067 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, 4068 "Dell Vostro 1500", STAC_9205_DELL_M42), 4069 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229, 4070 "Dell Vostro 1700", STAC_9205_DELL_M42), 4071 /* Gateway */ 4072 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD), 4073 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), 4074 {} /* terminator */ 4075 }; 4076 4077 static int stac_parse_auto_config(struct hda_codec *codec) 4078 { 4079 struct sigmatel_spec *spec = codec->spec; 4080 int err; 4081 int flags = 0; 4082 4083 if (spec->headset_jack) 4084 flags |= HDA_PINCFG_HEADSET_MIC; 4085 4086 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags); 4087 if (err < 0) 4088 return err; 4089 4090 /* add hooks */ 4091 spec->gen.pcm_playback_hook = stac_playback_pcm_hook; 4092 spec->gen.pcm_capture_hook = stac_capture_pcm_hook; 4093 4094 spec->gen.automute_hook = stac_update_outputs; 4095 spec->gen.hp_automute_hook = stac_hp_automute; 4096 spec->gen.line_automute_hook = stac_line_automute; 4097 spec->gen.mic_autoswitch_hook = stac_mic_autoswitch; 4098 4099 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); 4100 if (err < 0) 4101 return err; 4102 4103 /* minimum value is actually mute */ 4104 spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; 4105 4106 /* setup analog beep controls */ 4107 if (spec->anabeep_nid > 0) { 4108 err = stac_auto_create_beep_ctls(codec, 4109 spec->anabeep_nid); 4110 if (err < 0) 4111 return err; 4112 } 4113 4114 /* setup digital beep controls and input device */ 4115 #ifdef CONFIG_SND_HDA_INPUT_BEEP 4116 if (spec->gen.beep_nid) { 4117 hda_nid_t nid = spec->gen.beep_nid; 4118 unsigned int caps; 4119 4120 err = stac_auto_create_beep_ctls(codec, nid); 4121 if (err < 0) 4122 return err; 4123 if (codec->beep) { 4124 /* IDT/STAC codecs have linear beep tone parameter */ 4125 codec->beep->linear_tone = spec->linear_tone_beep; 4126 /* if no beep switch is available, make its own one */ 4127 caps = query_amp_caps(codec, nid, HDA_OUTPUT); 4128 if (!(caps & AC_AMPCAP_MUTE)) { 4129 err = stac_beep_switch_ctl(codec); 4130 if (err < 0) 4131 return err; 4132 } 4133 } 4134 } 4135 #endif 4136 4137 if (spec->gpio_led) 4138 spec->gen.vmaster_mute.hook = stac_vmaster_hook; 4139 4140 if (spec->aloopback_ctl && 4141 snd_hda_get_bool_hint(codec, "loopback") == 1) { 4142 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl)) 4143 return -ENOMEM; 4144 } 4145 4146 if (spec->have_spdif_mux) { 4147 err = stac_create_spdif_mux_ctls(codec); 4148 if (err < 0) 4149 return err; 4150 } 4151 4152 stac_init_power_map(codec); 4153 4154 return 0; 4155 } 4156 4157 4158 static int stac_init(struct hda_codec *codec) 4159 { 4160 struct sigmatel_spec *spec = codec->spec; 4161 int i; 4162 4163 /* override some hints */ 4164 stac_store_hints(codec); 4165 4166 /* set up GPIO */ 4167 /* turn on EAPD statically when spec->eapd_switch isn't set. 4168 * otherwise, unsol event will turn it on/off dynamically 4169 */ 4170 if (!spec->eapd_switch) 4171 spec->gpio_data |= spec->eapd_mask; 4172 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 4173 4174 snd_hda_gen_init(codec); 4175 4176 /* sync the power-map */ 4177 if (spec->num_pwrs) 4178 snd_hda_codec_write(codec, codec->afg, 0, 4179 AC_VERB_IDT_SET_POWER_MAP, 4180 spec->power_map_bits); 4181 4182 /* power down inactive ADCs */ 4183 if (spec->powerdown_adcs) { 4184 for (i = 0; i < spec->gen.num_all_adcs; i++) { 4185 if (spec->active_adcs & (1 << i)) 4186 continue; 4187 snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0, 4188 AC_VERB_SET_POWER_STATE, 4189 AC_PWRST_D3); 4190 } 4191 } 4192 4193 return 0; 4194 } 4195 4196 static void stac_shutup(struct hda_codec *codec) 4197 { 4198 struct sigmatel_spec *spec = codec->spec; 4199 4200 snd_hda_shutup_pins(codec); 4201 4202 if (spec->eapd_mask) 4203 stac_gpio_set(codec, spec->gpio_mask, 4204 spec->gpio_dir, spec->gpio_data & 4205 ~spec->eapd_mask); 4206 } 4207 4208 #define stac_free snd_hda_gen_free 4209 4210 #ifdef CONFIG_PROC_FS 4211 static void stac92hd_proc_hook(struct snd_info_buffer *buffer, 4212 struct hda_codec *codec, hda_nid_t nid) 4213 { 4214 if (nid == codec->afg) 4215 snd_iprintf(buffer, "Power-Map: 0x%02x\n", 4216 snd_hda_codec_read(codec, nid, 0, 4217 AC_VERB_IDT_GET_POWER_MAP, 0)); 4218 } 4219 4220 static void analog_loop_proc_hook(struct snd_info_buffer *buffer, 4221 struct hda_codec *codec, 4222 unsigned int verb) 4223 { 4224 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n", 4225 snd_hda_codec_read(codec, codec->afg, 0, verb, 0)); 4226 } 4227 4228 /* stac92hd71bxx, stac92hd73xx */ 4229 static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer, 4230 struct hda_codec *codec, hda_nid_t nid) 4231 { 4232 stac92hd_proc_hook(buffer, codec, nid); 4233 if (nid == codec->afg) 4234 analog_loop_proc_hook(buffer, codec, 0xfa0); 4235 } 4236 4237 static void stac9205_proc_hook(struct snd_info_buffer *buffer, 4238 struct hda_codec *codec, hda_nid_t nid) 4239 { 4240 if (nid == codec->afg) 4241 analog_loop_proc_hook(buffer, codec, 0xfe0); 4242 } 4243 4244 static void stac927x_proc_hook(struct snd_info_buffer *buffer, 4245 struct hda_codec *codec, hda_nid_t nid) 4246 { 4247 if (nid == codec->afg) 4248 analog_loop_proc_hook(buffer, codec, 0xfeb); 4249 } 4250 #else 4251 #define stac92hd_proc_hook NULL 4252 #define stac92hd7x_proc_hook NULL 4253 #define stac9205_proc_hook NULL 4254 #define stac927x_proc_hook NULL 4255 #endif 4256 4257 #ifdef CONFIG_PM 4258 static int stac_suspend(struct hda_codec *codec) 4259 { 4260 stac_shutup(codec); 4261 return 0; 4262 } 4263 4264 static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg, 4265 unsigned int power_state) 4266 { 4267 unsigned int afg_power_state = power_state; 4268 struct sigmatel_spec *spec = codec->spec; 4269 4270 if (power_state == AC_PWRST_D3) { 4271 if (spec->vref_mute_led_nid) { 4272 /* with vref-out pin used for mute led control 4273 * codec AFG is prevented from D3 state 4274 */ 4275 afg_power_state = AC_PWRST_D1; 4276 } 4277 /* this delay seems necessary to avoid click noise at power-down */ 4278 msleep(100); 4279 } 4280 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 4281 afg_power_state); 4282 snd_hda_codec_set_power_to_all(codec, fg, power_state); 4283 } 4284 #else 4285 #define stac_suspend NULL 4286 #define stac_set_power_state NULL 4287 #endif /* CONFIG_PM */ 4288 4289 static const struct hda_codec_ops stac_patch_ops = { 4290 .build_controls = snd_hda_gen_build_controls, 4291 .build_pcms = snd_hda_gen_build_pcms, 4292 .init = stac_init, 4293 .free = stac_free, 4294 .unsol_event = snd_hda_jack_unsol_event, 4295 #ifdef CONFIG_PM 4296 .suspend = stac_suspend, 4297 #endif 4298 .reboot_notify = stac_shutup, 4299 }; 4300 4301 static int alloc_stac_spec(struct hda_codec *codec) 4302 { 4303 struct sigmatel_spec *spec; 4304 4305 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4306 if (!spec) 4307 return -ENOMEM; 4308 snd_hda_gen_spec_init(&spec->gen); 4309 codec->spec = spec; 4310 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */ 4311 return 0; 4312 } 4313 4314 static int patch_stac9200(struct hda_codec *codec) 4315 { 4316 struct sigmatel_spec *spec; 4317 int err; 4318 4319 err = alloc_stac_spec(codec); 4320 if (err < 0) 4321 return err; 4322 4323 spec = codec->spec; 4324 spec->linear_tone_beep = 1; 4325 spec->gen.own_eapd_ctl = 1; 4326 4327 codec->patch_ops = stac_patch_ops; 4328 codec->power_filter = snd_hda_codec_eapd_power_filter; 4329 4330 snd_hda_add_verbs(codec, stac9200_eapd_init); 4331 4332 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl, 4333 stac9200_fixups); 4334 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4335 4336 err = stac_parse_auto_config(codec); 4337 if (err < 0) { 4338 stac_free(codec); 4339 return err; 4340 } 4341 4342 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4343 4344 return 0; 4345 } 4346 4347 static int patch_stac925x(struct hda_codec *codec) 4348 { 4349 struct sigmatel_spec *spec; 4350 int err; 4351 4352 err = alloc_stac_spec(codec); 4353 if (err < 0) 4354 return err; 4355 4356 spec = codec->spec; 4357 spec->linear_tone_beep = 1; 4358 spec->gen.own_eapd_ctl = 1; 4359 4360 codec->patch_ops = stac_patch_ops; 4361 4362 snd_hda_add_verbs(codec, stac925x_core_init); 4363 4364 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl, 4365 stac925x_fixups); 4366 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4367 4368 err = stac_parse_auto_config(codec); 4369 if (err < 0) { 4370 stac_free(codec); 4371 return err; 4372 } 4373 4374 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4375 4376 return 0; 4377 } 4378 4379 static int patch_stac92hd73xx(struct hda_codec *codec) 4380 { 4381 struct sigmatel_spec *spec; 4382 int err; 4383 int num_dacs; 4384 4385 err = alloc_stac_spec(codec); 4386 if (err < 0) 4387 return err; 4388 4389 spec = codec->spec; 4390 spec->linear_tone_beep = 0; 4391 spec->gen.mixer_nid = 0x1d; 4392 spec->have_spdif_mux = 1; 4393 4394 num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1; 4395 if (num_dacs < 3 || num_dacs > 5) { 4396 printk(KERN_WARNING "hda_codec: Could not determine " 4397 "number of channels defaulting to DAC count\n"); 4398 num_dacs = 5; 4399 } 4400 4401 switch (num_dacs) { 4402 case 0x3: /* 6 Channel */ 4403 spec->aloopback_ctl = &stac92hd73xx_6ch_loopback; 4404 break; 4405 case 0x4: /* 8 Channel */ 4406 spec->aloopback_ctl = &stac92hd73xx_8ch_loopback; 4407 break; 4408 case 0x5: /* 10 Channel */ 4409 spec->aloopback_ctl = &stac92hd73xx_10ch_loopback; 4410 break; 4411 } 4412 4413 spec->aloopback_mask = 0x01; 4414 spec->aloopback_shift = 8; 4415 4416 spec->gen.beep_nid = 0x1c; /* digital beep */ 4417 4418 /* GPIO0 High = Enable EAPD */ 4419 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; 4420 spec->gpio_data = 0x01; 4421 4422 spec->eapd_switch = 1; 4423 4424 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); 4425 spec->pwr_nids = stac92hd73xx_pwr_nids; 4426 4427 spec->gen.own_eapd_ctl = 1; 4428 spec->gen.power_down_unused = 1; 4429 4430 codec->patch_ops = stac_patch_ops; 4431 4432 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl, 4433 stac92hd73xx_fixups); 4434 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4435 4436 if (!spec->volknob_init) 4437 snd_hda_add_verbs(codec, stac92hd73xx_core_init); 4438 4439 err = stac_parse_auto_config(codec); 4440 if (err < 0) { 4441 stac_free(codec); 4442 return err; 4443 } 4444 4445 /* Don't GPIO-mute speakers if there are no internal speakers, because 4446 * the GPIO might be necessary for Headphone 4447 */ 4448 if (spec->eapd_switch && !has_builtin_speaker(codec)) 4449 spec->eapd_switch = 0; 4450 4451 codec->proc_widget_hook = stac92hd7x_proc_hook; 4452 4453 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4454 4455 return 0; 4456 } 4457 4458 static void stac_setup_gpio(struct hda_codec *codec) 4459 { 4460 struct sigmatel_spec *spec = codec->spec; 4461 4462 spec->gpio_mask |= spec->eapd_mask; 4463 if (spec->gpio_led) { 4464 if (!spec->vref_mute_led_nid) { 4465 spec->gpio_mask |= spec->gpio_led; 4466 spec->gpio_dir |= spec->gpio_led; 4467 spec->gpio_data |= spec->gpio_led; 4468 } else { 4469 codec->patch_ops.set_power_state = 4470 stac_set_power_state; 4471 } 4472 } 4473 4474 if (spec->mic_mute_led_gpio) { 4475 spec->gpio_mask |= spec->mic_mute_led_gpio; 4476 spec->gpio_dir |= spec->mic_mute_led_gpio; 4477 spec->mic_mute_led_on = true; 4478 spec->gpio_data |= spec->mic_mute_led_gpio; 4479 4480 spec->gen.cap_sync_hook = stac_capture_led_hook; 4481 } 4482 } 4483 4484 static int patch_stac92hd83xxx(struct hda_codec *codec) 4485 { 4486 struct sigmatel_spec *spec; 4487 int err; 4488 4489 err = alloc_stac_spec(codec); 4490 if (err < 0) 4491 return err; 4492 4493 codec->epss = 0; /* longer delay needed for D3 */ 4494 4495 spec = codec->spec; 4496 spec->linear_tone_beep = 0; 4497 spec->gen.own_eapd_ctl = 1; 4498 spec->gen.power_down_unused = 1; 4499 spec->gen.mixer_nid = 0x1b; 4500 4501 spec->gen.beep_nid = 0x21; /* digital beep */ 4502 spec->pwr_nids = stac92hd83xxx_pwr_nids; 4503 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 4504 spec->default_polarity = -1; /* no default cfg */ 4505 4506 codec->patch_ops = stac_patch_ops; 4507 4508 snd_hda_add_verbs(codec, stac92hd83xxx_core_init); 4509 4510 snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl, 4511 stac92hd83xxx_fixups); 4512 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4513 4514 stac_setup_gpio(codec); 4515 4516 err = stac_parse_auto_config(codec); 4517 if (err < 0) { 4518 stac_free(codec); 4519 return err; 4520 } 4521 4522 codec->proc_widget_hook = stac92hd_proc_hook; 4523 4524 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4525 4526 return 0; 4527 } 4528 4529 static const hda_nid_t stac92hd95_pwr_nids[] = { 4530 0x0a, 0x0b, 0x0c, 0x0d 4531 }; 4532 4533 static int patch_stac92hd95(struct hda_codec *codec) 4534 { 4535 struct sigmatel_spec *spec; 4536 int err; 4537 4538 err = alloc_stac_spec(codec); 4539 if (err < 0) 4540 return err; 4541 4542 codec->epss = 0; /* longer delay needed for D3 */ 4543 4544 spec = codec->spec; 4545 spec->linear_tone_beep = 0; 4546 spec->gen.own_eapd_ctl = 1; 4547 spec->gen.power_down_unused = 1; 4548 4549 spec->gen.beep_nid = 0x19; /* digital beep */ 4550 spec->pwr_nids = stac92hd95_pwr_nids; 4551 spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids); 4552 spec->default_polarity = -1; /* no default cfg */ 4553 4554 codec->patch_ops = stac_patch_ops; 4555 4556 err = stac_parse_auto_config(codec); 4557 if (err < 0) { 4558 stac_free(codec); 4559 return err; 4560 } 4561 4562 codec->proc_widget_hook = stac92hd_proc_hook; 4563 4564 return 0; 4565 } 4566 4567 static int patch_stac92hd71bxx(struct hda_codec *codec) 4568 { 4569 struct sigmatel_spec *spec; 4570 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; 4571 int err; 4572 4573 err = alloc_stac_spec(codec); 4574 if (err < 0) 4575 return err; 4576 4577 spec = codec->spec; 4578 spec->linear_tone_beep = 0; 4579 spec->gen.own_eapd_ctl = 1; 4580 spec->gen.power_down_unused = 1; 4581 spec->gen.mixer_nid = 0x17; 4582 spec->have_spdif_mux = 1; 4583 4584 codec->patch_ops = stac_patch_ops; 4585 4586 /* GPIO0 = EAPD */ 4587 spec->gpio_mask = 0x01; 4588 spec->gpio_dir = 0x01; 4589 spec->gpio_data = 0x01; 4590 4591 switch (codec->vendor_id) { 4592 case 0x111d76b6: /* 4 Port without Analog Mixer */ 4593 case 0x111d76b7: 4594 unmute_init++; 4595 break; 4596 case 0x111d7608: /* 5 Port with Analog Mixer */ 4597 if ((codec->revision_id & 0xf) == 0 || 4598 (codec->revision_id & 0xf) == 1) 4599 spec->stream_delay = 40; /* 40 milliseconds */ 4600 4601 /* disable VSW */ 4602 unmute_init++; 4603 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 4604 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 4605 break; 4606 case 0x111d7603: /* 6 Port with Analog Mixer */ 4607 if ((codec->revision_id & 0xf) == 1) 4608 spec->stream_delay = 40; /* 40 milliseconds */ 4609 4610 break; 4611 } 4612 4613 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB) 4614 snd_hda_add_verbs(codec, stac92hd71bxx_core_init); 4615 4616 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 4617 snd_hda_sequence_write_cache(codec, unmute_init); 4618 4619 spec->aloopback_ctl = &stac92hd71bxx_loopback; 4620 spec->aloopback_mask = 0x50; 4621 spec->aloopback_shift = 0; 4622 4623 spec->powerdown_adcs = 1; 4624 spec->gen.beep_nid = 0x26; /* digital beep */ 4625 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); 4626 spec->pwr_nids = stac92hd71bxx_pwr_nids; 4627 4628 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl, 4629 stac92hd71bxx_fixups); 4630 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4631 4632 stac_setup_gpio(codec); 4633 4634 err = stac_parse_auto_config(codec); 4635 if (err < 0) { 4636 stac_free(codec); 4637 return err; 4638 } 4639 4640 codec->proc_widget_hook = stac92hd7x_proc_hook; 4641 4642 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4643 4644 return 0; 4645 } 4646 4647 static int patch_stac922x(struct hda_codec *codec) 4648 { 4649 struct sigmatel_spec *spec; 4650 int err; 4651 4652 err = alloc_stac_spec(codec); 4653 if (err < 0) 4654 return err; 4655 4656 spec = codec->spec; 4657 spec->linear_tone_beep = 1; 4658 spec->gen.own_eapd_ctl = 1; 4659 4660 codec->patch_ops = stac_patch_ops; 4661 4662 snd_hda_add_verbs(codec, stac922x_core_init); 4663 4664 /* Fix Mux capture level; max to 2 */ 4665 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, 4666 (0 << AC_AMPCAP_OFFSET_SHIFT) | 4667 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4668 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4669 (0 << AC_AMPCAP_MUTE_SHIFT)); 4670 4671 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl, 4672 stac922x_fixups); 4673 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4674 4675 err = stac_parse_auto_config(codec); 4676 if (err < 0) { 4677 stac_free(codec); 4678 return err; 4679 } 4680 4681 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4682 4683 return 0; 4684 } 4685 4686 static const char * const stac927x_spdif_labels[] = { 4687 "Digital Playback", "ADAT", "Analog Mux 1", 4688 "Analog Mux 2", "Analog Mux 3", NULL 4689 }; 4690 4691 static int patch_stac927x(struct hda_codec *codec) 4692 { 4693 struct sigmatel_spec *spec; 4694 int err; 4695 4696 err = alloc_stac_spec(codec); 4697 if (err < 0) 4698 return err; 4699 4700 spec = codec->spec; 4701 spec->linear_tone_beep = 1; 4702 spec->gen.own_eapd_ctl = 1; 4703 spec->have_spdif_mux = 1; 4704 spec->spdif_labels = stac927x_spdif_labels; 4705 4706 spec->gen.beep_nid = 0x23; /* digital beep */ 4707 4708 /* GPIO0 High = Enable EAPD */ 4709 spec->eapd_mask = spec->gpio_mask = 0x01; 4710 spec->gpio_dir = spec->gpio_data = 0x01; 4711 4712 spec->aloopback_ctl = &stac927x_loopback; 4713 spec->aloopback_mask = 0x40; 4714 spec->aloopback_shift = 0; 4715 spec->eapd_switch = 1; 4716 4717 codec->patch_ops = stac_patch_ops; 4718 4719 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl, 4720 stac927x_fixups); 4721 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4722 4723 if (!spec->volknob_init) 4724 snd_hda_add_verbs(codec, stac927x_core_init); 4725 4726 err = stac_parse_auto_config(codec); 4727 if (err < 0) { 4728 stac_free(codec); 4729 return err; 4730 } 4731 4732 codec->proc_widget_hook = stac927x_proc_hook; 4733 4734 /* 4735 * !!FIXME!! 4736 * The STAC927x seem to require fairly long delays for certain 4737 * command sequences. With too short delays (even if the answer 4738 * is set to RIRB properly), it results in the silence output 4739 * on some hardwares like Dell. 4740 * 4741 * The below flag enables the longer delay (see get_response 4742 * in hda_intel.c). 4743 */ 4744 codec->bus->needs_damn_long_delay = 1; 4745 4746 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4747 4748 return 0; 4749 } 4750 4751 static int patch_stac9205(struct hda_codec *codec) 4752 { 4753 struct sigmatel_spec *spec; 4754 int err; 4755 4756 err = alloc_stac_spec(codec); 4757 if (err < 0) 4758 return err; 4759 4760 spec = codec->spec; 4761 spec->linear_tone_beep = 1; 4762 spec->gen.own_eapd_ctl = 1; 4763 spec->have_spdif_mux = 1; 4764 4765 spec->gen.beep_nid = 0x23; /* digital beep */ 4766 4767 snd_hda_add_verbs(codec, stac9205_core_init); 4768 spec->aloopback_ctl = &stac9205_loopback; 4769 4770 spec->aloopback_mask = 0x40; 4771 spec->aloopback_shift = 0; 4772 4773 /* GPIO0 High = EAPD */ 4774 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; 4775 spec->gpio_data = 0x01; 4776 4777 /* Turn on/off EAPD per HP plugging */ 4778 spec->eapd_switch = 1; 4779 4780 codec->patch_ops = stac_patch_ops; 4781 4782 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl, 4783 stac9205_fixups); 4784 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4785 4786 err = stac_parse_auto_config(codec); 4787 if (err < 0) { 4788 stac_free(codec); 4789 return err; 4790 } 4791 4792 codec->proc_widget_hook = stac9205_proc_hook; 4793 4794 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4795 4796 return 0; 4797 } 4798 4799 /* 4800 * STAC9872 hack 4801 */ 4802 4803 static const struct hda_verb stac9872_core_init[] = { 4804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ 4805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ 4806 {} 4807 }; 4808 4809 static const struct hda_pintbl stac9872_vaio_pin_configs[] = { 4810 { 0x0a, 0x03211020 }, 4811 { 0x0b, 0x411111f0 }, 4812 { 0x0c, 0x411111f0 }, 4813 { 0x0d, 0x03a15030 }, 4814 { 0x0e, 0x411111f0 }, 4815 { 0x0f, 0x90170110 }, 4816 { 0x11, 0x411111f0 }, 4817 { 0x13, 0x411111f0 }, 4818 { 0x14, 0x90a7013e }, 4819 {} 4820 }; 4821 4822 static const struct hda_model_fixup stac9872_models[] = { 4823 { .id = STAC_9872_VAIO, .name = "vaio" }, 4824 {} 4825 }; 4826 4827 static const struct hda_fixup stac9872_fixups[] = { 4828 [STAC_9872_VAIO] = { 4829 .type = HDA_FIXUP_PINS, 4830 .v.pins = stac9872_vaio_pin_configs, 4831 }, 4832 }; 4833 4834 static const struct snd_pci_quirk stac9872_fixup_tbl[] = { 4835 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, 4836 "Sony VAIO F/S", STAC_9872_VAIO), 4837 {} /* terminator */ 4838 }; 4839 4840 static int patch_stac9872(struct hda_codec *codec) 4841 { 4842 struct sigmatel_spec *spec; 4843 int err; 4844 4845 err = alloc_stac_spec(codec); 4846 if (err < 0) 4847 return err; 4848 4849 spec = codec->spec; 4850 spec->linear_tone_beep = 1; 4851 spec->gen.own_eapd_ctl = 1; 4852 4853 codec->patch_ops = stac_patch_ops; 4854 4855 snd_hda_add_verbs(codec, stac9872_core_init); 4856 4857 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl, 4858 stac9872_fixups); 4859 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4860 4861 err = stac_parse_auto_config(codec); 4862 if (err < 0) { 4863 stac_free(codec); 4864 return -EINVAL; 4865 } 4866 4867 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4868 4869 return 0; 4870 } 4871 4872 4873 /* 4874 * patch entries 4875 */ 4876 static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { 4877 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 4878 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 4879 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 4880 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x }, 4881 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, 4882 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, 4883 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, 4884 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x }, 4885 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x }, 4886 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x }, 4887 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x }, 4888 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x }, 4889 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x }, 4890 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, 4891 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, 4892 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, 4893 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x }, 4894 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x }, 4895 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x }, 4896 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x }, 4897 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, 4898 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, 4899 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, 4900 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x }, 4901 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x }, 4902 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x }, 4903 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x }, 4904 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x }, 4905 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x }, 4906 { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x }, 4907 { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x }, 4908 /* The following does not take into account .id=0x83847661 when subsys = 4909 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are 4910 * currently not fully supported. 4911 */ 4912 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 }, 4913 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 }, 4914 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 }, 4915 { .id = 0x83847698, .name = "STAC9205", .patch = patch_stac9205 }, 4916 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, 4917 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, 4918 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, 4919 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 }, 4920 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 }, 4921 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, 4922 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, 4923 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 4924 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 4925 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 4926 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx}, 4927 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 4928 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 4929 { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx}, 4930 { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx}, 4931 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx}, 4932 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx}, 4933 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx}, 4934 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx}, 4935 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 4936 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 4937 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 4938 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, 4939 { .id = 0x111d7695, .name = "92HD95", .patch = patch_stac92hd95 }, 4940 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, 4941 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, 4942 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, 4943 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, 4944 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, 4945 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, 4946 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 4947 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 4948 { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx }, 4949 { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx }, 4950 { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx }, 4951 { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx }, 4952 { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx }, 4953 { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx }, 4954 { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx }, 4955 { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx }, 4956 { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx }, 4957 { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx }, 4958 { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx }, 4959 { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx }, 4960 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, 4961 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, 4962 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, 4963 { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx}, 4964 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx}, 4965 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, 4966 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, 4967 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, 4968 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx}, 4969 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx}, 4970 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx}, 4971 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx}, 4972 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx}, 4973 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx}, 4974 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx}, 4975 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx}, 4976 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx}, 4977 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx}, 4978 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx}, 4979 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx}, 4980 {} /* terminator */ 4981 }; 4982 4983 MODULE_ALIAS("snd-hda-codec-id:8384*"); 4984 MODULE_ALIAS("snd-hda-codec-id:111d*"); 4985 4986 MODULE_LICENSE("GPL"); 4987 MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec"); 4988 4989 static struct hda_codec_preset_list sigmatel_list = { 4990 .preset = snd_hda_preset_sigmatel, 4991 .owner = THIS_MODULE, 4992 }; 4993 4994 static int __init patch_sigmatel_init(void) 4995 { 4996 return snd_hda_add_codec_preset(&sigmatel_list); 4997 } 4998 4999 static void __exit patch_sigmatel_exit(void) 5000 { 5001 snd_hda_delete_codec_preset(&sigmatel_list); 5002 } 5003 5004 module_init(patch_sigmatel_init) 5005 module_exit(patch_sigmatel_exit) 5006