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