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