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