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