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