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