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