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