1d0fa1179SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
22f2f4251SMatt /*
32f2f4251SMatt * Universal Interface for Intel High Definition Audio Codec
42f2f4251SMatt *
52f2f4251SMatt * HD audio interface patch for SigmaTel STAC92xx
62f2f4251SMatt *
72f2f4251SMatt * Copyright (c) 2005 Embedded Alley Solutions, Inc.
8403d1944SMatt Porter * Matt Porter <mporter@embeddedalley.com>
92f2f4251SMatt *
102f2f4251SMatt * Based on patch_cmedia.c and patch_realtek.c
112f2f4251SMatt * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
122f2f4251SMatt */
132f2f4251SMatt
142f2f4251SMatt #include <linux/init.h>
152f2f4251SMatt #include <linux/delay.h>
162f2f4251SMatt #include <linux/slab.h>
172f2f4251SMatt #include <linux/pci.h>
185bdaaadaSVitaliy Kulikov #include <linux/dmi.h>
19da155d5bSPaul Gortmaker #include <linux/module.h>
202f2f4251SMatt #include <sound/core.h>
2145a6ac16SMatthew Ranostay #include <sound/jack.h>
22be57bfffSPierre-Louis Bossart #include <sound/hda_codec.h>
232f2f4251SMatt #include "hda_local.h"
24128bc4baSTakashi Iwai #include "hda_auto_parser.h"
251cd2224cSMatthew Ranostay #include "hda_beep.h"
261835a0f9STakashi Iwai #include "hda_jack.h"
2736c9db7aSTakashi Iwai #include "hda_generic.h"
282f2f4251SMatt
29c6e4c666STakashi Iwai enum {
30f5fcc13cSTakashi Iwai STAC_REF,
31bf277785STobin Davis STAC_9200_OQO,
32dfe495d0STakashi Iwai STAC_9200_DELL_D21,
33dfe495d0STakashi Iwai STAC_9200_DELL_D22,
34dfe495d0STakashi Iwai STAC_9200_DELL_D23,
35dfe495d0STakashi Iwai STAC_9200_DELL_M21,
36dfe495d0STakashi Iwai STAC_9200_DELL_M22,
37dfe495d0STakashi Iwai STAC_9200_DELL_M23,
38dfe495d0STakashi Iwai STAC_9200_DELL_M24,
39dfe495d0STakashi Iwai STAC_9200_DELL_M25,
40dfe495d0STakashi Iwai STAC_9200_DELL_M26,
41dfe495d0STakashi Iwai STAC_9200_DELL_M27,
4258eec423SMauro Carvalho Chehab STAC_9200_M4,
4358eec423SMauro Carvalho Chehab STAC_9200_M4_2,
44117f257dSTakashi Iwai STAC_9200_PANASONIC,
45d39a3ae8STakashi Iwai STAC_9200_EAPD_INIT,
46f5fcc13cSTakashi Iwai STAC_9200_MODELS
47f5fcc13cSTakashi Iwai };
48f5fcc13cSTakashi Iwai
49f5fcc13cSTakashi Iwai enum {
50f5fcc13cSTakashi Iwai STAC_9205_REF,
51dfe495d0STakashi Iwai STAC_9205_DELL_M42,
52ae0a8ed8STobin Davis STAC_9205_DELL_M43,
53ae0a8ed8STobin Davis STAC_9205_DELL_M44,
54d9a4268eSTakashi Iwai STAC_9205_EAPD,
55f5fcc13cSTakashi Iwai STAC_9205_MODELS
56f5fcc13cSTakashi Iwai };
57f5fcc13cSTakashi Iwai
58f5fcc13cSTakashi Iwai enum {
599e43f0deSTakashi Iwai STAC_92HD73XX_NO_JD, /* no jack-detection */
60e1f0d669SMatthew Ranostay STAC_92HD73XX_REF,
61ae709440SWu Fengguang STAC_92HD73XX_INTEL,
62661cd8fbSTakashi Iwai STAC_DELL_M6_AMIC,
63661cd8fbSTakashi Iwai STAC_DELL_M6_DMIC,
64661cd8fbSTakashi Iwai STAC_DELL_M6_BOTH,
656b3ab21eSMatthew Ranostay STAC_DELL_EQ,
66842ae638STakashi Iwai STAC_ALIENWARE_M17X,
67d153135eSMichael Pobega STAC_ELO_VUPOINT_15MX,
681de7ca5eSHui Wang STAC_92HD89XX_HP_FRONT_JACK,
697440850cSHui Wang STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK,
706426460eSTakashi Iwai STAC_92HD73XX_ASUS_MOBO,
71e1f0d669SMatthew Ranostay STAC_92HD73XX_MODELS
72e1f0d669SMatthew Ranostay };
73e1f0d669SMatthew Ranostay
74e1f0d669SMatthew Ranostay enum {
75d0513fc6SMatthew Ranostay STAC_92HD83XXX_REF,
7632ed3f46SMatthew Ranostay STAC_92HD83XXX_PWR_REF,
778bb0ac55SMatthew Ranostay STAC_DELL_S14,
78f7f9bdfaSJulian Wollrath STAC_DELL_VOSTRO_3500,
790c27c180SVitaliy Kulikov STAC_92HD83XXX_HP_cNB11_INTQUAD,
8048315590SSteven Eastland STAC_HP_DV7_4000,
815556e147SVitaliy Kulikov STAC_HP_ZEPHYR,
82a3e19973STakashi Iwai STAC_92HD83XXX_HP_LED,
83ff8a1e27STakashi Iwai STAC_92HD83XXX_HP_INV_LED,
8462cbde18STakashi Iwai STAC_92HD83XXX_HP_MIC_LED,
8537c367ecSTakashi Iwai STAC_HP_LED_GPIO10,
868d032a8fSDavid Henningsson STAC_92HD83XXX_HEADSET_JACK,
87372f8c75STakashi Iwai STAC_92HD83XXX_HP,
8849920427STakashi Iwai STAC_HP_ENVY_BASS,
89d009f3deSVitaliy Kulikov STAC_HP_BNB13_EQ,
908695a003STakashi Iwai STAC_HP_ENVY_TS_BASS,
916ab42ff4SHui Wang STAC_HP_ENVY_TS_DAC_BIND,
924227de2aSTakashi Iwai STAC_92HD83XXX_GPIO10_EAPD,
93d0513fc6SMatthew Ranostay STAC_92HD83XXX_MODELS
94d0513fc6SMatthew Ranostay };
95d0513fc6SMatthew Ranostay
96d0513fc6SMatthew Ranostay enum {
97e035b841SMatthew Ranostay STAC_92HD71BXX_REF,
98a7662640SMatthew Ranostay STAC_DELL_M4_1,
99a7662640SMatthew Ranostay STAC_DELL_M4_2,
1003a7abfd2SMatthew Ranostay STAC_DELL_M4_3,
1016a14f585SMatthew Ranostay STAC_HP_M4,
1022a6ce6e5STakashi Iwai STAC_HP_DV4,
1031b0652ebSTakashi Iwai STAC_HP_DV5,
104ae6241fbSChristoph Plattner STAC_HP_HDX,
1050f6fcb73STakashi Iwai STAC_92HD71BXX_HP,
1060f6fcb73STakashi Iwai STAC_92HD71BXX_NO_DMIC,
1070f6fcb73STakashi Iwai STAC_92HD71BXX_NO_SMUX,
108e035b841SMatthew Ranostay STAC_92HD71BXX_MODELS
109e035b841SMatthew Ranostay };
110e035b841SMatthew Ranostay
111e035b841SMatthew Ranostay enum {
1128b3dfdafSTakashi Iwai STAC_92HD95_HP_LED,
1138b3dfdafSTakashi Iwai STAC_92HD95_HP_BASS,
1148b3dfdafSTakashi Iwai STAC_92HD95_MODELS
1158b3dfdafSTakashi Iwai };
1168b3dfdafSTakashi Iwai
1178b3dfdafSTakashi Iwai enum {
1188e21c34cSTobin Davis STAC_925x_REF,
1199cb36c2aSMauro Carvalho Chehab STAC_M1,
1209cb36c2aSMauro Carvalho Chehab STAC_M1_2,
1219cb36c2aSMauro Carvalho Chehab STAC_M2,
1228e21c34cSTobin Davis STAC_M2_2,
1239cb36c2aSMauro Carvalho Chehab STAC_M3,
1249cb36c2aSMauro Carvalho Chehab STAC_M5,
1259cb36c2aSMauro Carvalho Chehab STAC_M6,
1268e21c34cSTobin Davis STAC_925x_MODELS
1278e21c34cSTobin Davis };
1288e21c34cSTobin Davis
1298e21c34cSTobin Davis enum {
130f5fcc13cSTakashi Iwai STAC_D945_REF,
131f5fcc13cSTakashi Iwai STAC_D945GTP3,
132f5fcc13cSTakashi Iwai STAC_D945GTP5,
1335d5d3bc3SIvan N. Zlatev STAC_INTEL_MAC_V1,
1345d5d3bc3SIvan N. Zlatev STAC_INTEL_MAC_V2,
1355d5d3bc3SIvan N. Zlatev STAC_INTEL_MAC_V3,
1365d5d3bc3SIvan N. Zlatev STAC_INTEL_MAC_V4,
1375d5d3bc3SIvan N. Zlatev STAC_INTEL_MAC_V5,
1380a427846STakashi Iwai STAC_INTEL_MAC_AUTO,
1398c650087SMauro Carvalho Chehab STAC_ECS_202,
140dfe495d0STakashi Iwai STAC_922X_DELL_D81,
141dfe495d0STakashi Iwai STAC_922X_DELL_D82,
142dfe495d0STakashi Iwai STAC_922X_DELL_M81,
143dfe495d0STakashi Iwai STAC_922X_DELL_M82,
1440a427846STakashi Iwai STAC_922X_INTEL_MAC_GPIO,
145f5fcc13cSTakashi Iwai STAC_922X_MODELS
146f5fcc13cSTakashi Iwai };
147f5fcc13cSTakashi Iwai
148f5fcc13cSTakashi Iwai enum {
149e28d8322STakashi Iwai STAC_D965_REF_NO_JD, /* no jack-detection */
150f5fcc13cSTakashi Iwai STAC_D965_REF,
151f5fcc13cSTakashi Iwai STAC_D965_3ST,
152f5fcc13cSTakashi Iwai STAC_D965_5ST,
153679d92edSTakashi Iwai STAC_D965_5ST_NO_FP,
15429ac8363STakashi Iwai STAC_D965_VERBS,
1554ff076e5STobin Davis STAC_DELL_3ST,
1568e9068b1SMatthew Ranostay STAC_DELL_BIOS,
157078502b5SDarren Stevens STAC_NEMO_DEFAULT,
158eefb8be4STakashi Iwai STAC_DELL_BIOS_AMIC,
15929ac8363STakashi Iwai STAC_DELL_BIOS_SPDIF,
16029ac8363STakashi Iwai STAC_927X_DELL_DMIC,
16154930531STakashi Iwai STAC_927X_VOLKNOB,
162f5fcc13cSTakashi Iwai STAC_927X_MODELS
163f5fcc13cSTakashi Iwai };
164403d1944SMatt Porter
165307282c8STakashi Iwai enum {
166307282c8STakashi Iwai STAC_9872_VAIO,
167307282c8STakashi Iwai STAC_9872_MODELS
168307282c8STakashi Iwai };
169307282c8STakashi Iwai
1702f2f4251SMatt struct sigmatel_spec {
17136c9db7aSTakashi Iwai struct hda_gen_spec gen;
172c7d4b2faSMatt
173c0cea0d0SMatthew Ranostay unsigned int eapd_switch: 1;
1741b0e372dSDaniel J Blueman unsigned int linear_tone_beep:1;
1758d032a8fSDavid Henningsson unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
17629ac8363STakashi Iwai unsigned int volknob_init:1; /* special volume-knob initialization */
17736c9db7aSTakashi Iwai unsigned int powerdown_adcs:1;
17842875479STakashi Iwai unsigned int have_spdif_mux:1;
179c7d4b2faSMatt
1804fe5195cSMatthew Ranostay /* gpio lines */
1810fc9dec4SMatthew Ranostay unsigned int eapd_mask;
1824fe5195cSMatthew Ranostay unsigned int gpio_mask;
1834fe5195cSMatthew Ranostay unsigned int gpio_dir;
1844fe5195cSMatthew Ranostay unsigned int gpio_data;
1854fe5195cSMatthew Ranostay unsigned int gpio_mute;
18686d190e7STakashi Iwai unsigned int gpio_led;
187c357aab0SVitaliy Kulikov unsigned int gpio_led_polarity;
188f1a73746STakashi Iwai unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
18945eebda7SVitaliy Kulikov unsigned int vref_led;
190372f8c75STakashi Iwai int default_polarity;
1914fe5195cSMatthew Ranostay
19262cbde18STakashi Iwai unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
1937fe30711STakashi Iwai unsigned int mic_enabled; /* current mic mute state (bitmask) */
19462cbde18STakashi Iwai
1958daaaa97SMatthew Ranostay /* stream */
1968daaaa97SMatthew Ranostay unsigned int stream_delay;
1978daaaa97SMatthew Ranostay
1984fe5195cSMatthew Ranostay /* analog loopback */
1992b63536fSTakashi Iwai const struct snd_kcontrol_new *aloopback_ctl;
20036c9db7aSTakashi Iwai unsigned int aloopback;
201e1f0d669SMatthew Ranostay unsigned char aloopback_mask;
202e1f0d669SMatthew Ranostay unsigned char aloopback_shift;
2038259980eSTakashi Iwai
204a64135a2SMatthew Ranostay /* power management */
205c882246dSTakashi Iwai unsigned int power_map_bits;
206a64135a2SMatthew Ranostay unsigned int num_pwrs;
2072b63536fSTakashi Iwai const hda_nid_t *pwr_nids;
20836c9db7aSTakashi Iwai unsigned int active_adcs;
209a64135a2SMatthew Ranostay
21036c9db7aSTakashi Iwai /* beep widgets */
2111cd2224cSMatthew Ranostay hda_nid_t anabeep_nid;
212414d38baSTakashi Iwai bool beep_power_on;
21342875479STakashi Iwai
21442875479STakashi Iwai /* SPDIF-out mux */
21542875479STakashi Iwai const char * const *spdif_labels;
21642875479STakashi Iwai struct hda_input_mux spdif_mux;
21742875479STakashi Iwai unsigned int cur_smux[2];
2182f2f4251SMatt };
2192f2f4251SMatt
220c882246dSTakashi Iwai #define AC_VERB_IDT_SET_POWER_MAP 0x7ec
221c882246dSTakashi Iwai #define AC_VERB_IDT_GET_POWER_MAP 0xfec
222c882246dSTakashi Iwai
2232b63536fSTakashi Iwai static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
224a64135a2SMatthew Ranostay 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
225a64135a2SMatthew Ranostay 0x0f, 0x10, 0x11
226a64135a2SMatthew Ranostay };
227a64135a2SMatthew Ranostay
228afef2cfaSCharles Chin static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
229afef2cfaSCharles Chin 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
230afef2cfaSCharles Chin 0x0f, 0x10
231d0513fc6SMatthew Ranostay };
232d0513fc6SMatthew Ranostay
2332b63536fSTakashi Iwai static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
234a64135a2SMatthew Ranostay 0x0a, 0x0d, 0x0f
235a64135a2SMatthew Ranostay };
236a64135a2SMatthew Ranostay
237e035b841SMatthew Ranostay
23836c9db7aSTakashi Iwai /*
23936c9db7aSTakashi Iwai * PCM hooks
24036c9db7aSTakashi Iwai */
stac_playback_pcm_hook(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream,int action)24136c9db7aSTakashi Iwai static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo,
24236c9db7aSTakashi Iwai struct hda_codec *codec,
24336c9db7aSTakashi Iwai struct snd_pcm_substream *substream,
24436c9db7aSTakashi Iwai int action)
2458b65727bSMatt Porter {
2468b65727bSMatt Porter struct sigmatel_spec *spec = codec->spec;
24736c9db7aSTakashi Iwai if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay)
24836c9db7aSTakashi Iwai msleep(spec->stream_delay);
2498b65727bSMatt Porter }
2508b65727bSMatt Porter
stac_capture_pcm_hook(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream,int action)25136c9db7aSTakashi Iwai static void stac_capture_pcm_hook(struct hda_pcm_stream *hinfo,
25236c9db7aSTakashi Iwai struct hda_codec *codec,
25336c9db7aSTakashi Iwai struct snd_pcm_substream *substream,
25436c9db7aSTakashi Iwai int action)
2558b65727bSMatt Porter {
2568b65727bSMatt Porter struct sigmatel_spec *spec = codec->spec;
25736c9db7aSTakashi Iwai int i, idx = 0;
2588b65727bSMatt Porter
25936c9db7aSTakashi Iwai if (!spec->powerdown_adcs)
26036c9db7aSTakashi Iwai return;
26136c9db7aSTakashi Iwai
26236c9db7aSTakashi Iwai for (i = 0; i < spec->gen.num_all_adcs; i++) {
26336c9db7aSTakashi Iwai if (spec->gen.all_adcs[i] == hinfo->nid) {
26436c9db7aSTakashi Iwai idx = i;
26536c9db7aSTakashi Iwai break;
26636c9db7aSTakashi Iwai }
2678b65727bSMatt Porter }
2688b65727bSMatt Porter
26936c9db7aSTakashi Iwai switch (action) {
27036c9db7aSTakashi Iwai case HDA_GEN_PCM_ACT_OPEN:
27136c9db7aSTakashi Iwai msleep(40);
27236c9db7aSTakashi Iwai snd_hda_codec_write(codec, hinfo->nid, 0,
27336c9db7aSTakashi Iwai AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
27436c9db7aSTakashi Iwai spec->active_adcs |= (1 << idx);
27536c9db7aSTakashi Iwai break;
27636c9db7aSTakashi Iwai case HDA_GEN_PCM_ACT_CLOSE:
27736c9db7aSTakashi Iwai snd_hda_codec_write(codec, hinfo->nid, 0,
27836c9db7aSTakashi Iwai AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
27936c9db7aSTakashi Iwai spec->active_adcs &= ~(1 << idx);
28036c9db7aSTakashi Iwai break;
28136c9db7aSTakashi Iwai }
2828b65727bSMatt Porter }
2838b65727bSMatt Porter
28436c9db7aSTakashi Iwai /*
28536c9db7aSTakashi Iwai * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
28636c9db7aSTakashi Iwai * funky external mute control using GPIO pins.
28736c9db7aSTakashi Iwai */
28836c9db7aSTakashi Iwai
stac_gpio_set(struct hda_codec * codec,unsigned int mask,unsigned int dir_mask,unsigned int data)28936c9db7aSTakashi Iwai static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
29036c9db7aSTakashi Iwai unsigned int dir_mask, unsigned int data)
291d9737751SMatthew Ranostay {
29236c9db7aSTakashi Iwai unsigned int gpiostate, gpiomask, gpiodir;
2937639a06cSTakashi Iwai hda_nid_t fg = codec->core.afg;
29436c9db7aSTakashi Iwai
2954e76a883STakashi Iwai codec_dbg(codec, "%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
29636c9db7aSTakashi Iwai
2977639a06cSTakashi Iwai gpiostate = snd_hda_codec_read(codec, fg, 0,
29836c9db7aSTakashi Iwai AC_VERB_GET_GPIO_DATA, 0);
29936c9db7aSTakashi Iwai gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
30036c9db7aSTakashi Iwai
3017639a06cSTakashi Iwai gpiomask = snd_hda_codec_read(codec, fg, 0,
30236c9db7aSTakashi Iwai AC_VERB_GET_GPIO_MASK, 0);
30336c9db7aSTakashi Iwai gpiomask |= mask;
30436c9db7aSTakashi Iwai
3057639a06cSTakashi Iwai gpiodir = snd_hda_codec_read(codec, fg, 0,
30636c9db7aSTakashi Iwai AC_VERB_GET_GPIO_DIRECTION, 0);
30736c9db7aSTakashi Iwai gpiodir |= dir_mask;
30836c9db7aSTakashi Iwai
30936c9db7aSTakashi Iwai /* Configure GPIOx as CMOS */
3107639a06cSTakashi Iwai snd_hda_codec_write(codec, fg, 0, 0x7e7, 0);
31136c9db7aSTakashi Iwai
3127639a06cSTakashi Iwai snd_hda_codec_write(codec, fg, 0,
31336c9db7aSTakashi Iwai AC_VERB_SET_GPIO_MASK, gpiomask);
3147639a06cSTakashi Iwai snd_hda_codec_read(codec, fg, 0,
31536c9db7aSTakashi Iwai AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
31636c9db7aSTakashi Iwai
31736c9db7aSTakashi Iwai msleep(1);
31836c9db7aSTakashi Iwai
3197639a06cSTakashi Iwai snd_hda_codec_read(codec, fg, 0,
32036c9db7aSTakashi Iwai AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
321d9737751SMatthew Ranostay }
322d9737751SMatthew Ranostay
32336c9db7aSTakashi Iwai /* hook for controlling mic-mute LED GPIO */
stac_capture_led_update(struct led_classdev * led_cdev,enum led_brightness brightness)32423a2b469STakashi Iwai static int stac_capture_led_update(struct led_classdev *led_cdev,
32523a2b469STakashi Iwai enum led_brightness brightness)
326d9737751SMatthew Ranostay {
32723a2b469STakashi Iwai struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
328d9737751SMatthew Ranostay struct sigmatel_spec *spec = codec->spec;
329d9737751SMatthew Ranostay
33023a2b469STakashi Iwai if (brightness)
33136c9db7aSTakashi Iwai spec->gpio_data |= spec->mic_mute_led_gpio;
33200ef50c2SMatthew Ranostay else
33336c9db7aSTakashi Iwai spec->gpio_data &= ~spec->mic_mute_led_gpio;
3343bf29db7STakashi Iwai stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
33523a2b469STakashi Iwai return 0;
336d9737751SMatthew Ranostay }
337d9737751SMatthew Ranostay
stac_vrefout_set(struct hda_codec * codec,hda_nid_t nid,unsigned int new_vref)33845eebda7SVitaliy Kulikov static int stac_vrefout_set(struct hda_codec *codec,
33945eebda7SVitaliy Kulikov hda_nid_t nid, unsigned int new_vref)
34045eebda7SVitaliy Kulikov {
34145eebda7SVitaliy Kulikov int error, pinctl;
34245eebda7SVitaliy Kulikov
3434e76a883STakashi Iwai codec_dbg(codec, "%s, nid %x ctl %x\n", __func__, nid, new_vref);
34445eebda7SVitaliy Kulikov pinctl = snd_hda_codec_read(codec, nid, 0,
34545eebda7SVitaliy Kulikov AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
34645eebda7SVitaliy Kulikov
34745eebda7SVitaliy Kulikov if (pinctl < 0)
34845eebda7SVitaliy Kulikov return pinctl;
34945eebda7SVitaliy Kulikov
35045eebda7SVitaliy Kulikov pinctl &= 0xff;
35145eebda7SVitaliy Kulikov pinctl &= ~AC_PINCTL_VREFEN;
35245eebda7SVitaliy Kulikov pinctl |= (new_vref & AC_PINCTL_VREFEN);
35345eebda7SVitaliy Kulikov
354cdd03cedSTakashi Iwai error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
35545eebda7SVitaliy Kulikov if (error < 0)
35645eebda7SVitaliy Kulikov return error;
35745eebda7SVitaliy Kulikov
35845eebda7SVitaliy Kulikov return 1;
35945eebda7SVitaliy Kulikov }
36045eebda7SVitaliy Kulikov
361dfc6e469STakashi Iwai /* prevent codec AFG to D3 state when vref-out pin is used for mute LED */
362dfc6e469STakashi Iwai /* 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)363dfc6e469STakashi Iwai static unsigned int stac_vref_led_power_filter(struct hda_codec *codec,
364dfc6e469STakashi Iwai hda_nid_t nid,
365dfc6e469STakashi Iwai unsigned int power_state)
366dfc6e469STakashi Iwai {
3677639a06cSTakashi Iwai if (nid == codec->core.afg && power_state == AC_PWRST_D3)
368dfc6e469STakashi Iwai return AC_PWRST_D1;
369dfc6e469STakashi Iwai return snd_hda_gen_path_power_filter(codec, nid, power_state);
370dfc6e469STakashi Iwai }
371dfc6e469STakashi Iwai
37236c9db7aSTakashi Iwai /* update mute-LED accoring to the master switch */
stac_update_led_status(struct hda_codec * codec,bool muted)373d1d37c57STakashi Iwai static void stac_update_led_status(struct hda_codec *codec, bool muted)
3742fc99890SNickolas Lloyd {
37536c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
3762fc99890SNickolas Lloyd
37736c9db7aSTakashi Iwai if (!spec->gpio_led)
37836c9db7aSTakashi Iwai return;
3792fc99890SNickolas Lloyd
38036c9db7aSTakashi Iwai /* LED state is inverted on these systems */
38136c9db7aSTakashi Iwai if (spec->gpio_led_polarity)
38236c9db7aSTakashi Iwai muted = !muted;
38336c9db7aSTakashi Iwai
38436c9db7aSTakashi Iwai if (!spec->vref_mute_led_nid) {
38536c9db7aSTakashi Iwai if (muted)
38636c9db7aSTakashi Iwai spec->gpio_data |= spec->gpio_led;
3872fc99890SNickolas Lloyd else
38836c9db7aSTakashi Iwai spec->gpio_data &= ~spec->gpio_led;
38936c9db7aSTakashi Iwai stac_gpio_set(codec, spec->gpio_mask,
39036c9db7aSTakashi Iwai spec->gpio_dir, spec->gpio_data);
3915207e10eSTakashi Iwai } else {
39236c9db7aSTakashi Iwai spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
39336c9db7aSTakashi Iwai stac_vrefout_set(codec, spec->vref_mute_led_nid,
39436c9db7aSTakashi Iwai spec->vref_led);
39536c9db7aSTakashi Iwai }
39636c9db7aSTakashi Iwai }
39736c9db7aSTakashi Iwai
39836c9db7aSTakashi Iwai /* vmaster hook to update mute LED */
stac_vmaster_hook(struct led_classdev * led_cdev,enum led_brightness brightness)399d1d37c57STakashi Iwai static int stac_vmaster_hook(struct led_classdev *led_cdev,
400d1d37c57STakashi Iwai enum led_brightness brightness)
40136c9db7aSTakashi Iwai {
402d1d37c57STakashi Iwai struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
403d1d37c57STakashi Iwai
404d1d37c57STakashi Iwai stac_update_led_status(codec, brightness);
405d1d37c57STakashi Iwai return 0;
40636c9db7aSTakashi Iwai }
40736c9db7aSTakashi Iwai
40836c9db7aSTakashi Iwai /* automute hook to handle GPIO mute and EAPD updates */
stac_update_outputs(struct hda_codec * codec)40936c9db7aSTakashi Iwai static void stac_update_outputs(struct hda_codec *codec)
41036c9db7aSTakashi Iwai {
41136c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
41236c9db7aSTakashi Iwai
41336c9db7aSTakashi Iwai if (spec->gpio_mute)
41436c9db7aSTakashi Iwai spec->gen.master_mute =
4157639a06cSTakashi Iwai !(snd_hda_codec_read(codec, codec->core.afg, 0,
41636c9db7aSTakashi Iwai AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
41736c9db7aSTakashi Iwai
41836c9db7aSTakashi Iwai snd_hda_gen_update_outputs(codec);
41936c9db7aSTakashi Iwai
42036c9db7aSTakashi Iwai if (spec->eapd_mask && spec->eapd_switch) {
42136c9db7aSTakashi Iwai unsigned int val = spec->gpio_data;
42236c9db7aSTakashi Iwai if (spec->gen.speaker_muted)
42336c9db7aSTakashi Iwai val &= ~spec->eapd_mask;
42436c9db7aSTakashi Iwai else
42536c9db7aSTakashi Iwai val |= spec->eapd_mask;
4261ea9a69dSTakashi Iwai if (spec->gpio_data != val) {
4271ea9a69dSTakashi Iwai spec->gpio_data = val;
42836c9db7aSTakashi Iwai stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir,
42936c9db7aSTakashi Iwai val);
43036c9db7aSTakashi Iwai }
43136c9db7aSTakashi Iwai }
4321ea9a69dSTakashi Iwai }
43336c9db7aSTakashi Iwai
stac_toggle_power_map(struct hda_codec * codec,hda_nid_t nid,bool enable,bool do_write)43436c9db7aSTakashi Iwai static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
43536c9db7aSTakashi Iwai bool enable, bool do_write)
43636c9db7aSTakashi Iwai {
43736c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
43836c9db7aSTakashi Iwai unsigned int idx, val;
43936c9db7aSTakashi Iwai
44036c9db7aSTakashi Iwai for (idx = 0; idx < spec->num_pwrs; idx++) {
44136c9db7aSTakashi Iwai if (spec->pwr_nids[idx] == nid)
44236c9db7aSTakashi Iwai break;
44336c9db7aSTakashi Iwai }
44436c9db7aSTakashi Iwai if (idx >= spec->num_pwrs)
44536c9db7aSTakashi Iwai return;
44636c9db7aSTakashi Iwai
44736c9db7aSTakashi Iwai idx = 1 << idx;
44836c9db7aSTakashi Iwai
44936c9db7aSTakashi Iwai val = spec->power_map_bits;
45036c9db7aSTakashi Iwai if (enable)
45136c9db7aSTakashi Iwai val &= ~idx;
45236c9db7aSTakashi Iwai else
45336c9db7aSTakashi Iwai val |= idx;
45436c9db7aSTakashi Iwai
45536c9db7aSTakashi Iwai /* power down unused output ports */
45636c9db7aSTakashi Iwai if (val != spec->power_map_bits) {
45736c9db7aSTakashi Iwai spec->power_map_bits = val;
45836c9db7aSTakashi Iwai if (do_write)
4597639a06cSTakashi Iwai snd_hda_codec_write(codec, codec->core.afg, 0,
46036c9db7aSTakashi Iwai AC_VERB_IDT_SET_POWER_MAP, val);
46136c9db7aSTakashi Iwai }
46236c9db7aSTakashi Iwai }
46336c9db7aSTakashi Iwai
46436c9db7aSTakashi Iwai /* update power bit per jack plug/unplug */
jack_update_power(struct hda_codec * codec,struct hda_jack_callback * jack)46536c9db7aSTakashi Iwai static void jack_update_power(struct hda_codec *codec,
4661a4f69d5STakashi Iwai struct hda_jack_callback *jack)
46736c9db7aSTakashi Iwai {
46836c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
46936c9db7aSTakashi Iwai int i;
47036c9db7aSTakashi Iwai
47136c9db7aSTakashi Iwai if (!spec->num_pwrs)
47236c9db7aSTakashi Iwai return;
47336c9db7aSTakashi Iwai
4742ebab40eSTakashi Iwai if (jack && jack->nid) {
4752ebab40eSTakashi Iwai stac_toggle_power_map(codec, jack->nid,
4762ebab40eSTakashi Iwai snd_hda_jack_detect(codec, jack->nid),
47736c9db7aSTakashi Iwai true);
47836c9db7aSTakashi Iwai return;
47936c9db7aSTakashi Iwai }
48036c9db7aSTakashi Iwai
48136c9db7aSTakashi Iwai /* update all jacks */
48236c9db7aSTakashi Iwai for (i = 0; i < spec->num_pwrs; i++) {
48336c9db7aSTakashi Iwai hda_nid_t nid = spec->pwr_nids[i];
4841a4f69d5STakashi Iwai if (!snd_hda_jack_tbl_get(codec, nid))
48536c9db7aSTakashi Iwai continue;
48636c9db7aSTakashi Iwai stac_toggle_power_map(codec, nid,
48736c9db7aSTakashi Iwai snd_hda_jack_detect(codec, nid),
48836c9db7aSTakashi Iwai false);
48936c9db7aSTakashi Iwai }
49036c9db7aSTakashi Iwai
4917639a06cSTakashi Iwai snd_hda_codec_write(codec, codec->core.afg, 0,
4927639a06cSTakashi Iwai AC_VERB_IDT_SET_POWER_MAP,
49336c9db7aSTakashi Iwai spec->power_map_bits);
49436c9db7aSTakashi Iwai }
49536c9db7aSTakashi Iwai
stac_vref_event(struct hda_codec * codec,struct hda_jack_callback * event)4961a4f69d5STakashi Iwai static void stac_vref_event(struct hda_codec *codec,
4971a4f69d5STakashi Iwai struct hda_jack_callback *event)
49836c9db7aSTakashi Iwai {
49936c9db7aSTakashi Iwai unsigned int data;
50036c9db7aSTakashi Iwai
5017639a06cSTakashi Iwai data = snd_hda_codec_read(codec, codec->core.afg, 0,
50236c9db7aSTakashi Iwai AC_VERB_GET_GPIO_DATA, 0);
50336c9db7aSTakashi Iwai /* toggle VREF state based on GPIOx status */
5047639a06cSTakashi Iwai snd_hda_codec_write(codec, codec->core.afg, 0, 0x7e0,
50536c9db7aSTakashi Iwai !!(data & (1 << event->private_data)));
50636c9db7aSTakashi Iwai }
50736c9db7aSTakashi Iwai
50836c9db7aSTakashi Iwai /* initialize the power map and enable the power event to jacks that
50936c9db7aSTakashi Iwai * haven't been assigned to automute
510094a4245SVitaliy Kulikov */
stac_init_power_map(struct hda_codec * codec)51136c9db7aSTakashi Iwai static void stac_init_power_map(struct hda_codec *codec)
512b22b4821SMatthew Ranostay {
513b22b4821SMatthew Ranostay struct sigmatel_spec *spec = codec->spec;
51436c9db7aSTakashi Iwai int i;
51536c9db7aSTakashi Iwai
51636c9db7aSTakashi Iwai for (i = 0; i < spec->num_pwrs; i++) {
51736c9db7aSTakashi Iwai hda_nid_t nid = spec->pwr_nids[i];
51836c9db7aSTakashi Iwai unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
51936c9db7aSTakashi Iwai def_conf = get_defcfg_connect(def_conf);
52036c9db7aSTakashi Iwai if (def_conf == AC_JACK_PORT_COMPLEX &&
5217a9744cbSTakashi Iwai spec->vref_mute_led_nid != nid &&
5227a9744cbSTakashi Iwai is_jack_detectable(codec, nid)) {
52336c9db7aSTakashi Iwai snd_hda_jack_detect_enable_callback(codec, nid,
52436c9db7aSTakashi Iwai jack_update_power);
52536c9db7aSTakashi Iwai } else {
52636c9db7aSTakashi Iwai if (def_conf == AC_JACK_PORT_NONE)
52736c9db7aSTakashi Iwai stac_toggle_power_map(codec, nid, false, false);
52836c9db7aSTakashi Iwai else
52936c9db7aSTakashi Iwai stac_toggle_power_map(codec, nid, true, false);
53036c9db7aSTakashi Iwai }
53136c9db7aSTakashi Iwai }
532b22b4821SMatthew Ranostay }
533b22b4821SMatthew Ranostay
53436c9db7aSTakashi Iwai /*
53536c9db7aSTakashi Iwai */
53636c9db7aSTakashi Iwai
get_int_hint(struct hda_codec * codec,const char * key,int * valp)53736c9db7aSTakashi Iwai static inline bool get_int_hint(struct hda_codec *codec, const char *key,
53836c9db7aSTakashi Iwai int *valp)
539b22b4821SMatthew Ranostay {
54036c9db7aSTakashi Iwai return !snd_hda_get_int_hint(codec, key, valp);
541b22b4821SMatthew Ranostay }
542b22b4821SMatthew Ranostay
54336c9db7aSTakashi Iwai /* override some hints from the hwdep entry */
stac_store_hints(struct hda_codec * codec)54436c9db7aSTakashi Iwai static void stac_store_hints(struct hda_codec *codec)
545b22b4821SMatthew Ranostay {
546b22b4821SMatthew Ranostay struct sigmatel_spec *spec = codec->spec;
54736c9db7aSTakashi Iwai int val;
548b22b4821SMatthew Ranostay
54936c9db7aSTakashi Iwai if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
55036c9db7aSTakashi Iwai spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
55136c9db7aSTakashi Iwai spec->gpio_mask;
55236c9db7aSTakashi Iwai }
55336c9db7aSTakashi Iwai if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
55436c9db7aSTakashi Iwai spec->gpio_dir &= spec->gpio_mask;
555c507de88STakashi Iwai if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
556c507de88STakashi Iwai spec->gpio_data &= spec->gpio_mask;
55736c9db7aSTakashi Iwai if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
55836c9db7aSTakashi Iwai spec->eapd_mask &= spec->gpio_mask;
55936c9db7aSTakashi Iwai if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
56036c9db7aSTakashi Iwai spec->gpio_mute &= spec->gpio_mask;
56136c9db7aSTakashi Iwai val = snd_hda_get_bool_hint(codec, "eapd_switch");
56236c9db7aSTakashi Iwai if (val >= 0)
56336c9db7aSTakashi Iwai spec->eapd_switch = val;
564b22b4821SMatthew Ranostay }
565b22b4821SMatthew Ranostay
56636c9db7aSTakashi Iwai /*
56736c9db7aSTakashi Iwai * loopback controls
56836c9db7aSTakashi Iwai */
5695f10c4a9SMaxim Levitsky
57036c9db7aSTakashi Iwai #define stac_aloopback_info snd_ctl_boolean_mono_info
57136c9db7aSTakashi Iwai
stac_aloopback_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)57236c9db7aSTakashi Iwai static int stac_aloopback_get(struct snd_kcontrol *kcontrol,
5735f10c4a9SMaxim Levitsky struct snd_ctl_elem_value *ucontrol)
5745f10c4a9SMaxim Levitsky {
5755f10c4a9SMaxim Levitsky struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
576e1f0d669SMatthew Ranostay unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5775f10c4a9SMaxim Levitsky struct sigmatel_spec *spec = codec->spec;
5785f10c4a9SMaxim Levitsky
579e1f0d669SMatthew Ranostay ucontrol->value.integer.value[0] = !!(spec->aloopback &
580e1f0d669SMatthew Ranostay (spec->aloopback_mask << idx));
5815f10c4a9SMaxim Levitsky return 0;
5825f10c4a9SMaxim Levitsky }
5835f10c4a9SMaxim Levitsky
stac_aloopback_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)58436c9db7aSTakashi Iwai static int stac_aloopback_put(struct snd_kcontrol *kcontrol,
5855f10c4a9SMaxim Levitsky struct snd_ctl_elem_value *ucontrol)
5865f10c4a9SMaxim Levitsky {
5875f10c4a9SMaxim Levitsky struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5885f10c4a9SMaxim Levitsky struct sigmatel_spec *spec = codec->spec;
589e1f0d669SMatthew Ranostay unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5905f10c4a9SMaxim Levitsky unsigned int dac_mode;
591e1f0d669SMatthew Ranostay unsigned int val, idx_val;
5925f10c4a9SMaxim Levitsky
593e1f0d669SMatthew Ranostay idx_val = spec->aloopback_mask << idx;
594e1f0d669SMatthew Ranostay if (ucontrol->value.integer.value[0])
595e1f0d669SMatthew Ranostay val = spec->aloopback | idx_val;
596e1f0d669SMatthew Ranostay else
597e1f0d669SMatthew Ranostay val = spec->aloopback & ~idx_val;
59868ea7b2fSTakashi Iwai if (spec->aloopback == val)
5995f10c4a9SMaxim Levitsky return 0;
6005f10c4a9SMaxim Levitsky
60168ea7b2fSTakashi Iwai spec->aloopback = val;
6025f10c4a9SMaxim Levitsky
603e1f0d669SMatthew Ranostay /* Only return the bits defined by the shift value of the
604e1f0d669SMatthew Ranostay * first two bytes of the mask
605e1f0d669SMatthew Ranostay */
6067639a06cSTakashi Iwai dac_mode = snd_hda_codec_read(codec, codec->core.afg, 0,
6075f10c4a9SMaxim Levitsky kcontrol->private_value & 0xFFFF, 0x0);
608e1f0d669SMatthew Ranostay dac_mode >>= spec->aloopback_shift;
6095f10c4a9SMaxim Levitsky
610e1f0d669SMatthew Ranostay if (spec->aloopback & idx_val) {
6115f10c4a9SMaxim Levitsky snd_hda_power_up(codec);
612e1f0d669SMatthew Ranostay dac_mode |= idx_val;
6135f10c4a9SMaxim Levitsky } else {
6145f10c4a9SMaxim Levitsky snd_hda_power_down(codec);
615e1f0d669SMatthew Ranostay dac_mode &= ~idx_val;
6165f10c4a9SMaxim Levitsky }
6175f10c4a9SMaxim Levitsky
6187639a06cSTakashi Iwai snd_hda_codec_write_cache(codec, codec->core.afg, 0,
6195f10c4a9SMaxim Levitsky kcontrol->private_value >> 16, dac_mode);
6205f10c4a9SMaxim Levitsky
6215f10c4a9SMaxim Levitsky return 1;
6225f10c4a9SMaxim Levitsky }
6235f10c4a9SMaxim Levitsky
62436c9db7aSTakashi Iwai #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
62536c9db7aSTakashi Iwai { \
62636c9db7aSTakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
62736c9db7aSTakashi Iwai .name = "Analog Loopback", \
62836c9db7aSTakashi Iwai .count = cnt, \
62936c9db7aSTakashi Iwai .info = stac_aloopback_info, \
63036c9db7aSTakashi Iwai .get = stac_aloopback_get, \
63136c9db7aSTakashi Iwai .put = stac_aloopback_put, \
63236c9db7aSTakashi Iwai .private_value = verb_read | (verb_write << 16), \
63336c9db7aSTakashi Iwai }
63436c9db7aSTakashi Iwai
63536c9db7aSTakashi Iwai /*
63636c9db7aSTakashi Iwai * Mute LED handling on HP laptops
63736c9db7aSTakashi Iwai */
63836c9db7aSTakashi Iwai
63936c9db7aSTakashi Iwai /* check whether it's a HP laptop with a docking port */
hp_bnb2011_with_dock(struct hda_codec * codec)64036c9db7aSTakashi Iwai static bool hp_bnb2011_with_dock(struct hda_codec *codec)
64136c9db7aSTakashi Iwai {
6427639a06cSTakashi Iwai if (codec->core.vendor_id != 0x111d7605 &&
6437639a06cSTakashi Iwai codec->core.vendor_id != 0x111d76d1)
64436c9db7aSTakashi Iwai return false;
64536c9db7aSTakashi Iwai
6467639a06cSTakashi Iwai switch (codec->core.subsystem_id) {
64736c9db7aSTakashi Iwai case 0x103c1618:
64836c9db7aSTakashi Iwai case 0x103c1619:
64936c9db7aSTakashi Iwai case 0x103c161a:
65036c9db7aSTakashi Iwai case 0x103c161b:
65136c9db7aSTakashi Iwai case 0x103c161c:
65236c9db7aSTakashi Iwai case 0x103c161d:
65336c9db7aSTakashi Iwai case 0x103c161e:
65436c9db7aSTakashi Iwai case 0x103c161f:
65536c9db7aSTakashi Iwai
65636c9db7aSTakashi Iwai case 0x103c162a:
65736c9db7aSTakashi Iwai case 0x103c162b:
65836c9db7aSTakashi Iwai
65936c9db7aSTakashi Iwai case 0x103c1630:
66036c9db7aSTakashi Iwai case 0x103c1631:
66136c9db7aSTakashi Iwai
66236c9db7aSTakashi Iwai case 0x103c1633:
66336c9db7aSTakashi Iwai case 0x103c1634:
66436c9db7aSTakashi Iwai case 0x103c1635:
66536c9db7aSTakashi Iwai
66636c9db7aSTakashi Iwai case 0x103c3587:
66736c9db7aSTakashi Iwai case 0x103c3588:
66836c9db7aSTakashi Iwai case 0x103c3589:
66936c9db7aSTakashi Iwai case 0x103c358a:
67036c9db7aSTakashi Iwai
67136c9db7aSTakashi Iwai case 0x103c3667:
67236c9db7aSTakashi Iwai case 0x103c3668:
67336c9db7aSTakashi Iwai case 0x103c3669:
67436c9db7aSTakashi Iwai
67536c9db7aSTakashi Iwai return true;
67636c9db7aSTakashi Iwai }
67736c9db7aSTakashi Iwai return false;
67836c9db7aSTakashi Iwai }
67936c9db7aSTakashi Iwai
hp_blike_system(u32 subsystem_id)68036c9db7aSTakashi Iwai static bool hp_blike_system(u32 subsystem_id)
68136c9db7aSTakashi Iwai {
68236c9db7aSTakashi Iwai switch (subsystem_id) {
683c932b98cSTakashi Iwai case 0x103c1473: /* HP ProBook 6550b */
68436c9db7aSTakashi Iwai case 0x103c1520:
68536c9db7aSTakashi Iwai case 0x103c1521:
68636c9db7aSTakashi Iwai case 0x103c1523:
68736c9db7aSTakashi Iwai case 0x103c1524:
68836c9db7aSTakashi Iwai case 0x103c1525:
68936c9db7aSTakashi Iwai case 0x103c1722:
69036c9db7aSTakashi Iwai case 0x103c1723:
69136c9db7aSTakashi Iwai case 0x103c1724:
69236c9db7aSTakashi Iwai case 0x103c1725:
69336c9db7aSTakashi Iwai case 0x103c1726:
69436c9db7aSTakashi Iwai case 0x103c1727:
69536c9db7aSTakashi Iwai case 0x103c1728:
69636c9db7aSTakashi Iwai case 0x103c1729:
69736c9db7aSTakashi Iwai case 0x103c172a:
69836c9db7aSTakashi Iwai case 0x103c172b:
69936c9db7aSTakashi Iwai case 0x103c307e:
70036c9db7aSTakashi Iwai case 0x103c307f:
70136c9db7aSTakashi Iwai case 0x103c3080:
70236c9db7aSTakashi Iwai case 0x103c3081:
70336c9db7aSTakashi Iwai case 0x103c7007:
70436c9db7aSTakashi Iwai case 0x103c7008:
70536c9db7aSTakashi Iwai return true;
70636c9db7aSTakashi Iwai }
70736c9db7aSTakashi Iwai return false;
70836c9db7aSTakashi Iwai }
70936c9db7aSTakashi Iwai
set_hp_led_gpio(struct hda_codec * codec)71036c9db7aSTakashi Iwai static void set_hp_led_gpio(struct hda_codec *codec)
71136c9db7aSTakashi Iwai {
71236c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
71336c9db7aSTakashi Iwai unsigned int gpio;
71436c9db7aSTakashi Iwai
71536c9db7aSTakashi Iwai if (spec->gpio_led)
71636c9db7aSTakashi Iwai return;
71736c9db7aSTakashi Iwai
7187639a06cSTakashi Iwai gpio = snd_hda_param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
71936c9db7aSTakashi Iwai gpio &= AC_GPIO_IO_COUNT;
72036c9db7aSTakashi Iwai if (gpio > 3)
72136c9db7aSTakashi Iwai spec->gpio_led = 0x08; /* GPIO 3 */
72236c9db7aSTakashi Iwai else
72336c9db7aSTakashi Iwai spec->gpio_led = 0x01; /* GPIO 0 */
72436c9db7aSTakashi Iwai }
72536c9db7aSTakashi Iwai
72636c9db7aSTakashi Iwai /*
72736c9db7aSTakashi Iwai * This method searches for the mute LED GPIO configuration
72836c9db7aSTakashi Iwai * provided as OEM string in SMBIOS. The format of that string
72936c9db7aSTakashi Iwai * is HP_Mute_LED_P_G or HP_Mute_LED_P
73036c9db7aSTakashi Iwai * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
73136c9db7aSTakashi Iwai * that corresponds to the NOT muted state of the master volume
73236c9db7aSTakashi Iwai * and G is the index of the GPIO to use as the mute LED control (0..9)
73336c9db7aSTakashi Iwai * If _G portion is missing it is assigned based on the codec ID
73436c9db7aSTakashi Iwai *
73536c9db7aSTakashi Iwai * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
73636c9db7aSTakashi Iwai * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
73736c9db7aSTakashi Iwai *
73836c9db7aSTakashi Iwai *
73936c9db7aSTakashi Iwai * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
74036c9db7aSTakashi Iwai * SMBIOS - at least the ones I have seen do not have them - which include
74136c9db7aSTakashi Iwai * my own system (HP Pavilion dv6-1110ax) and my cousin's
74236c9db7aSTakashi Iwai * HP Pavilion dv9500t CTO.
74336c9db7aSTakashi Iwai * Need more information on whether it is true across the entire series.
74436c9db7aSTakashi Iwai * -- kunal
74536c9db7aSTakashi Iwai */
find_mute_led_cfg(struct hda_codec * codec,int default_polarity)74636c9db7aSTakashi Iwai static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
74736c9db7aSTakashi Iwai {
74836c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
74936c9db7aSTakashi Iwai const struct dmi_device *dev = NULL;
75036c9db7aSTakashi Iwai
75136c9db7aSTakashi Iwai if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
75236c9db7aSTakashi Iwai get_int_hint(codec, "gpio_led_polarity",
75336c9db7aSTakashi Iwai &spec->gpio_led_polarity);
75436c9db7aSTakashi Iwai return 1;
75536c9db7aSTakashi Iwai }
75636c9db7aSTakashi Iwai
75736c9db7aSTakashi Iwai while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
758e7fc4960SToralf Förster if (sscanf(dev->name, "HP_Mute_LED_%u_%x",
75936c9db7aSTakashi Iwai &spec->gpio_led_polarity,
76036c9db7aSTakashi Iwai &spec->gpio_led) == 2) {
76136c9db7aSTakashi Iwai unsigned int max_gpio;
7627639a06cSTakashi Iwai max_gpio = snd_hda_param_read(codec, codec->core.afg,
76336c9db7aSTakashi Iwai AC_PAR_GPIO_CAP);
76436c9db7aSTakashi Iwai max_gpio &= AC_GPIO_IO_COUNT;
76536c9db7aSTakashi Iwai if (spec->gpio_led < max_gpio)
76636c9db7aSTakashi Iwai spec->gpio_led = 1 << spec->gpio_led;
76736c9db7aSTakashi Iwai else
76836c9db7aSTakashi Iwai spec->vref_mute_led_nid = spec->gpio_led;
76936c9db7aSTakashi Iwai return 1;
77036c9db7aSTakashi Iwai }
771e7fc4960SToralf Förster if (sscanf(dev->name, "HP_Mute_LED_%u",
77236c9db7aSTakashi Iwai &spec->gpio_led_polarity) == 1) {
77336c9db7aSTakashi Iwai set_hp_led_gpio(codec);
77436c9db7aSTakashi Iwai return 1;
77536c9db7aSTakashi Iwai }
77636c9db7aSTakashi Iwai /* BIOS bug: unfilled OEM string */
77736c9db7aSTakashi Iwai if (strstr(dev->name, "HP_Mute_LED_P_G")) {
77836c9db7aSTakashi Iwai set_hp_led_gpio(codec);
77936c9db7aSTakashi Iwai if (default_polarity >= 0)
78036c9db7aSTakashi Iwai spec->gpio_led_polarity = default_polarity;
78136c9db7aSTakashi Iwai else
78236c9db7aSTakashi Iwai spec->gpio_led_polarity = 1;
78336c9db7aSTakashi Iwai return 1;
78436c9db7aSTakashi Iwai }
78536c9db7aSTakashi Iwai }
78636c9db7aSTakashi Iwai
78736c9db7aSTakashi Iwai /*
78836c9db7aSTakashi Iwai * Fallback case - if we don't find the DMI strings,
78936c9db7aSTakashi Iwai * we statically set the GPIO - if not a B-series system
79036c9db7aSTakashi Iwai * and default polarity is provided
79136c9db7aSTakashi Iwai */
7927639a06cSTakashi Iwai if (!hp_blike_system(codec->core.subsystem_id) &&
79336c9db7aSTakashi Iwai (default_polarity == 0 || default_polarity == 1)) {
79436c9db7aSTakashi Iwai set_hp_led_gpio(codec);
79536c9db7aSTakashi Iwai spec->gpio_led_polarity = default_polarity;
79636c9db7aSTakashi Iwai return 1;
79736c9db7aSTakashi Iwai }
79836c9db7aSTakashi Iwai return 0;
79936c9db7aSTakashi Iwai }
80036c9db7aSTakashi Iwai
801303985f8SDavid Henningsson /* check whether a built-in speaker is included in parsed pins */
has_builtin_speaker(struct hda_codec * codec)802303985f8SDavid Henningsson static bool has_builtin_speaker(struct hda_codec *codec)
803303985f8SDavid Henningsson {
804303985f8SDavid Henningsson struct sigmatel_spec *spec = codec->spec;
805caf3c043SMichał Mirosław const hda_nid_t *nid_pin;
806303985f8SDavid Henningsson int nids, i;
807303985f8SDavid Henningsson
808303985f8SDavid Henningsson if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
809303985f8SDavid Henningsson nid_pin = spec->gen.autocfg.line_out_pins;
810303985f8SDavid Henningsson nids = spec->gen.autocfg.line_outs;
811303985f8SDavid Henningsson } else {
812303985f8SDavid Henningsson nid_pin = spec->gen.autocfg.speaker_pins;
813303985f8SDavid Henningsson nids = spec->gen.autocfg.speaker_outs;
814303985f8SDavid Henningsson }
815303985f8SDavid Henningsson
816303985f8SDavid Henningsson for (i = 0; i < nids; i++) {
817303985f8SDavid Henningsson unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
818303985f8SDavid Henningsson if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
819303985f8SDavid Henningsson return true;
820303985f8SDavid Henningsson }
821303985f8SDavid Henningsson return false;
822303985f8SDavid Henningsson }
823303985f8SDavid Henningsson
82436c9db7aSTakashi Iwai /*
82536c9db7aSTakashi Iwai * PC beep controls
82636c9db7aSTakashi Iwai */
82736c9db7aSTakashi Iwai
82836c9db7aSTakashi Iwai /* create PC beep volume controls */
stac_auto_create_beep_ctls(struct hda_codec * codec,hda_nid_t nid)82936c9db7aSTakashi Iwai static int stac_auto_create_beep_ctls(struct hda_codec *codec,
83036c9db7aSTakashi Iwai hda_nid_t nid)
83136c9db7aSTakashi Iwai {
83236c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
83336c9db7aSTakashi Iwai u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
83436c9db7aSTakashi Iwai struct snd_kcontrol_new *knew;
83535ace5e8STakashi Iwai static const struct snd_kcontrol_new abeep_mute_ctl =
83636c9db7aSTakashi Iwai HDA_CODEC_MUTE(NULL, 0, 0, 0);
83735ace5e8STakashi Iwai static const struct snd_kcontrol_new dbeep_mute_ctl =
83836c9db7aSTakashi Iwai HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0);
83935ace5e8STakashi Iwai static const struct snd_kcontrol_new beep_vol_ctl =
84036c9db7aSTakashi Iwai HDA_CODEC_VOLUME(NULL, 0, 0, 0);
84136c9db7aSTakashi Iwai
842c7fabbc5SRandy Dunlap /* check for mute support for the amp */
84336c9db7aSTakashi Iwai if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
84436c9db7aSTakashi Iwai const struct snd_kcontrol_new *temp;
84536c9db7aSTakashi Iwai if (spec->anabeep_nid == nid)
84636c9db7aSTakashi Iwai temp = &abeep_mute_ctl;
84736c9db7aSTakashi Iwai else
84836c9db7aSTakashi Iwai temp = &dbeep_mute_ctl;
84936c9db7aSTakashi Iwai knew = snd_hda_gen_add_kctl(&spec->gen,
85036c9db7aSTakashi Iwai "Beep Playback Switch", temp);
85136c9db7aSTakashi Iwai if (!knew)
85236c9db7aSTakashi Iwai return -ENOMEM;
85336c9db7aSTakashi Iwai knew->private_value =
85436c9db7aSTakashi Iwai HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
85536c9db7aSTakashi Iwai }
85636c9db7aSTakashi Iwai
85736c9db7aSTakashi Iwai /* check to see if there is volume support for the amp */
85836c9db7aSTakashi Iwai if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
85936c9db7aSTakashi Iwai knew = snd_hda_gen_add_kctl(&spec->gen,
86036c9db7aSTakashi Iwai "Beep Playback Volume",
86136c9db7aSTakashi Iwai &beep_vol_ctl);
86236c9db7aSTakashi Iwai if (!knew)
86336c9db7aSTakashi Iwai return -ENOMEM;
86436c9db7aSTakashi Iwai knew->private_value =
86536c9db7aSTakashi Iwai HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT);
86636c9db7aSTakashi Iwai }
86736c9db7aSTakashi Iwai return 0;
86836c9db7aSTakashi Iwai }
86936c9db7aSTakashi Iwai
87036c9db7aSTakashi Iwai #ifdef CONFIG_SND_HDA_INPUT_BEEP
87136c9db7aSTakashi Iwai #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info
87236c9db7aSTakashi Iwai
stac_dig_beep_switch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)87336c9db7aSTakashi Iwai static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
87436c9db7aSTakashi Iwai struct snd_ctl_elem_value *ucontrol)
87536c9db7aSTakashi Iwai {
87636c9db7aSTakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
87736c9db7aSTakashi Iwai ucontrol->value.integer.value[0] = codec->beep->enabled;
87836c9db7aSTakashi Iwai return 0;
87936c9db7aSTakashi Iwai }
88036c9db7aSTakashi Iwai
stac_dig_beep_switch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)88136c9db7aSTakashi Iwai static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
88236c9db7aSTakashi Iwai struct snd_ctl_elem_value *ucontrol)
88336c9db7aSTakashi Iwai {
88436c9db7aSTakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
88536c9db7aSTakashi Iwai return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
88636c9db7aSTakashi Iwai }
88736c9db7aSTakashi Iwai
88836c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac_dig_beep_ctrl = {
88936c9db7aSTakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
89036c9db7aSTakashi Iwai .name = "Beep Playback Switch",
89136c9db7aSTakashi Iwai .info = stac_dig_beep_switch_info,
89236c9db7aSTakashi Iwai .get = stac_dig_beep_switch_get,
89336c9db7aSTakashi Iwai .put = stac_dig_beep_switch_put,
89436c9db7aSTakashi Iwai };
89536c9db7aSTakashi Iwai
stac_beep_switch_ctl(struct hda_codec * codec)89636c9db7aSTakashi Iwai static int stac_beep_switch_ctl(struct hda_codec *codec)
89736c9db7aSTakashi Iwai {
89836c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
89936c9db7aSTakashi Iwai
90036c9db7aSTakashi Iwai if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl))
90136c9db7aSTakashi Iwai return -ENOMEM;
90236c9db7aSTakashi Iwai return 0;
90336c9db7aSTakashi Iwai }
90436c9db7aSTakashi Iwai #endif
90536c9db7aSTakashi Iwai
90636c9db7aSTakashi Iwai /*
90742875479STakashi Iwai * SPDIF-out mux controls
90842875479STakashi Iwai */
90942875479STakashi Iwai
stac_smux_enum_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)91042875479STakashi Iwai static int stac_smux_enum_info(struct snd_kcontrol *kcontrol,
91142875479STakashi Iwai struct snd_ctl_elem_info *uinfo)
91242875479STakashi Iwai {
91342875479STakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
91442875479STakashi Iwai struct sigmatel_spec *spec = codec->spec;
91542875479STakashi Iwai return snd_hda_input_mux_info(&spec->spdif_mux, uinfo);
91642875479STakashi Iwai }
91742875479STakashi Iwai
stac_smux_enum_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)91842875479STakashi Iwai static int stac_smux_enum_get(struct snd_kcontrol *kcontrol,
91942875479STakashi Iwai struct snd_ctl_elem_value *ucontrol)
92042875479STakashi Iwai {
92142875479STakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
92242875479STakashi Iwai struct sigmatel_spec *spec = codec->spec;
92342875479STakashi Iwai unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
92442875479STakashi Iwai
92542875479STakashi Iwai ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
92642875479STakashi Iwai return 0;
92742875479STakashi Iwai }
92842875479STakashi Iwai
stac_smux_enum_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)92942875479STakashi Iwai static int stac_smux_enum_put(struct snd_kcontrol *kcontrol,
93042875479STakashi Iwai struct snd_ctl_elem_value *ucontrol)
93142875479STakashi Iwai {
93242875479STakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
93342875479STakashi Iwai struct sigmatel_spec *spec = codec->spec;
93442875479STakashi Iwai unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
93542875479STakashi Iwai
93642875479STakashi Iwai return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol,
93742875479STakashi Iwai spec->gen.autocfg.dig_out_pins[smux_idx],
93842875479STakashi Iwai &spec->cur_smux[smux_idx]);
93942875479STakashi Iwai }
94042875479STakashi Iwai
941fdbf0488SBhumika Goyal static const struct snd_kcontrol_new stac_smux_mixer = {
94242875479STakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
94342875479STakashi Iwai .name = "IEC958 Playback Source",
94442875479STakashi Iwai /* count set later */
94542875479STakashi Iwai .info = stac_smux_enum_info,
94642875479STakashi Iwai .get = stac_smux_enum_get,
94742875479STakashi Iwai .put = stac_smux_enum_put,
94842875479STakashi Iwai };
94942875479STakashi Iwai
95042875479STakashi Iwai static const char * const stac_spdif_labels[] = {
95142875479STakashi Iwai "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL
95242875479STakashi Iwai };
95342875479STakashi Iwai
stac_create_spdif_mux_ctls(struct hda_codec * codec)95442875479STakashi Iwai static int stac_create_spdif_mux_ctls(struct hda_codec *codec)
95542875479STakashi Iwai {
95642875479STakashi Iwai struct sigmatel_spec *spec = codec->spec;
95742875479STakashi Iwai struct auto_pin_cfg *cfg = &spec->gen.autocfg;
95842875479STakashi Iwai const char * const *labels = spec->spdif_labels;
95942875479STakashi Iwai struct snd_kcontrol_new *kctl;
96042875479STakashi Iwai int i, num_cons;
96142875479STakashi Iwai
96242875479STakashi Iwai if (cfg->dig_outs < 1)
96342875479STakashi Iwai return 0;
96442875479STakashi Iwai
96542875479STakashi Iwai num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]);
96642875479STakashi Iwai if (num_cons <= 1)
96742875479STakashi Iwai return 0;
96842875479STakashi Iwai
96942875479STakashi Iwai if (!labels)
97042875479STakashi Iwai labels = stac_spdif_labels;
97142875479STakashi Iwai for (i = 0; i < num_cons; i++) {
97242875479STakashi Iwai if (snd_BUG_ON(!labels[i]))
97342875479STakashi Iwai return -EINVAL;
9746194b99dSTakashi Iwai snd_hda_add_imux_item(codec, &spec->spdif_mux, labels[i], i, NULL);
97542875479STakashi Iwai }
97642875479STakashi Iwai
97742875479STakashi Iwai kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
97842875479STakashi Iwai if (!kctl)
97942875479STakashi Iwai return -ENOMEM;
98042875479STakashi Iwai kctl->count = cfg->dig_outs;
98142875479STakashi Iwai
98242875479STakashi Iwai return 0;
98342875479STakashi Iwai }
98442875479STakashi Iwai
9852b63536fSTakashi Iwai static const struct hda_verb stac9200_eapd_init[] = {
9861194b5b7STakashi Iwai /* set dac0mux for dac converter */
9871194b5b7STakashi Iwai {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9881194b5b7STakashi Iwai {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
9891194b5b7STakashi Iwai {}
9901194b5b7STakashi Iwai };
9911194b5b7STakashi Iwai
9922b63536fSTakashi Iwai static const struct hda_verb dell_eq_core_init[] = {
993d654a660SMatthew Ranostay /* set master volume to max value without distortion
994d654a660SMatthew Ranostay * and direct control */
995d654a660SMatthew Ranostay { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
996d654a660SMatthew Ranostay {}
997d654a660SMatthew Ranostay };
998d654a660SMatthew Ranostay
9992b63536fSTakashi Iwai static const struct hda_verb stac92hd73xx_core_init[] = {
1000e1f0d669SMatthew Ranostay /* set master volume and direct control */
1001e1f0d669SMatthew Ranostay { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1002e1f0d669SMatthew Ranostay {}
1003e1f0d669SMatthew Ranostay };
1004e1f0d669SMatthew Ranostay
10052b63536fSTakashi Iwai static const struct hda_verb stac92hd83xxx_core_init[] = {
1006d0513fc6SMatthew Ranostay /* power state controls amps */
1007d0513fc6SMatthew Ranostay { 0x01, AC_VERB_SET_EAPD, 1 << 2},
1008574f3c4fSHerton Ronaldo Krzesinski {}
1009d0513fc6SMatthew Ranostay };
1010d0513fc6SMatthew Ranostay
10115556e147SVitaliy Kulikov static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
10125556e147SVitaliy Kulikov { 0x22, 0x785, 0x43 },
10135556e147SVitaliy Kulikov { 0x22, 0x782, 0xe0 },
10145556e147SVitaliy Kulikov { 0x22, 0x795, 0x00 },
10155556e147SVitaliy Kulikov {}
10165556e147SVitaliy Kulikov };
10175556e147SVitaliy Kulikov
10182b63536fSTakashi Iwai static const struct hda_verb stac92hd71bxx_core_init[] = {
1019e035b841SMatthew Ranostay /* set master volume and direct control */
1020e035b841SMatthew Ranostay { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1021574f3c4fSHerton Ronaldo Krzesinski {}
1022541eee87SMatthew Ranostay };
1023541eee87SMatthew Ranostay
1024a551d914STakashi Iwai static const hda_nid_t stac92hd71bxx_unmute_nids[] = {
1025ca8d33fcSMatthew Ranostay /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
1026a551d914STakashi Iwai 0x0f, 0x0a, 0x0d, 0
1027e035b841SMatthew Ranostay };
1028e035b841SMatthew Ranostay
10292b63536fSTakashi Iwai static const struct hda_verb stac925x_core_init[] = {
10308e21c34cSTobin Davis /* set dac0mux for dac converter */
10318e21c34cSTobin Davis { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
1032c9280d68STakashi Iwai /* mute the master volume */
1033c9280d68STakashi Iwai { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10348e21c34cSTobin Davis {}
10358e21c34cSTobin Davis };
10368e21c34cSTobin Davis
10372b63536fSTakashi Iwai static const struct hda_verb stac922x_core_init[] = {
10382f2f4251SMatt /* set master volume and direct control */
1039c7d4b2faSMatt { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
10402f2f4251SMatt {}
10412f2f4251SMatt };
10422f2f4251SMatt
10432b63536fSTakashi Iwai static const struct hda_verb d965_core_init[] = {
104419039bd0STakashi Iwai /* unmute node 0x1b */
104519039bd0STakashi Iwai { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
104619039bd0STakashi Iwai /* select node 0x03 as DAC */
104719039bd0STakashi Iwai { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
104819039bd0STakashi Iwai {}
104919039bd0STakashi Iwai };
105019039bd0STakashi Iwai
10512b63536fSTakashi Iwai static const struct hda_verb dell_3st_core_init[] = {
1052ccca7cdcSTakashi Iwai /* don't set delta bit */
1053ccca7cdcSTakashi Iwai {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
1054ccca7cdcSTakashi Iwai /* unmute node 0x1b */
1055ccca7cdcSTakashi Iwai {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1056ccca7cdcSTakashi Iwai /* select node 0x03 as DAC */
1057ccca7cdcSTakashi Iwai {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
1058ccca7cdcSTakashi Iwai {}
1059ccca7cdcSTakashi Iwai };
1060ccca7cdcSTakashi Iwai
10612b63536fSTakashi Iwai static const struct hda_verb stac927x_core_init[] = {
10623cc08dc6SMatt Porter /* set master volume and direct control */
10633cc08dc6SMatt Porter { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
10641cd2224cSMatthew Ranostay /* enable analog pc beep path */
10651cd2224cSMatthew Ranostay { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
10663cc08dc6SMatt Porter {}
10673cc08dc6SMatt Porter };
10683cc08dc6SMatt Porter
10692b63536fSTakashi Iwai static const struct hda_verb stac927x_volknob_core_init[] = {
107054930531STakashi Iwai /* don't set delta bit */
107154930531STakashi Iwai {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
107254930531STakashi Iwai /* enable analog pc beep path */
107354930531STakashi Iwai {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
107454930531STakashi Iwai {}
107554930531STakashi Iwai };
107654930531STakashi Iwai
10772b63536fSTakashi Iwai static const struct hda_verb stac9205_core_init[] = {
1078f3302a59SMatt Porter /* set master volume and direct control */
1079f3302a59SMatt Porter { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1080d0513fc6SMatthew Ranostay /* enable analog pc beep path */
1081d0513fc6SMatthew Ranostay { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
1082f3302a59SMatt Porter {}
1083f3302a59SMatt Porter };
1084f3302a59SMatt Porter
108536c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback =
108636c9db7aSTakashi Iwai STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3);
1087b22b4821SMatthew Ranostay
108836c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback =
108936c9db7aSTakashi Iwai STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4);
10905f10c4a9SMaxim Levitsky
109136c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback =
109236c9db7aSTakashi Iwai STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5);
10932fc99890SNickolas Lloyd
109436c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac92hd71bxx_loopback =
109536c9db7aSTakashi Iwai STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2);
10962f2f4251SMatt
109736c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac9205_loopback =
109836c9db7aSTakashi Iwai STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1);
1099e1f0d669SMatthew Ranostay
110036c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac927x_loopback =
110136c9db7aSTakashi Iwai STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1);
11022f2f4251SMatt
1103d39a3ae8STakashi Iwai static const struct hda_pintbl ref9200_pin_configs[] = {
1104d39a3ae8STakashi Iwai { 0x08, 0x01c47010 },
1105d39a3ae8STakashi Iwai { 0x09, 0x01447010 },
1106d39a3ae8STakashi Iwai { 0x0d, 0x0221401f },
1107d39a3ae8STakashi Iwai { 0x0e, 0x01114010 },
1108d39a3ae8STakashi Iwai { 0x0f, 0x02a19020 },
1109d39a3ae8STakashi Iwai { 0x10, 0x01a19021 },
1110d39a3ae8STakashi Iwai { 0x11, 0x90100140 },
1111d39a3ae8STakashi Iwai { 0x12, 0x01813122 },
1112d39a3ae8STakashi Iwai {}
11132f2f4251SMatt };
11142f2f4251SMatt
1115d39a3ae8STakashi Iwai static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1116d39a3ae8STakashi Iwai { 0x08, 0x400000fe },
1117d39a3ae8STakashi Iwai { 0x09, 0x404500f4 },
1118d39a3ae8STakashi Iwai { 0x0d, 0x400100f0 },
1119d39a3ae8STakashi Iwai { 0x0e, 0x90110010 },
1120d39a3ae8STakashi Iwai { 0x0f, 0x400100f1 },
1121d39a3ae8STakashi Iwai { 0x10, 0x02a1902e },
1122d39a3ae8STakashi Iwai { 0x11, 0x500000f2 },
1123d39a3ae8STakashi Iwai { 0x12, 0x500000f3 },
1124d39a3ae8STakashi Iwai {}
112558eec423SMauro Carvalho Chehab };
1126d39a3ae8STakashi Iwai
1127d39a3ae8STakashi Iwai static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1128d39a3ae8STakashi Iwai { 0x08, 0x400000fe },
1129d39a3ae8STakashi Iwai { 0x09, 0x404500f4 },
1130d39a3ae8STakashi Iwai { 0x0d, 0x400100f0 },
1131d39a3ae8STakashi Iwai { 0x0e, 0x90110010 },
1132d39a3ae8STakashi Iwai { 0x0f, 0x400100f1 },
1133d39a3ae8STakashi Iwai { 0x10, 0x02a1902e },
1134d39a3ae8STakashi Iwai { 0x11, 0x500000f2 },
1135d39a3ae8STakashi Iwai { 0x12, 0x500000f3 },
1136d39a3ae8STakashi Iwai {}
113758eec423SMauro Carvalho Chehab };
113858eec423SMauro Carvalho Chehab
1139dfe495d0STakashi Iwai /*
1140dfe495d0STakashi Iwai STAC 9200 pin configs for
1141dfe495d0STakashi Iwai 102801A8
1142dfe495d0STakashi Iwai 102801DE
1143dfe495d0STakashi Iwai 102801E8
1144dfe495d0STakashi Iwai */
1145d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1146d39a3ae8STakashi Iwai { 0x08, 0x400001f0 },
1147d39a3ae8STakashi Iwai { 0x09, 0x400001f1 },
1148d39a3ae8STakashi Iwai { 0x0d, 0x02214030 },
1149d39a3ae8STakashi Iwai { 0x0e, 0x01014010 },
1150d39a3ae8STakashi Iwai { 0x0f, 0x02a19020 },
1151d39a3ae8STakashi Iwai { 0x10, 0x01a19021 },
1152d39a3ae8STakashi Iwai { 0x11, 0x90100140 },
1153d39a3ae8STakashi Iwai { 0x12, 0x01813122 },
1154d39a3ae8STakashi Iwai {}
1155dfe495d0STakashi Iwai };
1156dfe495d0STakashi Iwai
1157dfe495d0STakashi Iwai /*
1158dfe495d0STakashi Iwai STAC 9200 pin configs for
1159dfe495d0STakashi Iwai 102801C0
1160dfe495d0STakashi Iwai 102801C1
1161dfe495d0STakashi Iwai */
1162d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1163d39a3ae8STakashi Iwai { 0x08, 0x400001f0 },
1164d39a3ae8STakashi Iwai { 0x09, 0x400001f1 },
1165d39a3ae8STakashi Iwai { 0x0d, 0x0221401f },
1166d39a3ae8STakashi Iwai { 0x0e, 0x01014010 },
1167d39a3ae8STakashi Iwai { 0x0f, 0x01813020 },
1168d39a3ae8STakashi Iwai { 0x10, 0x02a19021 },
1169d39a3ae8STakashi Iwai { 0x11, 0x90100140 },
1170d39a3ae8STakashi Iwai { 0x12, 0x400001f2 },
1171d39a3ae8STakashi Iwai {}
1172dfe495d0STakashi Iwai };
1173dfe495d0STakashi Iwai
1174dfe495d0STakashi Iwai /*
1175dfe495d0STakashi Iwai STAC 9200 pin configs for
1176dfe495d0STakashi Iwai 102801C4 (Dell Dimension E310)
1177dfe495d0STakashi Iwai 102801C5
1178dfe495d0STakashi Iwai 102801C7
1179dfe495d0STakashi Iwai 102801D9
1180dfe495d0STakashi Iwai 102801DA
1181dfe495d0STakashi Iwai 102801E3
1182dfe495d0STakashi Iwai */
1183d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1184d39a3ae8STakashi Iwai { 0x08, 0x400001f0 },
1185d39a3ae8STakashi Iwai { 0x09, 0x400001f1 },
1186d39a3ae8STakashi Iwai { 0x0d, 0x0221401f },
1187d39a3ae8STakashi Iwai { 0x0e, 0x01014010 },
1188d39a3ae8STakashi Iwai { 0x0f, 0x01813020 },
1189d39a3ae8STakashi Iwai { 0x10, 0x01a19021 },
1190d39a3ae8STakashi Iwai { 0x11, 0x90100140 },
1191d39a3ae8STakashi Iwai { 0x12, 0x400001f2 },
1192d39a3ae8STakashi Iwai {}
1193dfe495d0STakashi Iwai };
1194dfe495d0STakashi Iwai
1195dfe495d0STakashi Iwai
1196dfe495d0STakashi Iwai /*
1197dfe495d0STakashi Iwai STAC 9200-32 pin configs for
1198dfe495d0STakashi Iwai 102801B5 (Dell Inspiron 630m)
1199dfe495d0STakashi Iwai 102801D8 (Dell Inspiron 640m)
1200dfe495d0STakashi Iwai */
1201d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1202d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1203d39a3ae8STakashi Iwai { 0x09, 0x03441340 },
1204d39a3ae8STakashi Iwai { 0x0d, 0x0321121f },
1205d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1206d39a3ae8STakashi Iwai { 0x0f, 0x408003fb },
1207d39a3ae8STakashi Iwai { 0x10, 0x03a11020 },
1208d39a3ae8STakashi Iwai { 0x11, 0x401003fc },
1209d39a3ae8STakashi Iwai { 0x12, 0x403003fd },
1210d39a3ae8STakashi Iwai {}
1211dfe495d0STakashi Iwai };
1212dfe495d0STakashi Iwai
1213dfe495d0STakashi Iwai /*
1214dfe495d0STakashi Iwai STAC 9200-32 pin configs for
1215dfe495d0STakashi Iwai 102801C2 (Dell Latitude D620)
1216dfe495d0STakashi Iwai 102801C8
1217dfe495d0STakashi Iwai 102801CC (Dell Latitude D820)
1218dfe495d0STakashi Iwai 102801D4
1219dfe495d0STakashi Iwai 102801D6
1220dfe495d0STakashi Iwai */
1221d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1222d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1223d39a3ae8STakashi Iwai { 0x09, 0x0144131f },
1224d39a3ae8STakashi Iwai { 0x0d, 0x0321121f },
1225d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1226d39a3ae8STakashi Iwai { 0x0f, 0x90a70321 },
1227d39a3ae8STakashi Iwai { 0x10, 0x03a11020 },
1228d39a3ae8STakashi Iwai { 0x11, 0x401003fb },
1229d39a3ae8STakashi Iwai { 0x12, 0x40f000fc },
1230d39a3ae8STakashi Iwai {}
1231dfe495d0STakashi Iwai };
1232dfe495d0STakashi Iwai
1233dfe495d0STakashi Iwai /*
1234dfe495d0STakashi Iwai STAC 9200-32 pin configs for
1235dfe495d0STakashi Iwai 102801CE (Dell XPS M1710)
1236dfe495d0STakashi Iwai 102801CF (Dell Precision M90)
1237dfe495d0STakashi Iwai */
1238d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1239d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1240d39a3ae8STakashi Iwai { 0x09, 0x01441340 },
1241d39a3ae8STakashi Iwai { 0x0d, 0x0421421f },
1242d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1243d39a3ae8STakashi Iwai { 0x0f, 0x408003fb },
1244d39a3ae8STakashi Iwai { 0x10, 0x04a1102e },
1245d39a3ae8STakashi Iwai { 0x11, 0x90170311 },
1246d39a3ae8STakashi Iwai { 0x12, 0x403003fc },
1247d39a3ae8STakashi Iwai {}
1248dfe495d0STakashi Iwai };
1249dfe495d0STakashi Iwai
1250dfe495d0STakashi Iwai /*
1251dfe495d0STakashi Iwai STAC 9200-32 pin configs for
1252dfe495d0STakashi Iwai 102801C9
1253dfe495d0STakashi Iwai 102801CA
1254dfe495d0STakashi Iwai 102801CB (Dell Latitude 120L)
1255dfe495d0STakashi Iwai 102801D3
1256dfe495d0STakashi Iwai */
1257d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1258d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1259d39a3ae8STakashi Iwai { 0x09, 0x404003fb },
1260d39a3ae8STakashi Iwai { 0x0d, 0x0321121f },
1261d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1262d39a3ae8STakashi Iwai { 0x0f, 0x408003fc },
1263d39a3ae8STakashi Iwai { 0x10, 0x03a11020 },
1264d39a3ae8STakashi Iwai { 0x11, 0x401003fd },
1265d39a3ae8STakashi Iwai { 0x12, 0x403003fe },
1266d39a3ae8STakashi Iwai {}
1267dfe495d0STakashi Iwai };
1268dfe495d0STakashi Iwai
1269dfe495d0STakashi Iwai /*
1270dfe495d0STakashi Iwai STAC 9200-32 pin configs for
1271dfe495d0STakashi Iwai 102801BD (Dell Inspiron E1505n)
1272dfe495d0STakashi Iwai 102801EE
1273dfe495d0STakashi Iwai 102801EF
1274dfe495d0STakashi Iwai */
1275d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1276d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1277d39a3ae8STakashi Iwai { 0x09, 0x01441340 },
1278d39a3ae8STakashi Iwai { 0x0d, 0x0421121f },
1279d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1280d39a3ae8STakashi Iwai { 0x0f, 0x408003fb },
1281d39a3ae8STakashi Iwai { 0x10, 0x04a11020 },
1282d39a3ae8STakashi Iwai { 0x11, 0x401003fc },
1283d39a3ae8STakashi Iwai { 0x12, 0x403003fd },
1284d39a3ae8STakashi Iwai {}
1285dfe495d0STakashi Iwai };
1286dfe495d0STakashi Iwai
1287dfe495d0STakashi Iwai /*
1288dfe495d0STakashi Iwai STAC 9200-32 pin configs for
1289dfe495d0STakashi Iwai 102801F5 (Dell Inspiron 1501)
1290dfe495d0STakashi Iwai 102801F6
1291dfe495d0STakashi Iwai */
1292d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1293d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1294d39a3ae8STakashi Iwai { 0x09, 0x404003fb },
1295d39a3ae8STakashi Iwai { 0x0d, 0x0421121f },
1296d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1297d39a3ae8STakashi Iwai { 0x0f, 0x408003fc },
1298d39a3ae8STakashi Iwai { 0x10, 0x04a11020 },
1299d39a3ae8STakashi Iwai { 0x11, 0x401003fd },
1300d39a3ae8STakashi Iwai { 0x12, 0x403003fe },
1301d39a3ae8STakashi Iwai {}
1302dfe495d0STakashi Iwai };
1303dfe495d0STakashi Iwai
1304dfe495d0STakashi Iwai /*
1305dfe495d0STakashi Iwai STAC 9200-32
1306dfe495d0STakashi Iwai 102801CD (Dell Inspiron E1705/9400)
1307dfe495d0STakashi Iwai */
1308d39a3ae8STakashi Iwai static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1309d39a3ae8STakashi Iwai { 0x08, 0x40c003fa },
1310d39a3ae8STakashi Iwai { 0x09, 0x01441340 },
1311d39a3ae8STakashi Iwai { 0x0d, 0x0421121f },
1312d39a3ae8STakashi Iwai { 0x0e, 0x90170310 },
1313d39a3ae8STakashi Iwai { 0x0f, 0x90170310 },
1314d39a3ae8STakashi Iwai { 0x10, 0x04a11020 },
1315d39a3ae8STakashi Iwai { 0x11, 0x90170310 },
1316d39a3ae8STakashi Iwai { 0x12, 0x40f003fc },
1317d39a3ae8STakashi Iwai {}
1318dfe495d0STakashi Iwai };
1319dfe495d0STakashi Iwai
1320d39a3ae8STakashi Iwai static const struct hda_pintbl oqo9200_pin_configs[] = {
1321d39a3ae8STakashi Iwai { 0x08, 0x40c000f0 },
1322d39a3ae8STakashi Iwai { 0x09, 0x404000f1 },
1323d39a3ae8STakashi Iwai { 0x0d, 0x0221121f },
1324d39a3ae8STakashi Iwai { 0x0e, 0x02211210 },
1325d39a3ae8STakashi Iwai { 0x0f, 0x90170111 },
1326d39a3ae8STakashi Iwai { 0x10, 0x90a70120 },
1327d39a3ae8STakashi Iwai { 0x11, 0x400000f2 },
1328d39a3ae8STakashi Iwai { 0x12, 0x400000f3 },
1329d39a3ae8STakashi Iwai {}
1330bf277785STobin Davis };
1331bf277785STobin Davis
1332078502b5SDarren Stevens /*
1333078502b5SDarren Stevens * STAC 92HD700
1334078502b5SDarren Stevens * 18881000 Amigaone X1000
1335078502b5SDarren Stevens */
1336078502b5SDarren Stevens static const struct hda_pintbl nemo_pin_configs[] = {
1337078502b5SDarren Stevens { 0x0a, 0x02214020 }, /* Front panel HP socket */
1338078502b5SDarren Stevens { 0x0b, 0x02a19080 }, /* Front Mic */
1339078502b5SDarren Stevens { 0x0c, 0x0181304e }, /* Line in */
1340078502b5SDarren Stevens { 0x0d, 0x01014010 }, /* Line out */
1341078502b5SDarren Stevens { 0x0e, 0x01a19040 }, /* Rear Mic */
1342078502b5SDarren Stevens { 0x0f, 0x01011012 }, /* Rear speakers */
1343078502b5SDarren Stevens { 0x10, 0x01016011 }, /* Center speaker */
1344078502b5SDarren Stevens { 0x11, 0x01012014 }, /* Side speakers (7.1) */
1345078502b5SDarren Stevens { 0x12, 0x103301f0 }, /* Motherboard CD line in connector */
1346078502b5SDarren Stevens { 0x13, 0x411111f0 }, /* Unused */
1347078502b5SDarren Stevens { 0x14, 0x411111f0 }, /* Unused */
1348078502b5SDarren Stevens { 0x21, 0x01442170 }, /* S/PDIF line out */
1349078502b5SDarren Stevens { 0x22, 0x411111f0 }, /* Unused */
1350078502b5SDarren Stevens { 0x23, 0x411111f0 }, /* Unused */
1351078502b5SDarren Stevens {}
1352078502b5SDarren Stevens };
1353dfe495d0STakashi Iwai
stac9200_fixup_panasonic(struct hda_codec * codec,const struct hda_fixup * fix,int action)1354d39a3ae8STakashi Iwai static void stac9200_fixup_panasonic(struct hda_codec *codec,
1355d39a3ae8STakashi Iwai const struct hda_fixup *fix, int action)
1356d39a3ae8STakashi Iwai {
1357d39a3ae8STakashi Iwai struct sigmatel_spec *spec = codec->spec;
1358d39a3ae8STakashi Iwai
135936c9db7aSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1360d39a3ae8STakashi Iwai spec->gpio_mask = spec->gpio_dir = 0x09;
1361d39a3ae8STakashi Iwai spec->gpio_data = 0x00;
1362d39a3ae8STakashi Iwai /* CF-74 has no headphone detection, and the driver should *NOT*
1363d39a3ae8STakashi Iwai * do detection and HP/speaker toggle because the hardware does it.
1364d39a3ae8STakashi Iwai */
136536c9db7aSTakashi Iwai spec->gen.suppress_auto_mute = 1;
1366d39a3ae8STakashi Iwai }
1367d39a3ae8STakashi Iwai }
1368d39a3ae8STakashi Iwai
1369d39a3ae8STakashi Iwai
1370d39a3ae8STakashi Iwai static const struct hda_fixup stac9200_fixups[] = {
1371d39a3ae8STakashi Iwai [STAC_REF] = {
1372d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1373d39a3ae8STakashi Iwai .v.pins = ref9200_pin_configs,
1374d39a3ae8STakashi Iwai },
1375d39a3ae8STakashi Iwai [STAC_9200_OQO] = {
1376d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1377d39a3ae8STakashi Iwai .v.pins = oqo9200_pin_configs,
1378d39a3ae8STakashi Iwai .chained = true,
1379d39a3ae8STakashi Iwai .chain_id = STAC_9200_EAPD_INIT,
1380d39a3ae8STakashi Iwai },
1381d39a3ae8STakashi Iwai [STAC_9200_DELL_D21] = {
1382d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1383d39a3ae8STakashi Iwai .v.pins = dell9200_d21_pin_configs,
1384d39a3ae8STakashi Iwai },
1385d39a3ae8STakashi Iwai [STAC_9200_DELL_D22] = {
1386d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1387d39a3ae8STakashi Iwai .v.pins = dell9200_d22_pin_configs,
1388d39a3ae8STakashi Iwai },
1389d39a3ae8STakashi Iwai [STAC_9200_DELL_D23] = {
1390d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1391d39a3ae8STakashi Iwai .v.pins = dell9200_d23_pin_configs,
1392d39a3ae8STakashi Iwai },
1393d39a3ae8STakashi Iwai [STAC_9200_DELL_M21] = {
1394d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1395d39a3ae8STakashi Iwai .v.pins = dell9200_m21_pin_configs,
1396d39a3ae8STakashi Iwai },
1397d39a3ae8STakashi Iwai [STAC_9200_DELL_M22] = {
1398d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1399d39a3ae8STakashi Iwai .v.pins = dell9200_m22_pin_configs,
1400d39a3ae8STakashi Iwai },
1401d39a3ae8STakashi Iwai [STAC_9200_DELL_M23] = {
1402d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1403d39a3ae8STakashi Iwai .v.pins = dell9200_m23_pin_configs,
1404d39a3ae8STakashi Iwai },
1405d39a3ae8STakashi Iwai [STAC_9200_DELL_M24] = {
1406d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1407d39a3ae8STakashi Iwai .v.pins = dell9200_m24_pin_configs,
1408d39a3ae8STakashi Iwai },
1409d39a3ae8STakashi Iwai [STAC_9200_DELL_M25] = {
1410d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1411d39a3ae8STakashi Iwai .v.pins = dell9200_m25_pin_configs,
1412d39a3ae8STakashi Iwai },
1413d39a3ae8STakashi Iwai [STAC_9200_DELL_M26] = {
1414d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1415d39a3ae8STakashi Iwai .v.pins = dell9200_m26_pin_configs,
1416d39a3ae8STakashi Iwai },
1417d39a3ae8STakashi Iwai [STAC_9200_DELL_M27] = {
1418d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1419d39a3ae8STakashi Iwai .v.pins = dell9200_m27_pin_configs,
1420d39a3ae8STakashi Iwai },
1421d39a3ae8STakashi Iwai [STAC_9200_M4] = {
1422d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1423d39a3ae8STakashi Iwai .v.pins = gateway9200_m4_pin_configs,
1424d39a3ae8STakashi Iwai .chained = true,
1425d39a3ae8STakashi Iwai .chain_id = STAC_9200_EAPD_INIT,
1426d39a3ae8STakashi Iwai },
1427d39a3ae8STakashi Iwai [STAC_9200_M4_2] = {
1428d39a3ae8STakashi Iwai .type = HDA_FIXUP_PINS,
1429d39a3ae8STakashi Iwai .v.pins = gateway9200_m4_2_pin_configs,
1430d39a3ae8STakashi Iwai .chained = true,
1431d39a3ae8STakashi Iwai .chain_id = STAC_9200_EAPD_INIT,
1432d39a3ae8STakashi Iwai },
1433d39a3ae8STakashi Iwai [STAC_9200_PANASONIC] = {
1434d39a3ae8STakashi Iwai .type = HDA_FIXUP_FUNC,
1435d39a3ae8STakashi Iwai .v.func = stac9200_fixup_panasonic,
1436d39a3ae8STakashi Iwai },
1437d39a3ae8STakashi Iwai [STAC_9200_EAPD_INIT] = {
1438d39a3ae8STakashi Iwai .type = HDA_FIXUP_VERBS,
1439d39a3ae8STakashi Iwai .v.verbs = (const struct hda_verb[]) {
1440d39a3ae8STakashi Iwai {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1441d39a3ae8STakashi Iwai {}
1442d39a3ae8STakashi Iwai },
1443d39a3ae8STakashi Iwai },
1444403d1944SMatt Porter };
1445403d1944SMatt Porter
1446d39a3ae8STakashi Iwai static const struct hda_model_fixup stac9200_models[] = {
1447d39a3ae8STakashi Iwai { .id = STAC_REF, .name = "ref" },
1448d39a3ae8STakashi Iwai { .id = STAC_9200_OQO, .name = "oqo" },
1449d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1450d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1451d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1452d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1453d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1454d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1455d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1456d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1457d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1458d39a3ae8STakashi Iwai { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1459d39a3ae8STakashi Iwai { .id = STAC_9200_M4, .name = "gateway-m4" },
1460d39a3ae8STakashi Iwai { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1461d39a3ae8STakashi Iwai { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1462d39a3ae8STakashi Iwai {}
1463f5fcc13cSTakashi Iwai };
1464f5fcc13cSTakashi Iwai
1465d39a3ae8STakashi Iwai static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
1466f5fcc13cSTakashi Iwai /* SigmaTel reference board */
1467f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1468f5fcc13cSTakashi Iwai "DFI LanParty", STAC_REF),
1469577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1470577aa2c1SMatthew Ranostay "DFI LanParty", STAC_REF),
1471e7377071SMatt Porter /* Dell laptops have BIOS problem */
1472dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1473dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D21),
1474f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
1475dfe495d0STakashi Iwai "Dell Inspiron 630m", STAC_9200_DELL_M21),
1476dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1477dfe495d0STakashi Iwai "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1478dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1479dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D22),
1480dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1481dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D22),
1482f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
1483dfe495d0STakashi Iwai "Dell Latitude D620", STAC_9200_DELL_M22),
1484dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1485dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D23),
1486dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1487dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D23),
1488dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1489dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M22),
1490dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1491dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M24),
1492dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1493dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M24),
1494f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
1495dfe495d0STakashi Iwai "Dell Latitude 120L", STAC_9200_DELL_M24),
1496877b866dSCory T. Tusar SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
1497dfe495d0STakashi Iwai "Dell Latitude D820", STAC_9200_DELL_M22),
149846f02ca3SMikael Nilsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
1499dfe495d0STakashi Iwai "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
150046f02ca3SMikael Nilsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
1501dfe495d0STakashi Iwai "Dell XPS M1710", STAC_9200_DELL_M23),
1502f0f96745STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
1503dfe495d0STakashi Iwai "Dell Precision M90", STAC_9200_DELL_M23),
1504dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1505dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M22),
1506dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1507dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M22),
15088286c53eSDaniel T Chen SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
1509dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M22),
151049c605dbSTobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
1511dfe495d0STakashi Iwai "Dell Inspiron 640m", STAC_9200_DELL_M21),
1512dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1513dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D23),
1514dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1515dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D23),
1516dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1517dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D21),
1518dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1519dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D23),
1520dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1521dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_D21),
1522dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1523dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M25),
1524dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1525dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M25),
152649c605dbSTobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
1527dfe495d0STakashi Iwai "Dell Inspiron 1501", STAC_9200_DELL_M26),
1528dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1529dfe495d0STakashi Iwai "unknown Dell", STAC_9200_DELL_M26),
15301fc2e41fSAlexander Tsoy SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201,
15311fc2e41fSAlexander Tsoy "Dell Latitude D430", STAC_9200_DELL_M22),
153249c605dbSTobin Davis /* Panasonic */
1533117f257dSTakashi Iwai SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
15341194b5b7STakashi Iwai /* Gateway machines needs EAPD to be set on resume */
153558eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
153658eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
153758eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
1538bf277785STobin Davis /* OQO Mobile */
1539bf277785STobin Davis SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
1540403d1944SMatt Porter {} /* terminator */
1541403d1944SMatt Porter };
1542403d1944SMatt Porter
1543d2077d40STakashi Iwai static const struct hda_pintbl ref925x_pin_configs[] = {
1544d2077d40STakashi Iwai { 0x07, 0x40c003f0 },
1545d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1546d2077d40STakashi Iwai { 0x0a, 0x01813022 },
1547d2077d40STakashi Iwai { 0x0b, 0x02a19021 },
1548d2077d40STakashi Iwai { 0x0c, 0x90a70320 },
1549d2077d40STakashi Iwai { 0x0d, 0x02214210 },
1550d2077d40STakashi Iwai { 0x10, 0x01019020 },
1551d2077d40STakashi Iwai { 0x11, 0x9033032e },
1552d2077d40STakashi Iwai {}
15538e21c34cSTobin Davis };
15548e21c34cSTobin Davis
1555d2077d40STakashi Iwai static const struct hda_pintbl stac925xM1_pin_configs[] = {
1556d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1557d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1558d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1559d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1560d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1561d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1562d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1563d2077d40STakashi Iwai { 0x11, 0x9033032e },
1564d2077d40STakashi Iwai {}
15658e21c34cSTobin Davis };
15668e21c34cSTobin Davis
1567d2077d40STakashi Iwai static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1568d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1569d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1570d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1571d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1572d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1573d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1574d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1575d2077d40STakashi Iwai { 0x11, 0x9033032e },
1576d2077d40STakashi Iwai {}
15779cb36c2aSMauro Carvalho Chehab };
157858eec423SMauro Carvalho Chehab
1579d2077d40STakashi Iwai static const struct hda_pintbl stac925xM2_pin_configs[] = {
1580d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1581d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1582d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1583d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1584d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1585d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1586d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1587d2077d40STakashi Iwai { 0x11, 0x9033032e },
1588d2077d40STakashi Iwai {}
15892c11f955STobin Davis };
15902c11f955STobin Davis
1591d2077d40STakashi Iwai static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1592d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1593d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1594d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1595d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1596d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1597d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1598d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1599d2077d40STakashi Iwai { 0x11, 0x9033032e },
1600d2077d40STakashi Iwai {}
160158eec423SMauro Carvalho Chehab };
160258eec423SMauro Carvalho Chehab
1603d2077d40STakashi Iwai static const struct hda_pintbl stac925xM3_pin_configs[] = {
1604d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1605d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1606d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1607d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1608d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1609d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1610d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1611d2077d40STakashi Iwai { 0x11, 0x503303f3 },
1612d2077d40STakashi Iwai {}
16139cb36c2aSMauro Carvalho Chehab };
161458eec423SMauro Carvalho Chehab
1615d2077d40STakashi Iwai static const struct hda_pintbl stac925xM5_pin_configs[] = {
1616d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1617d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1618d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1619d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1620d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1621d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1622d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1623d2077d40STakashi Iwai { 0x11, 0x9033032e },
1624d2077d40STakashi Iwai {}
16259cb36c2aSMauro Carvalho Chehab };
16269cb36c2aSMauro Carvalho Chehab
1627d2077d40STakashi Iwai static const struct hda_pintbl stac925xM6_pin_configs[] = {
1628d2077d40STakashi Iwai { 0x07, 0x40c003f4 },
1629d2077d40STakashi Iwai { 0x08, 0x424503f2 },
1630d2077d40STakashi Iwai { 0x0a, 0x400000f3 },
1631d2077d40STakashi Iwai { 0x0b, 0x02a19020 },
1632d2077d40STakashi Iwai { 0x0c, 0x40a000f0 },
1633d2077d40STakashi Iwai { 0x0d, 0x90100210 },
1634d2077d40STakashi Iwai { 0x10, 0x400003f1 },
1635d2077d40STakashi Iwai { 0x11, 0x90330320 },
1636d2077d40STakashi Iwai {}
16378e21c34cSTobin Davis };
16388e21c34cSTobin Davis
1639d2077d40STakashi Iwai static const struct hda_fixup stac925x_fixups[] = {
1640d2077d40STakashi Iwai [STAC_REF] = {
1641d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1642d2077d40STakashi Iwai .v.pins = ref925x_pin_configs,
1643d2077d40STakashi Iwai },
1644d2077d40STakashi Iwai [STAC_M1] = {
1645d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1646d2077d40STakashi Iwai .v.pins = stac925xM1_pin_configs,
1647d2077d40STakashi Iwai },
1648d2077d40STakashi Iwai [STAC_M1_2] = {
1649d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1650d2077d40STakashi Iwai .v.pins = stac925xM1_2_pin_configs,
1651d2077d40STakashi Iwai },
1652d2077d40STakashi Iwai [STAC_M2] = {
1653d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1654d2077d40STakashi Iwai .v.pins = stac925xM2_pin_configs,
1655d2077d40STakashi Iwai },
1656d2077d40STakashi Iwai [STAC_M2_2] = {
1657d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1658d2077d40STakashi Iwai .v.pins = stac925xM2_2_pin_configs,
1659d2077d40STakashi Iwai },
1660d2077d40STakashi Iwai [STAC_M3] = {
1661d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1662d2077d40STakashi Iwai .v.pins = stac925xM3_pin_configs,
1663d2077d40STakashi Iwai },
1664d2077d40STakashi Iwai [STAC_M5] = {
1665d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1666d2077d40STakashi Iwai .v.pins = stac925xM5_pin_configs,
1667d2077d40STakashi Iwai },
1668d2077d40STakashi Iwai [STAC_M6] = {
1669d2077d40STakashi Iwai .type = HDA_FIXUP_PINS,
1670d2077d40STakashi Iwai .v.pins = stac925xM6_pin_configs,
1671d2077d40STakashi Iwai },
16728e21c34cSTobin Davis };
16738e21c34cSTobin Davis
1674d2077d40STakashi Iwai static const struct hda_model_fixup stac925x_models[] = {
1675d2077d40STakashi Iwai { .id = STAC_REF, .name = "ref" },
1676d2077d40STakashi Iwai { .id = STAC_M1, .name = "m1" },
1677d2077d40STakashi Iwai { .id = STAC_M1_2, .name = "m1-2" },
1678d2077d40STakashi Iwai { .id = STAC_M2, .name = "m2" },
1679d2077d40STakashi Iwai { .id = STAC_M2_2, .name = "m2-2" },
1680d2077d40STakashi Iwai { .id = STAC_M3, .name = "m3" },
1681d2077d40STakashi Iwai { .id = STAC_M5, .name = "m5" },
1682d2077d40STakashi Iwai { .id = STAC_M6, .name = "m6" },
1683d2077d40STakashi Iwai {}
16848e21c34cSTobin Davis };
16858e21c34cSTobin Davis
1686d2077d40STakashi Iwai static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1687d2077d40STakashi Iwai /* SigmaTel reference board */
1688d2077d40STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1689d2077d40STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1690d2077d40STakashi Iwai SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1691d2077d40STakashi Iwai
1692d2077d40STakashi Iwai /* Default table for unknown ID */
1693d2077d40STakashi Iwai SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1694d2077d40STakashi Iwai
1695d2077d40STakashi Iwai /* gateway machines are checked via codec ssid */
169658eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
169758eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
169858eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
169958eec423SMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
17009cb36c2aSMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
17019cb36c2aSMauro Carvalho Chehab /* Not sure about the brand name for those */
17029cb36c2aSMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
17039cb36c2aSMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
17049cb36c2aSMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
17059cb36c2aSMauro Carvalho Chehab SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
17069cb36c2aSMauro Carvalho Chehab {} /* terminator */
17078e21c34cSTobin Davis };
17088e21c34cSTobin Davis
170955e30141STakashi Iwai static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1710*f342ac00SOswald Buddenhagen // Port A-H
171155e30141STakashi Iwai { 0x0a, 0x02214030 },
171255e30141STakashi Iwai { 0x0b, 0x02a19040 },
171355e30141STakashi Iwai { 0x0c, 0x01a19020 },
171455e30141STakashi Iwai { 0x0d, 0x02214030 },
171555e30141STakashi Iwai { 0x0e, 0x0181302e },
171655e30141STakashi Iwai { 0x0f, 0x01014010 },
171755e30141STakashi Iwai { 0x10, 0x01014020 },
171855e30141STakashi Iwai { 0x11, 0x01014030 },
1719*f342ac00SOswald Buddenhagen // CD in
172055e30141STakashi Iwai { 0x12, 0x02319040 },
1721*f342ac00SOswald Buddenhagen // Digial Mic ins
172255e30141STakashi Iwai { 0x13, 0x90a000f0 },
172355e30141STakashi Iwai { 0x14, 0x90a000f0 },
1724*f342ac00SOswald Buddenhagen // Digital outs
172555e30141STakashi Iwai { 0x22, 0x01452050 },
172655e30141STakashi Iwai { 0x23, 0x01452050 },
172755e30141STakashi Iwai {}
1728a7662640SMatthew Ranostay };
1729a7662640SMatthew Ranostay
173055e30141STakashi Iwai static const struct hda_pintbl dell_m6_pin_configs[] = {
173155e30141STakashi Iwai { 0x0a, 0x0321101f },
173255e30141STakashi Iwai { 0x0b, 0x4f00000f },
173355e30141STakashi Iwai { 0x0c, 0x4f0000f0 },
173455e30141STakashi Iwai { 0x0d, 0x90170110 },
173555e30141STakashi Iwai { 0x0e, 0x03a11020 },
173655e30141STakashi Iwai { 0x0f, 0x0321101f },
173755e30141STakashi Iwai { 0x10, 0x4f0000f0 },
173855e30141STakashi Iwai { 0x11, 0x4f0000f0 },
173955e30141STakashi Iwai { 0x12, 0x4f0000f0 },
174055e30141STakashi Iwai { 0x13, 0x90a60160 },
174155e30141STakashi Iwai { 0x14, 0x4f0000f0 },
174255e30141STakashi Iwai { 0x22, 0x4f0000f0 },
174355e30141STakashi Iwai { 0x23, 0x4f0000f0 },
174455e30141STakashi Iwai {}
1745e1f0d669SMatthew Ranostay };
1746e1f0d669SMatthew Ranostay
174755e30141STakashi Iwai static const struct hda_pintbl alienware_m17x_pin_configs[] = {
174855e30141STakashi Iwai { 0x0a, 0x0321101f },
174955e30141STakashi Iwai { 0x0b, 0x0321101f },
175055e30141STakashi Iwai { 0x0c, 0x03a11020 },
175155e30141STakashi Iwai { 0x0d, 0x03014020 },
175255e30141STakashi Iwai { 0x0e, 0x90170110 },
175355e30141STakashi Iwai { 0x0f, 0x4f0000f0 },
175455e30141STakashi Iwai { 0x10, 0x4f0000f0 },
175555e30141STakashi Iwai { 0x11, 0x4f0000f0 },
175655e30141STakashi Iwai { 0x12, 0x4f0000f0 },
175755e30141STakashi Iwai { 0x13, 0x90a60160 },
175855e30141STakashi Iwai { 0x14, 0x4f0000f0 },
175955e30141STakashi Iwai { 0x22, 0x4f0000f0 },
176055e30141STakashi Iwai { 0x23, 0x904601b0 },
176155e30141STakashi Iwai {}
1762842ae638STakashi Iwai };
1763842ae638STakashi Iwai
176455e30141STakashi Iwai static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1765*f342ac00SOswald Buddenhagen // Analog outputs
176655e30141STakashi Iwai { 0x0a, 0x02214230 },
176755e30141STakashi Iwai { 0x0b, 0x02A19240 },
176855e30141STakashi Iwai { 0x0c, 0x01013214 },
176955e30141STakashi Iwai { 0x0d, 0x01014210 },
177055e30141STakashi Iwai { 0x0e, 0x01A19250 },
177155e30141STakashi Iwai { 0x0f, 0x01011212 },
177255e30141STakashi Iwai { 0x10, 0x01016211 },
1773*f342ac00SOswald Buddenhagen // Digital output
1774*f342ac00SOswald Buddenhagen { 0x22, 0x01451380 },
1775*f342ac00SOswald Buddenhagen { 0x23, 0x40f000f0 },
177655e30141STakashi Iwai {}
177752dc4386SAlexey Fisher };
177852dc4386SAlexey Fisher
17791de7ca5eSHui Wang static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = {
17801de7ca5eSHui Wang { 0x0a, 0x02214030 },
17811de7ca5eSHui Wang { 0x0b, 0x02A19010 },
17821de7ca5eSHui Wang {}
17831de7ca5eSHui Wang };
17841de7ca5eSHui Wang
17857440850cSHui Wang static const struct hda_pintbl stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs[] = {
17867440850cSHui Wang { 0x0e, 0x400000f0 },
17877440850cSHui Wang {}
17887440850cSHui Wang };
17897440850cSHui Wang
stac92hd73xx_fixup_ref(struct hda_codec * codec,const struct hda_fixup * fix,int action)179055e30141STakashi Iwai static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
179155e30141STakashi Iwai const struct hda_fixup *fix, int action)
179255e30141STakashi Iwai {
179355e30141STakashi Iwai struct sigmatel_spec *spec = codec->spec;
179455e30141STakashi Iwai
179555e30141STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
179655e30141STakashi Iwai return;
179755e30141STakashi Iwai
179855e30141STakashi Iwai snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
179955e30141STakashi Iwai spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
180055e30141STakashi Iwai }
180155e30141STakashi Iwai
stac92hd73xx_fixup_dell(struct hda_codec * codec)180255e30141STakashi Iwai static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
180355e30141STakashi Iwai {
180455e30141STakashi Iwai struct sigmatel_spec *spec = codec->spec;
180555e30141STakashi Iwai
180655e30141STakashi Iwai snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
180755e30141STakashi Iwai spec->eapd_switch = 0;
180855e30141STakashi Iwai }
180955e30141STakashi Iwai
stac92hd73xx_fixup_dell_eq(struct hda_codec * codec,const struct hda_fixup * fix,int action)181055e30141STakashi Iwai static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
181155e30141STakashi Iwai const struct hda_fixup *fix, int action)
181255e30141STakashi Iwai {
181355e30141STakashi Iwai struct sigmatel_spec *spec = codec->spec;
181455e30141STakashi Iwai
181555e30141STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
181655e30141STakashi Iwai return;
181755e30141STakashi Iwai
181855e30141STakashi Iwai stac92hd73xx_fixup_dell(codec);
181955e30141STakashi Iwai snd_hda_add_verbs(codec, dell_eq_core_init);
182055e30141STakashi Iwai spec->volknob_init = 1;
182155e30141STakashi Iwai }
182255e30141STakashi Iwai
182355e30141STakashi Iwai /* Analog Mics */
stac92hd73xx_fixup_dell_m6_amic(struct hda_codec * codec,const struct hda_fixup * fix,int action)182455e30141STakashi Iwai static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
182555e30141STakashi Iwai const struct hda_fixup *fix, int action)
182655e30141STakashi Iwai {
182755e30141STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
182855e30141STakashi Iwai return;
182955e30141STakashi Iwai
183055e30141STakashi Iwai stac92hd73xx_fixup_dell(codec);
183155e30141STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
183255e30141STakashi Iwai }
183355e30141STakashi Iwai
183455e30141STakashi Iwai /* Digital Mics */
stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec * codec,const struct hda_fixup * fix,int action)183555e30141STakashi Iwai static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
183655e30141STakashi Iwai const struct hda_fixup *fix, int action)
183755e30141STakashi Iwai {
183855e30141STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
183955e30141STakashi Iwai return;
184055e30141STakashi Iwai
184155e30141STakashi Iwai stac92hd73xx_fixup_dell(codec);
184255e30141STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
184355e30141STakashi Iwai }
184455e30141STakashi Iwai
184555e30141STakashi Iwai /* Both */
stac92hd73xx_fixup_dell_m6_both(struct hda_codec * codec,const struct hda_fixup * fix,int action)184655e30141STakashi Iwai static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
184755e30141STakashi Iwai const struct hda_fixup *fix, int action)
184855e30141STakashi Iwai {
184955e30141STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
185055e30141STakashi Iwai return;
185155e30141STakashi Iwai
185255e30141STakashi Iwai stac92hd73xx_fixup_dell(codec);
185355e30141STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
185455e30141STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
185555e30141STakashi Iwai }
185655e30141STakashi Iwai
stac92hd73xx_fixup_alienware_m17x(struct hda_codec * codec,const struct hda_fixup * fix,int action)185755e30141STakashi Iwai static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
185855e30141STakashi Iwai const struct hda_fixup *fix, int action)
185955e30141STakashi Iwai {
186055e30141STakashi Iwai struct sigmatel_spec *spec = codec->spec;
186155e30141STakashi Iwai
186255e30141STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
186355e30141STakashi Iwai return;
186455e30141STakashi Iwai
186555e30141STakashi Iwai snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
186655e30141STakashi Iwai spec->eapd_switch = 0;
186755e30141STakashi Iwai }
186855e30141STakashi Iwai
stac92hd73xx_fixup_no_jd(struct hda_codec * codec,const struct hda_fixup * fix,int action)186955e30141STakashi Iwai static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
187055e30141STakashi Iwai const struct hda_fixup *fix, int action)
187155e30141STakashi Iwai {
187236c9db7aSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE)
187336c9db7aSTakashi Iwai codec->no_jack_detect = 1;
187455e30141STakashi Iwai }
187555e30141STakashi Iwai
1876d153135eSMichael Pobega
stac92hd73xx_disable_automute(struct hda_codec * codec,const struct hda_fixup * fix,int action)1877d153135eSMichael Pobega static void stac92hd73xx_disable_automute(struct hda_codec *codec,
1878d153135eSMichael Pobega const struct hda_fixup *fix, int action)
1879d153135eSMichael Pobega {
1880d153135eSMichael Pobega struct sigmatel_spec *spec = codec->spec;
1881d153135eSMichael Pobega
1882d153135eSMichael Pobega if (action != HDA_FIXUP_ACT_PRE_PROBE)
1883d153135eSMichael Pobega return;
1884d153135eSMichael Pobega
1885d153135eSMichael Pobega spec->gen.suppress_auto_mute = 1;
1886d153135eSMichael Pobega }
1887d153135eSMichael Pobega
188855e30141STakashi Iwai static const struct hda_fixup stac92hd73xx_fixups[] = {
188955e30141STakashi Iwai [STAC_92HD73XX_REF] = {
189055e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
189155e30141STakashi Iwai .v.func = stac92hd73xx_fixup_ref,
189255e30141STakashi Iwai },
189355e30141STakashi Iwai [STAC_DELL_M6_AMIC] = {
189455e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
189555e30141STakashi Iwai .v.func = stac92hd73xx_fixup_dell_m6_amic,
189655e30141STakashi Iwai },
189755e30141STakashi Iwai [STAC_DELL_M6_DMIC] = {
189855e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
189955e30141STakashi Iwai .v.func = stac92hd73xx_fixup_dell_m6_dmic,
190055e30141STakashi Iwai },
190155e30141STakashi Iwai [STAC_DELL_M6_BOTH] = {
190255e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
190355e30141STakashi Iwai .v.func = stac92hd73xx_fixup_dell_m6_both,
190455e30141STakashi Iwai },
190555e30141STakashi Iwai [STAC_DELL_EQ] = {
190655e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
190755e30141STakashi Iwai .v.func = stac92hd73xx_fixup_dell_eq,
190855e30141STakashi Iwai },
190955e30141STakashi Iwai [STAC_ALIENWARE_M17X] = {
191055e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
191155e30141STakashi Iwai .v.func = stac92hd73xx_fixup_alienware_m17x,
191255e30141STakashi Iwai },
1913d153135eSMichael Pobega [STAC_ELO_VUPOINT_15MX] = {
1914d153135eSMichael Pobega .type = HDA_FIXUP_FUNC,
1915d153135eSMichael Pobega .v.func = stac92hd73xx_disable_automute,
1916d153135eSMichael Pobega },
191755e30141STakashi Iwai [STAC_92HD73XX_INTEL] = {
191855e30141STakashi Iwai .type = HDA_FIXUP_PINS,
191955e30141STakashi Iwai .v.pins = intel_dg45id_pin_configs,
192055e30141STakashi Iwai },
192155e30141STakashi Iwai [STAC_92HD73XX_NO_JD] = {
192255e30141STakashi Iwai .type = HDA_FIXUP_FUNC,
192355e30141STakashi Iwai .v.func = stac92hd73xx_fixup_no_jd,
19241de7ca5eSHui Wang },
19251de7ca5eSHui Wang [STAC_92HD89XX_HP_FRONT_JACK] = {
19261de7ca5eSHui Wang .type = HDA_FIXUP_PINS,
19271de7ca5eSHui Wang .v.pins = stac92hd89xx_hp_front_jack_pin_configs,
19287440850cSHui Wang },
19297440850cSHui Wang [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = {
19307440850cSHui Wang .type = HDA_FIXUP_PINS,
19317440850cSHui Wang .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs,
19326426460eSTakashi Iwai },
19336426460eSTakashi Iwai [STAC_92HD73XX_ASUS_MOBO] = {
19346426460eSTakashi Iwai .type = HDA_FIXUP_PINS,
19356426460eSTakashi Iwai .v.pins = (const struct hda_pintbl[]) {
19366426460eSTakashi Iwai /* enable 5.1 and SPDIF out */
19376426460eSTakashi Iwai { 0x0c, 0x01014411 },
19386426460eSTakashi Iwai { 0x0d, 0x01014410 },
19396426460eSTakashi Iwai { 0x0e, 0x01014412 },
19406426460eSTakashi Iwai { 0x22, 0x014b1180 },
19416426460eSTakashi Iwai { }
194255e30141STakashi Iwai }
19436426460eSTakashi Iwai },
1944e1f0d669SMatthew Ranostay };
1945e1f0d669SMatthew Ranostay
194655e30141STakashi Iwai static const struct hda_model_fixup stac92hd73xx_models[] = {
194755e30141STakashi Iwai { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
194855e30141STakashi Iwai { .id = STAC_92HD73XX_REF, .name = "ref" },
194955e30141STakashi Iwai { .id = STAC_92HD73XX_INTEL, .name = "intel" },
195055e30141STakashi Iwai { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
195155e30141STakashi Iwai { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
195255e30141STakashi Iwai { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
195355e30141STakashi Iwai { .id = STAC_DELL_EQ, .name = "dell-eq" },
195455e30141STakashi Iwai { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1955d153135eSMichael Pobega { .id = STAC_ELO_VUPOINT_15MX, .name = "elo-vupoint-15mx" },
19566426460eSTakashi Iwai { .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" },
195755e30141STakashi Iwai {}
1958e1f0d669SMatthew Ranostay };
1959e1f0d669SMatthew Ranostay
196055e30141STakashi Iwai static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
1961e1f0d669SMatthew Ranostay /* SigmaTel reference board */
1962e1f0d669SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1963e1f0d669SMatthew Ranostay "DFI LanParty", STAC_92HD73XX_REF),
1964577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1965577aa2c1SMatthew Ranostay "DFI LanParty", STAC_92HD73XX_REF),
1966c17f8fd3SOswald Buddenhagen SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5001,
1967c17f8fd3SOswald Buddenhagen "Intel DP45SG", STAC_92HD73XX_INTEL),
1968ae709440SWu Fengguang SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
1969ae709440SWu Fengguang "Intel DG45ID", STAC_92HD73XX_INTEL),
1970ae709440SWu Fengguang SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
1971ae709440SWu Fengguang "Intel DG45FC", STAC_92HD73XX_INTEL),
1972a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1973661cd8fbSTakashi Iwai "Dell Studio 1535", STAC_DELL_M6_DMIC),
1974a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1975661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_DMIC),
1976a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1977661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_BOTH),
1978a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1979661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_BOTH),
1980a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1981661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_AMIC),
1982a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1983661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_AMIC),
1984a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1985661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_DMIC),
1986661cd8fbSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1987661cd8fbSTakashi Iwai "unknown Dell", STAC_DELL_M6_DMIC),
1988b0fc5e04STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1989661cd8fbSTakashi Iwai "Dell Studio 1537", STAC_DELL_M6_DMIC),
1990fa620e97SJoerg Schirottke SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1991fa620e97SJoerg Schirottke "Dell Studio 17", STAC_DELL_M6_DMIC),
1992626f5cefSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
1993626f5cefSTakashi Iwai "Dell Studio 1555", STAC_DELL_M6_DMIC),
19948ef5837aSDaniel J Blueman SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
19958ef5837aSDaniel J Blueman "Dell Studio 1557", STAC_DELL_M6_DMIC),
1996aac78dafSDaniel T Chen SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1997ffe535edSDavid Henningsson "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
19985c1bccf6SDaniel T Chen SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1999e033ebfbSDavid Henningsson "Dell Studio 1558", STAC_DELL_M6_DMIC),
200055e30141STakashi Iwai /* codec SSID matching */
2001842ae638STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
2002842ae638STakashi Iwai "Alienware M17x", STAC_ALIENWARE_M17X),
20030defe09cSDaniel T Chen SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
20040defe09cSDaniel T Chen "Alienware M17x", STAC_ALIENWARE_M17X),
2005dbd1b547STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
2006b9ecc4eeSAlbert Pool "Alienware M17x R3", STAC_DELL_EQ),
2007d153135eSMichael Pobega SND_PCI_QUIRK(0x1059, 0x1011,
2008d153135eSMichael Pobega "ELO VuPoint 15MX", STAC_ELO_VUPOINT_15MX),
20097440850cSHui Wang SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1927,
20107440850cSHui Wang "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK),
20111de7ca5eSHui Wang SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
20121de7ca5eSHui Wang "unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
20136426460eSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10",
20146426460eSTakashi Iwai STAC_92HD73XX_ASUS_MOBO),
2015842ae638STakashi Iwai {} /* terminator */
2016842ae638STakashi Iwai };
2017842ae638STakashi Iwai
2018372f8c75STakashi Iwai static const struct hda_pintbl ref92hd83xxx_pin_configs[] = {
2019372f8c75STakashi Iwai { 0x0a, 0x02214030 },
2020372f8c75STakashi Iwai { 0x0b, 0x02211010 },
2021372f8c75STakashi Iwai { 0x0c, 0x02a19020 },
2022372f8c75STakashi Iwai { 0x0d, 0x02170130 },
2023372f8c75STakashi Iwai { 0x0e, 0x01014050 },
2024372f8c75STakashi Iwai { 0x0f, 0x01819040 },
2025372f8c75STakashi Iwai { 0x10, 0x01014020 },
2026372f8c75STakashi Iwai { 0x11, 0x90a3014e },
2027372f8c75STakashi Iwai { 0x1f, 0x01451160 },
2028372f8c75STakashi Iwai { 0x20, 0x98560170 },
2029372f8c75STakashi Iwai {}
2030d0513fc6SMatthew Ranostay };
2031d0513fc6SMatthew Ranostay
2032372f8c75STakashi Iwai static const struct hda_pintbl dell_s14_pin_configs[] = {
2033372f8c75STakashi Iwai { 0x0a, 0x0221403f },
2034372f8c75STakashi Iwai { 0x0b, 0x0221101f },
2035372f8c75STakashi Iwai { 0x0c, 0x02a19020 },
2036372f8c75STakashi Iwai { 0x0d, 0x90170110 },
2037372f8c75STakashi Iwai { 0x0e, 0x40f000f0 },
2038372f8c75STakashi Iwai { 0x0f, 0x40f000f0 },
2039372f8c75STakashi Iwai { 0x10, 0x40f000f0 },
2040372f8c75STakashi Iwai { 0x11, 0x90a60160 },
2041372f8c75STakashi Iwai { 0x1f, 0x40f000f0 },
2042372f8c75STakashi Iwai { 0x20, 0x40f000f0 },
2043372f8c75STakashi Iwai {}
20448bb0ac55SMatthew Ranostay };
20458bb0ac55SMatthew Ranostay
2046372f8c75STakashi Iwai static const struct hda_pintbl dell_vostro_3500_pin_configs[] = {
2047372f8c75STakashi Iwai { 0x0a, 0x02a11020 },
2048372f8c75STakashi Iwai { 0x0b, 0x0221101f },
2049372f8c75STakashi Iwai { 0x0c, 0x400000f0 },
2050372f8c75STakashi Iwai { 0x0d, 0x90170110 },
2051372f8c75STakashi Iwai { 0x0e, 0x400000f1 },
2052372f8c75STakashi Iwai { 0x0f, 0x400000f2 },
2053372f8c75STakashi Iwai { 0x10, 0x400000f3 },
2054372f8c75STakashi Iwai { 0x11, 0x90a60160 },
2055372f8c75STakashi Iwai { 0x1f, 0x400000f4 },
2056372f8c75STakashi Iwai { 0x20, 0x400000f5 },
2057372f8c75STakashi Iwai {}
2058f7f9bdfaSJulian Wollrath };
2059f7f9bdfaSJulian Wollrath
2060372f8c75STakashi Iwai static const struct hda_pintbl hp_dv7_4000_pin_configs[] = {
2061372f8c75STakashi Iwai { 0x0a, 0x03a12050 },
2062372f8c75STakashi Iwai { 0x0b, 0x0321201f },
2063372f8c75STakashi Iwai { 0x0c, 0x40f000f0 },
2064372f8c75STakashi Iwai { 0x0d, 0x90170110 },
2065372f8c75STakashi Iwai { 0x0e, 0x40f000f0 },
2066372f8c75STakashi Iwai { 0x0f, 0x40f000f0 },
2067372f8c75STakashi Iwai { 0x10, 0x90170110 },
2068372f8c75STakashi Iwai { 0x11, 0xd5a30140 },
2069372f8c75STakashi Iwai { 0x1f, 0x40f000f0 },
2070372f8c75STakashi Iwai { 0x20, 0x40f000f0 },
2071372f8c75STakashi Iwai {}
207248315590SSteven Eastland };
207348315590SSteven Eastland
2074372f8c75STakashi Iwai static const struct hda_pintbl hp_zephyr_pin_configs[] = {
2075372f8c75STakashi Iwai { 0x0a, 0x01813050 },
2076372f8c75STakashi Iwai { 0x0b, 0x0421201f },
2077372f8c75STakashi Iwai { 0x0c, 0x04a1205e },
2078372f8c75STakashi Iwai { 0x0d, 0x96130310 },
2079372f8c75STakashi Iwai { 0x0e, 0x96130310 },
2080372f8c75STakashi Iwai { 0x0f, 0x0101401f },
2081372f8c75STakashi Iwai { 0x10, 0x1111611f },
2082372f8c75STakashi Iwai { 0x11, 0xd5a30130 },
2083372f8c75STakashi Iwai {}
20845556e147SVitaliy Kulikov };
20855556e147SVitaliy Kulikov
2086372f8c75STakashi Iwai static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = {
2087372f8c75STakashi Iwai { 0x0a, 0x40f000f0 },
2088372f8c75STakashi Iwai { 0x0b, 0x0221101f },
2089372f8c75STakashi Iwai { 0x0c, 0x02a11020 },
2090372f8c75STakashi Iwai { 0x0d, 0x92170110 },
2091372f8c75STakashi Iwai { 0x0e, 0x40f000f0 },
2092372f8c75STakashi Iwai { 0x0f, 0x92170110 },
2093372f8c75STakashi Iwai { 0x10, 0x40f000f0 },
2094372f8c75STakashi Iwai { 0x11, 0xd5a30130 },
2095372f8c75STakashi Iwai { 0x1f, 0x40f000f0 },
2096372f8c75STakashi Iwai { 0x20, 0x40f000f0 },
2097372f8c75STakashi Iwai {}
20980c27c180SVitaliy Kulikov };
20990c27c180SVitaliy Kulikov
stac92hd83xxx_fixup_hp(struct hda_codec * codec,const struct hda_fixup * fix,int action)2100372f8c75STakashi Iwai static void stac92hd83xxx_fixup_hp(struct hda_codec *codec,
2101372f8c75STakashi Iwai const struct hda_fixup *fix, int action)
2102372f8c75STakashi Iwai {
2103372f8c75STakashi Iwai struct sigmatel_spec *spec = codec->spec;
2104372f8c75STakashi Iwai
2105372f8c75STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
2106372f8c75STakashi Iwai return;
2107372f8c75STakashi Iwai
2108372f8c75STakashi Iwai if (hp_bnb2011_with_dock(codec)) {
2109372f8c75STakashi Iwai snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
2110372f8c75STakashi Iwai snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
2111372f8c75STakashi Iwai }
2112372f8c75STakashi Iwai
2113372f8c75STakashi Iwai if (find_mute_led_cfg(codec, spec->default_polarity))
21144e76a883STakashi Iwai codec_dbg(codec, "mute LED gpio %d polarity %d\n",
2115372f8c75STakashi Iwai spec->gpio_led,
2116372f8c75STakashi Iwai spec->gpio_led_polarity);
2117e8b99a1dSTakashi Iwai
2118e8b99a1dSTakashi Iwai /* allow auto-switching of dock line-in */
2119e8b99a1dSTakashi Iwai spec->gen.line_in_auto_switch = true;
2120372f8c75STakashi Iwai }
2121372f8c75STakashi Iwai
stac92hd83xxx_fixup_hp_zephyr(struct hda_codec * codec,const struct hda_fixup * fix,int action)2122372f8c75STakashi Iwai static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec,
2123372f8c75STakashi Iwai const struct hda_fixup *fix, int action)
2124372f8c75STakashi Iwai {
2125372f8c75STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
2126372f8c75STakashi Iwai return;
2127372f8c75STakashi Iwai
2128372f8c75STakashi Iwai snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs);
2129372f8c75STakashi Iwai snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init);
2130372f8c75STakashi Iwai }
2131372f8c75STakashi Iwai
stac92hd83xxx_fixup_hp_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)2132372f8c75STakashi Iwai static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec,
2133372f8c75STakashi Iwai const struct hda_fixup *fix, int action)
2134372f8c75STakashi Iwai {
2135372f8c75STakashi Iwai struct sigmatel_spec *spec = codec->spec;
2136372f8c75STakashi Iwai
2137372f8c75STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE)
2138372f8c75STakashi Iwai spec->default_polarity = 0;
2139372f8c75STakashi Iwai }
2140372f8c75STakashi Iwai
stac92hd83xxx_fixup_hp_inv_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)2141372f8c75STakashi Iwai static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec,
2142372f8c75STakashi Iwai const struct hda_fixup *fix, int action)
2143372f8c75STakashi Iwai {
2144372f8c75STakashi Iwai struct sigmatel_spec *spec = codec->spec;
2145372f8c75STakashi Iwai
2146372f8c75STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE)
2147372f8c75STakashi Iwai spec->default_polarity = 1;
2148372f8c75STakashi Iwai }
2149372f8c75STakashi Iwai
stac92hd83xxx_fixup_hp_mic_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)2150372f8c75STakashi Iwai static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2151372f8c75STakashi Iwai const struct hda_fixup *fix, int action)
2152372f8c75STakashi Iwai {
2153372f8c75STakashi Iwai struct sigmatel_spec *spec = codec->spec;
2154372f8c75STakashi Iwai
215595f74c41STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2156372f8c75STakashi Iwai spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
2157873ce8adSTakashi Iwai /* resetting controller clears GPIO, so we need to keep on */
21587639a06cSTakashi Iwai codec->core.power_caps &= ~AC_PWRST_CLKSTOP;
215995f74c41STakashi Iwai }
2160372f8c75STakashi Iwai }
2161372f8c75STakashi Iwai
stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec * codec,const struct hda_fixup * fix,int action)216237c367ecSTakashi Iwai static void stac92hd83xxx_fixup_hp_led_gpio10(struct hda_codec *codec,
216337c367ecSTakashi Iwai const struct hda_fixup *fix, int action)
216437c367ecSTakashi Iwai {
216537c367ecSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
216637c367ecSTakashi Iwai
216737c367ecSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
216837c367ecSTakashi Iwai spec->gpio_led = 0x10; /* GPIO4 */
216937c367ecSTakashi Iwai spec->default_polarity = 0;
217037c367ecSTakashi Iwai }
217137c367ecSTakashi Iwai }
217237c367ecSTakashi Iwai
stac92hd83xxx_fixup_headset_jack(struct hda_codec * codec,const struct hda_fixup * fix,int action)2173372f8c75STakashi Iwai static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2174372f8c75STakashi Iwai const struct hda_fixup *fix, int action)
2175372f8c75STakashi Iwai {
2176372f8c75STakashi Iwai struct sigmatel_spec *spec = codec->spec;
2177372f8c75STakashi Iwai
2178372f8c75STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE)
2179372f8c75STakashi Iwai spec->headset_jack = 1;
2180372f8c75STakashi Iwai }
2181372f8c75STakashi Iwai
stac92hd83xxx_fixup_gpio10_eapd(struct hda_codec * codec,const struct hda_fixup * fix,int action)21824227de2aSTakashi Iwai static void stac92hd83xxx_fixup_gpio10_eapd(struct hda_codec *codec,
21834227de2aSTakashi Iwai const struct hda_fixup *fix,
21844227de2aSTakashi Iwai int action)
21854227de2aSTakashi Iwai {
21864227de2aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
21874227de2aSTakashi Iwai
21884227de2aSTakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
21894227de2aSTakashi Iwai return;
21904227de2aSTakashi Iwai spec->eapd_mask = spec->gpio_mask = spec->gpio_dir =
21914227de2aSTakashi Iwai spec->gpio_data = 0x10;
21924227de2aSTakashi Iwai spec->eapd_switch = 0;
21934227de2aSTakashi Iwai }
21944227de2aSTakashi Iwai
hp_envy_ts_fixup_dac_bind(struct hda_codec * codec,const struct hda_fixup * fix,int action)21956ab42ff4SHui Wang static void hp_envy_ts_fixup_dac_bind(struct hda_codec *codec,
21966ab42ff4SHui Wang const struct hda_fixup *fix,
21976ab42ff4SHui Wang int action)
21986ab42ff4SHui Wang {
21996ab42ff4SHui Wang struct sigmatel_spec *spec = codec->spec;
2200caf3c043SMichał Mirosław static const hda_nid_t preferred_pairs[] = {
22016ab42ff4SHui Wang 0xd, 0x13,
22026ab42ff4SHui Wang 0
22036ab42ff4SHui Wang };
22046ab42ff4SHui Wang
22056ab42ff4SHui Wang if (action != HDA_FIXUP_ACT_PRE_PROBE)
22066ab42ff4SHui Wang return;
22076ab42ff4SHui Wang
22086ab42ff4SHui Wang spec->gen.preferred_dacs = preferred_pairs;
22096ab42ff4SHui Wang }
22106ab42ff4SHui Wang
2211d009f3deSVitaliy Kulikov static const struct hda_verb hp_bnb13_eq_verbs[] = {
2212d009f3deSVitaliy Kulikov /* 44.1KHz base */
2213d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2214d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x68 },
2215d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x17 },
2216d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2217d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x68 },
2218d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x17 },
2219d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x00 },
2220d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2221d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x83 },
2222d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x2F },
2223d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xD1 },
2224d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x83 },
2225d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x2F },
2226d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xD1 },
2227d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x01 },
2228d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2229d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2230d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x68 },
2231d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x17 },
2232d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2233d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x68 },
2234d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x17 },
2235d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x02 },
2236d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2237d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x7C },
2238d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xC6 },
2239d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x0C },
2240d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x7C },
2241d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xC6 },
2242d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x0C },
2243d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x03 },
2244d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2245d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xC3 },
2246d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x25 },
2247d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xAF },
2248d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xC3 },
2249d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x25 },
2250d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xAF },
2251d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x04 },
2252d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2253d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2254d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x85 },
2255d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x73 },
2256d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2257d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x85 },
2258d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x73 },
2259d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x05 },
2260d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2261d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x85 },
2262d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x39 },
2263d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xC7 },
2264d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x85 },
2265d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x39 },
2266d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xC7 },
2267d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x06 },
2268d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2269d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3C },
2270d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x90 },
2271d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xB0 },
2272d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3C },
2273d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x90 },
2274d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xB0 },
2275d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x07 },
2276d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2277d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x7A },
2278d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xC6 },
2279d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x39 },
2280d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x7A },
2281d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xC6 },
2282d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x39 },
2283d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x08 },
2284d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2285d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xC4 },
2286d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xE9 },
2287d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xDC },
2288d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xC4 },
2289d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xE9 },
2290d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xDC },
2291d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x09 },
2292d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2293d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3D },
2294d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xE1 },
2295d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x0D },
2296d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3D },
2297d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xE1 },
2298d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x0D },
2299d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x0A },
2300d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2301d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x89 },
2302d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xB6 },
2303d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xEB },
2304d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x89 },
2305d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xB6 },
2306d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xEB },
2307d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x0B },
2308d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2309d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x39 },
2310d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x9D },
2311d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xFE },
2312d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x39 },
2313d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x9D },
2314d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xFE },
2315d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x0C },
2316d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2317d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x76 },
2318d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x49 },
2319d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x15 },
2320d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x76 },
2321d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x49 },
2322d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x15 },
2323d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x0D },
2324d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2325d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xC8 },
2326d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x80 },
2327d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xF5 },
2328d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xC8 },
2329d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x80 },
2330d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xF5 },
2331d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x0E },
2332d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2333d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x40 },
2334d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x00 },
2335d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x00 },
2336d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x40 },
2337d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x00 },
2338d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x00 },
2339d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x0F },
2340d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2341d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x90 },
2342d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x68 },
2343d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xF1 },
2344d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x90 },
2345d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x68 },
2346d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xF1 },
2347d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x10 },
2348d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2349d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x34 },
2350d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x47 },
2351d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x6C },
2352d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x34 },
2353d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x47 },
2354d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x6C },
2355d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x11 },
2356d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2357d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x6F },
2358d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x97 },
2359d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x0F },
2360d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x6F },
2361d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x97 },
2362d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x0F },
2363d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x12 },
2364d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2365d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xCB },
2366d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xB8 },
2367d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x94 },
2368d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xCB },
2369d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xB8 },
2370d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x94 },
2371d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x13 },
2372d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2373d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x40 },
2374d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x00 },
2375d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x00 },
2376d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x40 },
2377d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x00 },
2378d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x00 },
2379d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x14 },
2380d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2381d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x95 },
2382d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x76 },
2383d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x5B },
2384d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x95 },
2385d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x76 },
2386d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x5B },
2387d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x15 },
2388d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2389d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x31 },
2390d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xAC },
2391d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x31 },
2392d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x31 },
2393d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xAC },
2394d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x31 },
2395d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x16 },
2396d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2397d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x6A },
2398d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x89 },
2399d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xA5 },
2400d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x6A },
2401d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x89 },
2402d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xA5 },
2403d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x17 },
2404d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2405d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xCE },
2406d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x53 },
2407d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xCF },
2408d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xCE },
2409d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x53 },
2410d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xCF },
2411d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x18 },
2412d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2413d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x40 },
2414d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x00 },
2415d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x00 },
2416d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x40 },
2417d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x00 },
2418d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x00 },
2419d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x19 },
2420d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2421d009f3deSVitaliy Kulikov /* 48KHz base */
2422d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2423d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x88 },
2424d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xDC },
2425d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2426d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x88 },
2427d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xDC },
2428d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x1A },
2429d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2430d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x82 },
2431d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xEE },
2432d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x46 },
2433d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x82 },
2434d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xEE },
2435d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x46 },
2436d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x1B },
2437d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2438d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2439d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x88 },
2440d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xDC },
2441d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2442d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x88 },
2443d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xDC },
2444d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x1C },
2445d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2446d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x7D },
2447d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x09 },
2448d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x28 },
2449d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x7D },
2450d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x09 },
2451d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x28 },
2452d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x1D },
2453d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2454d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xC2 },
2455d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xE5 },
2456d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xB4 },
2457d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xC2 },
2458d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xE5 },
2459d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xB4 },
2460d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x1E },
2461d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2462d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2463d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xA3 },
2464d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x1F },
2465d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2466d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xA3 },
2467d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x1F },
2468d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x1F },
2469d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2470d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x84 },
2471d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xCA },
2472d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xF1 },
2473d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x84 },
2474d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xCA },
2475d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xF1 },
2476d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x20 },
2477d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2478d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3C },
2479d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xD5 },
2480d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x9C },
2481d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3C },
2482d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xD5 },
2483d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x9C },
2484d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x21 },
2485d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2486d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x7B },
2487d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x35 },
2488d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x0F },
2489d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x7B },
2490d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x35 },
2491d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x0F },
2492d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x22 },
2493d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2494d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xC4 },
2495d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x87 },
2496d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x45 },
2497d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xC4 },
2498d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x87 },
2499d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x45 },
2500d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x23 },
2501d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2502d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3E },
2503d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x0A },
2504d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x78 },
2505d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3E },
2506d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x0A },
2507d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x78 },
2508d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x24 },
2509d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2510d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x88 },
2511d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xE2 },
2512d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x05 },
2513d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x88 },
2514d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xE2 },
2515d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x05 },
2516d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x25 },
2517d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2518d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x3A },
2519d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x1A },
2520d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xA3 },
2521d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x3A },
2522d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x1A },
2523d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xA3 },
2524d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x26 },
2525d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2526d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x77 },
2527d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x1D },
2528d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xFB },
2529d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x77 },
2530d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x1D },
2531d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xFB },
2532d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x27 },
2533d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2534d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xC7 },
2535d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xDA },
2536d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xE5 },
2537d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xC7 },
2538d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xDA },
2539d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xE5 },
2540d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x28 },
2541d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2542d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x40 },
2543d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x00 },
2544d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x00 },
2545d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x40 },
2546d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x00 },
2547d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x00 },
2548d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x29 },
2549d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2550d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x8E },
2551d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xD7 },
2552d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x22 },
2553d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x8E },
2554d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xD7 },
2555d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x22 },
2556d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x2A },
2557d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2558d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x35 },
2559d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x26 },
2560d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xC6 },
2561d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x35 },
2562d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x26 },
2563d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xC6 },
2564d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x2B },
2565d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2566d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x71 },
2567d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x28 },
2568d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xDE },
2569d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x71 },
2570d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x28 },
2571d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xDE },
2572d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x2C },
2573d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2574d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xCA },
2575d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xD9 },
2576d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x3A },
2577d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xCA },
2578d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xD9 },
2579d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x3A },
2580d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x2D },
2581d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2582d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x40 },
2583d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x00 },
2584d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x00 },
2585d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x40 },
2586d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x00 },
2587d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x00 },
2588d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x2E },
2589d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2590d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x93 },
2591d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x5E },
2592d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xD8 },
2593d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x93 },
2594d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x5E },
2595d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xD8 },
2596d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x2F },
2597d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2598d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x32 },
2599d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xB7 },
2600d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0xB1 },
2601d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x32 },
2602d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xB7 },
2603d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0xB1 },
2604d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x30 },
2605d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2606d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x6C },
2607d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0xA1 },
2608d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x28 },
2609d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x6C },
2610d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0xA1 },
2611d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x28 },
2612d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x31 },
2613d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2614d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0xCD },
2615d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x48 },
2616d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x4F },
2617d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0xCD },
2618d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x48 },
2619d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x4F },
2620d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x32 },
2621d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2622d009f3deSVitaliy Kulikov { 0x22, 0x7A6, 0x40 },
2623d009f3deSVitaliy Kulikov { 0x22, 0x7A7, 0x00 },
2624d009f3deSVitaliy Kulikov { 0x22, 0x7A8, 0x00 },
2625d009f3deSVitaliy Kulikov { 0x22, 0x7A9, 0x40 },
2626d009f3deSVitaliy Kulikov { 0x22, 0x7AA, 0x00 },
2627d009f3deSVitaliy Kulikov { 0x22, 0x7AB, 0x00 },
2628d009f3deSVitaliy Kulikov { 0x22, 0x7AC, 0x33 },
2629d009f3deSVitaliy Kulikov { 0x22, 0x7AD, 0x80 },
2630d009f3deSVitaliy Kulikov /* common */
2631d009f3deSVitaliy Kulikov { 0x22, 0x782, 0xC1 },
2632d009f3deSVitaliy Kulikov { 0x22, 0x771, 0x2C },
2633d009f3deSVitaliy Kulikov { 0x22, 0x772, 0x2C },
2634d009f3deSVitaliy Kulikov { 0x22, 0x788, 0x04 },
2635d009f3deSVitaliy Kulikov { 0x01, 0x7B0, 0x08 },
2636d009f3deSVitaliy Kulikov {}
2637d009f3deSVitaliy Kulikov };
2638d009f3deSVitaliy Kulikov
2639372f8c75STakashi Iwai static const struct hda_fixup stac92hd83xxx_fixups[] = {
2640372f8c75STakashi Iwai [STAC_92HD83XXX_REF] = {
2641372f8c75STakashi Iwai .type = HDA_FIXUP_PINS,
2642372f8c75STakashi Iwai .v.pins = ref92hd83xxx_pin_configs,
2643372f8c75STakashi Iwai },
2644372f8c75STakashi Iwai [STAC_92HD83XXX_PWR_REF] = {
2645372f8c75STakashi Iwai .type = HDA_FIXUP_PINS,
2646372f8c75STakashi Iwai .v.pins = ref92hd83xxx_pin_configs,
2647372f8c75STakashi Iwai },
2648372f8c75STakashi Iwai [STAC_DELL_S14] = {
2649372f8c75STakashi Iwai .type = HDA_FIXUP_PINS,
2650372f8c75STakashi Iwai .v.pins = dell_s14_pin_configs,
2651372f8c75STakashi Iwai },
2652372f8c75STakashi Iwai [STAC_DELL_VOSTRO_3500] = {
2653372f8c75STakashi Iwai .type = HDA_FIXUP_PINS,
2654372f8c75STakashi Iwai .v.pins = dell_vostro_3500_pin_configs,
2655372f8c75STakashi Iwai },
2656372f8c75STakashi Iwai [STAC_92HD83XXX_HP_cNB11_INTQUAD] = {
2657372f8c75STakashi Iwai .type = HDA_FIXUP_PINS,
2658372f8c75STakashi Iwai .v.pins = hp_cNB11_intquad_pin_configs,
2659372f8c75STakashi Iwai .chained = true,
2660372f8c75STakashi Iwai .chain_id = STAC_92HD83XXX_HP,
2661372f8c75STakashi Iwai },
2662372f8c75STakashi Iwai [STAC_92HD83XXX_HP] = {
2663372f8c75STakashi Iwai .type = HDA_FIXUP_FUNC,
2664372f8c75STakashi Iwai .v.func = stac92hd83xxx_fixup_hp,
2665372f8c75STakashi Iwai },
2666372f8c75STakashi Iwai [STAC_HP_DV7_4000] = {
2667372f8c75STakashi Iwai .type = HDA_FIXUP_PINS,
2668372f8c75STakashi Iwai .v.pins = hp_dv7_4000_pin_configs,
2669372f8c75STakashi Iwai .chained = true,
2670372f8c75STakashi Iwai .chain_id = STAC_92HD83XXX_HP,
2671372f8c75STakashi Iwai },
2672372f8c75STakashi Iwai [STAC_HP_ZEPHYR] = {
2673372f8c75STakashi Iwai .type = HDA_FIXUP_FUNC,
2674372f8c75STakashi Iwai .v.func = stac92hd83xxx_fixup_hp_zephyr,
2675372f8c75STakashi Iwai .chained = true,
2676372f8c75STakashi Iwai .chain_id = STAC_92HD83XXX_HP,
2677372f8c75STakashi Iwai },
2678372f8c75STakashi Iwai [STAC_92HD83XXX_HP_LED] = {
2679372f8c75STakashi Iwai .type = HDA_FIXUP_FUNC,
2680372f8c75STakashi Iwai .v.func = stac92hd83xxx_fixup_hp_led,
2681372f8c75STakashi Iwai .chained = true,
2682372f8c75STakashi Iwai .chain_id = STAC_92HD83XXX_HP,
2683372f8c75STakashi Iwai },
2684372f8c75STakashi Iwai [STAC_92HD83XXX_HP_INV_LED] = {
2685372f8c75STakashi Iwai .type = HDA_FIXUP_FUNC,
2686372f8c75STakashi Iwai .v.func = stac92hd83xxx_fixup_hp_inv_led,
2687372f8c75STakashi Iwai .chained = true,
2688372f8c75STakashi Iwai .chain_id = STAC_92HD83XXX_HP,
2689372f8c75STakashi Iwai },
2690372f8c75STakashi Iwai [STAC_92HD83XXX_HP_MIC_LED] = {
2691372f8c75STakashi Iwai .type = HDA_FIXUP_FUNC,
2692372f8c75STakashi Iwai .v.func = stac92hd83xxx_fixup_hp_mic_led,
2693372f8c75STakashi Iwai .chained = true,
2694372f8c75STakashi Iwai .chain_id = STAC_92HD83XXX_HP,
2695372f8c75STakashi Iwai },
269637c367ecSTakashi Iwai [STAC_HP_LED_GPIO10] = {
269737c367ecSTakashi Iwai .type = HDA_FIXUP_FUNC,
269837c367ecSTakashi Iwai .v.func = stac92hd83xxx_fixup_hp_led_gpio10,
269937c367ecSTakashi Iwai .chained = true,
270037c367ecSTakashi Iwai .chain_id = STAC_92HD83XXX_HP,
270137c367ecSTakashi Iwai },
2702372f8c75STakashi Iwai [STAC_92HD83XXX_HEADSET_JACK] = {
2703372f8c75STakashi Iwai .type = HDA_FIXUP_FUNC,
2704372f8c75STakashi Iwai .v.func = stac92hd83xxx_fixup_headset_jack,
2705372f8c75STakashi Iwai },
270649920427STakashi Iwai [STAC_HP_ENVY_BASS] = {
270749920427STakashi Iwai .type = HDA_FIXUP_PINS,
270849920427STakashi Iwai .v.pins = (const struct hda_pintbl[]) {
270949920427STakashi Iwai { 0x0f, 0x90170111 },
271049920427STakashi Iwai {}
271149920427STakashi Iwai },
271249920427STakashi Iwai },
2713d009f3deSVitaliy Kulikov [STAC_HP_BNB13_EQ] = {
2714d009f3deSVitaliy Kulikov .type = HDA_FIXUP_VERBS,
2715d009f3deSVitaliy Kulikov .v.verbs = hp_bnb13_eq_verbs,
2716d009f3deSVitaliy Kulikov .chained = true,
2717d009f3deSVitaliy Kulikov .chain_id = STAC_92HD83XXX_HP_MIC_LED,
2718d009f3deSVitaliy Kulikov },
27198695a003STakashi Iwai [STAC_HP_ENVY_TS_BASS] = {
27208695a003STakashi Iwai .type = HDA_FIXUP_PINS,
27218695a003STakashi Iwai .v.pins = (const struct hda_pintbl[]) {
27228695a003STakashi Iwai { 0x10, 0x92170111 },
27238695a003STakashi Iwai {}
27248695a003STakashi Iwai },
27258695a003STakashi Iwai },
27266ab42ff4SHui Wang [STAC_HP_ENVY_TS_DAC_BIND] = {
27276ab42ff4SHui Wang .type = HDA_FIXUP_FUNC,
27286ab42ff4SHui Wang .v.func = hp_envy_ts_fixup_dac_bind,
27296ab42ff4SHui Wang .chained = true,
27306ab42ff4SHui Wang .chain_id = STAC_HP_ENVY_TS_BASS,
27316ab42ff4SHui Wang },
27324227de2aSTakashi Iwai [STAC_92HD83XXX_GPIO10_EAPD] = {
27334227de2aSTakashi Iwai .type = HDA_FIXUP_FUNC,
27344227de2aSTakashi Iwai .v.func = stac92hd83xxx_fixup_gpio10_eapd,
27354227de2aSTakashi Iwai },
2736d0513fc6SMatthew Ranostay };
2737d0513fc6SMatthew Ranostay
2738372f8c75STakashi Iwai static const struct hda_model_fixup stac92hd83xxx_models[] = {
2739372f8c75STakashi Iwai { .id = STAC_92HD83XXX_REF, .name = "ref" },
2740372f8c75STakashi Iwai { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" },
2741372f8c75STakashi Iwai { .id = STAC_DELL_S14, .name = "dell-s14" },
2742372f8c75STakashi Iwai { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" },
2743372f8c75STakashi Iwai { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" },
2744372f8c75STakashi Iwai { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" },
2745372f8c75STakashi Iwai { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" },
2746372f8c75STakashi Iwai { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" },
2747372f8c75STakashi Iwai { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" },
2748372f8c75STakashi Iwai { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" },
2749372f8c75STakashi Iwai { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
275049920427STakashi Iwai { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
2751d009f3deSVitaliy Kulikov { .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" },
27528695a003STakashi Iwai { .id = STAC_HP_ENVY_TS_BASS, .name = "hp-envy-ts-bass" },
2753372f8c75STakashi Iwai {}
2754d0513fc6SMatthew Ranostay };
2755d0513fc6SMatthew Ranostay
2756372f8c75STakashi Iwai static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2757d0513fc6SMatthew Ranostay /* SigmaTel reference board */
2758d0513fc6SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2759f9d088b2STakashi Iwai "DFI LanParty", STAC_92HD83XXX_REF),
2760577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2761577aa2c1SMatthew Ranostay "DFI LanParty", STAC_92HD83XXX_REF),
27628bb0ac55SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
27638bb0ac55SMatthew Ranostay "unknown Dell", STAC_DELL_S14),
27648d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
27658d032a8fSDavid Henningsson "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
27668d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
27678d032a8fSDavid Henningsson "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
27688d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
27698d032a8fSDavid Henningsson "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
27708d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
27718d032a8fSDavid Henningsson "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
27728d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
27738d032a8fSDavid Henningsson "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
27748d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
27758d032a8fSDavid Henningsson "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
27768d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
27778d032a8fSDavid Henningsson "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
27788d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
27798d032a8fSDavid Henningsson "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
27808d032a8fSDavid Henningsson SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
27818d032a8fSDavid Henningsson "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
2782f7f9bdfaSJulian Wollrath SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2783f7f9bdfaSJulian Wollrath "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
27840c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
27850c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
27860c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
27870c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
27880c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
27890c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
27900c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
27918ae5865eSTakashi Iwai "HP Pavilion dv7", STAC_HP_DV7_4000),
27920c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
27930c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
27940c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
27950c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
279649920427STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888,
279749920427STakashi Iwai "HP Envy Spectre", STAC_HP_ENVY_BASS),
279837c367ecSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1899,
279937c367ecSTakashi Iwai "HP Folio 13", STAC_HP_LED_GPIO10),
280062cbde18STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2801d009f3deSVitaliy Kulikov "HP Folio", STAC_HP_BNB13_EQ),
2802d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18F8,
2803d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2804d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1909,
2805d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2806d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A,
2807d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
28088695a003STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190e,
28098695a003STakashi Iwai "HP ENVY TS", STAC_HP_ENVY_TS_BASS),
28106ab42ff4SHui Wang SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1967,
28116ab42ff4SHui Wang "HP ENVY TS", STAC_HP_ENVY_TS_DAC_BIND),
2812d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940,
2813d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2814d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941,
2815d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2816d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1942,
2817d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2818d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1943,
2819d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2820d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1944,
2821d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2822d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1945,
2823d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2824d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1946,
2825d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2826d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1948,
2827d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2828d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1949,
2829d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2830d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194A,
2831d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2832d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194B,
2833d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2834d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194C,
2835d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2836d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194E,
2837d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2838d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x194F,
2839d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2840d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1950,
2841d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2842d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1951,
2843d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2844d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195A,
2845d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2846d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195B,
2847d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2848d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x195C,
2849d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2850d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1991,
2851d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2852d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2103,
2853d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2854d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2104,
2855d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2856d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2105,
2857d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2858d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2106,
2859d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2860d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2107,
2861d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2862d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2108,
2863d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2864d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2109,
2865d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2866d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210A,
2867d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2868d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x210B,
2869d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2870d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211C,
2871d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2872d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211D,
2873d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2874d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211E,
2875d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2876d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x211F,
2877d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2878d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2120,
2879d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2880d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2121,
2881d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2882d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2122,
2883d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2884d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2123,
2885d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2886d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213E,
2887d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2888d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x213F,
2889d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2890d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2140,
2891d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2892d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B2,
2893d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2894d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B3,
2895d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2896d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B5,
2897d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2898d009f3deSVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x21B6,
2899d009f3deSVitaliy Kulikov "HP bNB13", STAC_HP_BNB13_EQ),
2900f9afed1fSTakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900,
2901f9afed1fSTakashi Iwai "HP", STAC_92HD83XXX_HP_MIC_LED),
29024059a42cSTakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
29034059a42cSTakashi Iwai "HP", STAC_92HD83XXX_HP_MIC_LED),
29044059a42cSTakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100,
29054059a42cSTakashi Iwai "HP", STAC_92HD83XXX_HP_MIC_LED),
29060c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
29070c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29080c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
29090c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29100c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
29110c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29120c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
29130c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29140c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
29150c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29160c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
29170c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29180c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
29190c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29200c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
29210c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29220c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
29230c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29240c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
29250c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29260c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
29270c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29280c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
29290c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29300c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
29310c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29320c27c180SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
29330c27c180SVitaliy Kulikov "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
29345556e147SVitaliy Kulikov SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
29355556e147SVitaliy Kulikov "HP", STAC_HP_ZEPHYR),
2936a3e19973STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2937a3e19973STakashi Iwai "HP Mini", STAC_92HD83XXX_HP_LED),
29385afc13afSGustavo Maciel Dias Vieira SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
29395afc13afSGustavo Maciel Dias Vieira "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
29408c698fe2STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a,
29418c698fe2STakashi Iwai "HP Mini", STAC_92HD83XXX_HP_LED),
2942372f8c75STakashi Iwai SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP),
2943b9d9c9efSTakashi Iwai /* match both for 0xfa91 and 0xfa93 */
2944b9d9c9efSTakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_TOSHIBA, 0xfffd, 0xfa91,
29454227de2aSTakashi Iwai "Toshiba Satellite S50D", STAC_92HD83XXX_GPIO10_EAPD),
2946574f3c4fSHerton Ronaldo Krzesinski {} /* terminator */
2947d0513fc6SMatthew Ranostay };
2948d0513fc6SMatthew Ranostay
294936c9db7aSTakashi Iwai /* HP dv7 bass switch - GPIO5 */
295036c9db7aSTakashi Iwai #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)295136c9db7aSTakashi Iwai static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
295236c9db7aSTakashi Iwai struct snd_ctl_elem_value *ucontrol)
295336c9db7aSTakashi Iwai {
295436c9db7aSTakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
295536c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
295636c9db7aSTakashi Iwai ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
295736c9db7aSTakashi Iwai return 0;
295836c9db7aSTakashi Iwai }
295936c9db7aSTakashi Iwai
stac_hp_bass_gpio_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)296036c9db7aSTakashi Iwai static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
296136c9db7aSTakashi Iwai struct snd_ctl_elem_value *ucontrol)
296236c9db7aSTakashi Iwai {
296336c9db7aSTakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
296436c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
296536c9db7aSTakashi Iwai unsigned int gpio_data;
296636c9db7aSTakashi Iwai
296736c9db7aSTakashi Iwai gpio_data = (spec->gpio_data & ~0x20) |
296836c9db7aSTakashi Iwai (ucontrol->value.integer.value[0] ? 0x20 : 0);
296936c9db7aSTakashi Iwai if (gpio_data == spec->gpio_data)
297036c9db7aSTakashi Iwai return 0;
297136c9db7aSTakashi Iwai spec->gpio_data = gpio_data;
297236c9db7aSTakashi Iwai stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
297336c9db7aSTakashi Iwai return 1;
297436c9db7aSTakashi Iwai }
297536c9db7aSTakashi Iwai
297636c9db7aSTakashi Iwai static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
297736c9db7aSTakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
297836c9db7aSTakashi Iwai .info = stac_hp_bass_gpio_info,
297936c9db7aSTakashi Iwai .get = stac_hp_bass_gpio_get,
298036c9db7aSTakashi Iwai .put = stac_hp_bass_gpio_put,
298136c9db7aSTakashi Iwai };
298236c9db7aSTakashi Iwai
stac_add_hp_bass_switch(struct hda_codec * codec)298336c9db7aSTakashi Iwai static int stac_add_hp_bass_switch(struct hda_codec *codec)
298436c9db7aSTakashi Iwai {
298536c9db7aSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
298636c9db7aSTakashi Iwai
298736c9db7aSTakashi Iwai if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch",
298836c9db7aSTakashi Iwai &stac_hp_bass_sw_ctrl))
298936c9db7aSTakashi Iwai return -ENOMEM;
299036c9db7aSTakashi Iwai
299136c9db7aSTakashi Iwai spec->gpio_mask |= 0x20;
299236c9db7aSTakashi Iwai spec->gpio_dir |= 0x20;
299336c9db7aSTakashi Iwai spec->gpio_data |= 0x20;
299436c9db7aSTakashi Iwai return 0;
299536c9db7aSTakashi Iwai }
299636c9db7aSTakashi Iwai
29970f6fcb73STakashi Iwai static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
29980f6fcb73STakashi Iwai { 0x0a, 0x02214030 },
29990f6fcb73STakashi Iwai { 0x0b, 0x02a19040 },
30000f6fcb73STakashi Iwai { 0x0c, 0x01a19020 },
30010f6fcb73STakashi Iwai { 0x0d, 0x01014010 },
30020f6fcb73STakashi Iwai { 0x0e, 0x0181302e },
30030f6fcb73STakashi Iwai { 0x0f, 0x01014010 },
30040f6fcb73STakashi Iwai { 0x14, 0x01019020 },
30050f6fcb73STakashi Iwai { 0x18, 0x90a000f0 },
30060f6fcb73STakashi Iwai { 0x19, 0x90a000f0 },
30070f6fcb73STakashi Iwai { 0x1e, 0x01452050 },
30080f6fcb73STakashi Iwai { 0x1f, 0x01452050 },
30090f6fcb73STakashi Iwai {}
3010e035b841SMatthew Ranostay };
3011e035b841SMatthew Ranostay
30120f6fcb73STakashi Iwai static const struct hda_pintbl dell_m4_1_pin_configs[] = {
30130f6fcb73STakashi Iwai { 0x0a, 0x0421101f },
30140f6fcb73STakashi Iwai { 0x0b, 0x04a11221 },
30150f6fcb73STakashi Iwai { 0x0c, 0x40f000f0 },
30160f6fcb73STakashi Iwai { 0x0d, 0x90170110 },
30170f6fcb73STakashi Iwai { 0x0e, 0x23a1902e },
30180f6fcb73STakashi Iwai { 0x0f, 0x23014250 },
30190f6fcb73STakashi Iwai { 0x14, 0x40f000f0 },
30200f6fcb73STakashi Iwai { 0x18, 0x90a000f0 },
30210f6fcb73STakashi Iwai { 0x19, 0x40f000f0 },
30220f6fcb73STakashi Iwai { 0x1e, 0x4f0000f0 },
30230f6fcb73STakashi Iwai { 0x1f, 0x4f0000f0 },
30240f6fcb73STakashi Iwai {}
3025a7662640SMatthew Ranostay };
3026a7662640SMatthew Ranostay
30270f6fcb73STakashi Iwai static const struct hda_pintbl dell_m4_2_pin_configs[] = {
30280f6fcb73STakashi Iwai { 0x0a, 0x0421101f },
30290f6fcb73STakashi Iwai { 0x0b, 0x04a11221 },
30300f6fcb73STakashi Iwai { 0x0c, 0x90a70330 },
30310f6fcb73STakashi Iwai { 0x0d, 0x90170110 },
30320f6fcb73STakashi Iwai { 0x0e, 0x23a1902e },
30330f6fcb73STakashi Iwai { 0x0f, 0x23014250 },
30340f6fcb73STakashi Iwai { 0x14, 0x40f000f0 },
30350f6fcb73STakashi Iwai { 0x18, 0x40f000f0 },
30360f6fcb73STakashi Iwai { 0x19, 0x40f000f0 },
30370f6fcb73STakashi Iwai { 0x1e, 0x044413b0 },
30380f6fcb73STakashi Iwai { 0x1f, 0x044413b0 },
30390f6fcb73STakashi Iwai {}
3040a7662640SMatthew Ranostay };
3041a7662640SMatthew Ranostay
30420f6fcb73STakashi Iwai static const struct hda_pintbl dell_m4_3_pin_configs[] = {
30430f6fcb73STakashi Iwai { 0x0a, 0x0421101f },
30440f6fcb73STakashi Iwai { 0x0b, 0x04a11221 },
30450f6fcb73STakashi Iwai { 0x0c, 0x90a70330 },
30460f6fcb73STakashi Iwai { 0x0d, 0x90170110 },
30470f6fcb73STakashi Iwai { 0x0e, 0x40f000f0 },
30480f6fcb73STakashi Iwai { 0x0f, 0x40f000f0 },
30490f6fcb73STakashi Iwai { 0x14, 0x40f000f0 },
30500f6fcb73STakashi Iwai { 0x18, 0x90a000f0 },
30510f6fcb73STakashi Iwai { 0x19, 0x40f000f0 },
30520f6fcb73STakashi Iwai { 0x1e, 0x044413b0 },
30530f6fcb73STakashi Iwai { 0x1f, 0x044413b0 },
30540f6fcb73STakashi Iwai {}
30553a7abfd2SMatthew Ranostay };
30563a7abfd2SMatthew Ranostay
stac92hd71bxx_fixup_ref(struct hda_codec * codec,const struct hda_fixup * fix,int action)30570f6fcb73STakashi Iwai static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
30580f6fcb73STakashi Iwai const struct hda_fixup *fix, int action)
30590f6fcb73STakashi Iwai {
30600f6fcb73STakashi Iwai struct sigmatel_spec *spec = codec->spec;
30610f6fcb73STakashi Iwai
30620f6fcb73STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
30630f6fcb73STakashi Iwai return;
30640f6fcb73STakashi Iwai
30650f6fcb73STakashi Iwai snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
30660f6fcb73STakashi Iwai spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
30670f6fcb73STakashi Iwai }
30680f6fcb73STakashi Iwai
stac92hd71bxx_fixup_hp_m4(struct hda_codec * codec,const struct hda_fixup * fix,int action)30690f6fcb73STakashi Iwai static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
30700f6fcb73STakashi Iwai const struct hda_fixup *fix, int action)
30710f6fcb73STakashi Iwai {
30720f6fcb73STakashi Iwai struct sigmatel_spec *spec = codec->spec;
30731a4f69d5STakashi Iwai struct hda_jack_callback *jack;
30740f6fcb73STakashi Iwai
30750f6fcb73STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
30760f6fcb73STakashi Iwai return;
30770f6fcb73STakashi Iwai
30780f6fcb73STakashi Iwai /* Enable VREF power saving on GPIO1 detect */
30797639a06cSTakashi Iwai snd_hda_codec_write_cache(codec, codec->core.afg, 0,
30800f6fcb73STakashi Iwai AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
30817639a06cSTakashi Iwai jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
308236c9db7aSTakashi Iwai stac_vref_event);
3083bda17b82STakashi Iwai if (!IS_ERR(jack))
308436c9db7aSTakashi Iwai jack->private_data = 0x02;
308536c9db7aSTakashi Iwai
30860f6fcb73STakashi Iwai spec->gpio_mask |= 0x02;
30870f6fcb73STakashi Iwai
30880f6fcb73STakashi Iwai /* enable internal microphone */
30890f6fcb73STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
30900f6fcb73STakashi Iwai }
30910f6fcb73STakashi Iwai
stac92hd71bxx_fixup_hp_dv4(struct hda_codec * codec,const struct hda_fixup * fix,int action)30920f6fcb73STakashi Iwai static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
30930f6fcb73STakashi Iwai const struct hda_fixup *fix, int action)
30940f6fcb73STakashi Iwai {
30950f6fcb73STakashi Iwai struct sigmatel_spec *spec = codec->spec;
30960f6fcb73STakashi Iwai
30970f6fcb73STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
30980f6fcb73STakashi Iwai return;
30990f6fcb73STakashi Iwai spec->gpio_led = 0x01;
31000f6fcb73STakashi Iwai }
31010f6fcb73STakashi Iwai
stac92hd71bxx_fixup_hp_dv5(struct hda_codec * codec,const struct hda_fixup * fix,int action)31020f6fcb73STakashi Iwai static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
31030f6fcb73STakashi Iwai const struct hda_fixup *fix, int action)
31040f6fcb73STakashi Iwai {
31050f6fcb73STakashi Iwai unsigned int cap;
31060f6fcb73STakashi Iwai
31070f6fcb73STakashi Iwai switch (action) {
31080f6fcb73STakashi Iwai case HDA_FIXUP_ACT_PRE_PROBE:
31090f6fcb73STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
3110f6655d52STakashi Iwai break;
3111f6655d52STakashi Iwai
3112f6655d52STakashi Iwai case HDA_FIXUP_ACT_PROBE:
31130f6fcb73STakashi Iwai /* enable bass on HP dv7 */
31140f6fcb73STakashi Iwai cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
31150f6fcb73STakashi Iwai cap &= AC_GPIO_IO_COUNT;
31160f6fcb73STakashi Iwai if (cap >= 6)
31170f6fcb73STakashi Iwai stac_add_hp_bass_switch(codec);
31180f6fcb73STakashi Iwai break;
31190f6fcb73STakashi Iwai }
31200f6fcb73STakashi Iwai }
31210f6fcb73STakashi Iwai
stac92hd71bxx_fixup_hp_hdx(struct hda_codec * codec,const struct hda_fixup * fix,int action)31220f6fcb73STakashi Iwai static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
31230f6fcb73STakashi Iwai const struct hda_fixup *fix, int action)
31240f6fcb73STakashi Iwai {
31250f6fcb73STakashi Iwai struct sigmatel_spec *spec = codec->spec;
31260f6fcb73STakashi Iwai
31270f6fcb73STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
31280f6fcb73STakashi Iwai return;
31290f6fcb73STakashi Iwai spec->gpio_led = 0x08;
31300f6fcb73STakashi Iwai }
31310f6fcb73STakashi Iwai
is_hp_output(struct hda_codec * codec,hda_nid_t pin)3132196543d5STakashi Iwai static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin)
3133196543d5STakashi Iwai {
3134196543d5STakashi Iwai unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3135196543d5STakashi Iwai
3136196543d5STakashi Iwai /* count line-out, too, as BIOS sets often so */
3137196543d5STakashi Iwai return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE &&
3138196543d5STakashi Iwai (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
3139196543d5STakashi Iwai get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT);
3140196543d5STakashi Iwai }
3141196543d5STakashi Iwai
fixup_hp_headphone(struct hda_codec * codec,hda_nid_t pin)3142196543d5STakashi Iwai static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin)
3143196543d5STakashi Iwai {
3144196543d5STakashi Iwai unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);
3145196543d5STakashi Iwai
3146196543d5STakashi Iwai /* It was changed in the BIOS to just satisfy MS DTM.
31479ab0cb30STakashi Iwai * Lets turn it back into follower HP
3148196543d5STakashi Iwai */
3149196543d5STakashi Iwai pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) |
3150196543d5STakashi Iwai (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT);
3151196543d5STakashi Iwai pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) |
3152196543d5STakashi Iwai 0x1f;
3153196543d5STakashi Iwai snd_hda_codec_set_pincfg(codec, pin, pin_cfg);
3154196543d5STakashi Iwai }
31550f6fcb73STakashi Iwai
stac92hd71bxx_fixup_hp(struct hda_codec * codec,const struct hda_fixup * fix,int action)31560f6fcb73STakashi Iwai static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
31570f6fcb73STakashi Iwai const struct hda_fixup *fix, int action)
31580f6fcb73STakashi Iwai {
31590f6fcb73STakashi Iwai struct sigmatel_spec *spec = codec->spec;
31600f6fcb73STakashi Iwai
31610f6fcb73STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
31620f6fcb73STakashi Iwai return;
31630f6fcb73STakashi Iwai
3164196543d5STakashi Iwai /* when both output A and F are assigned, these are supposedly
3165196543d5STakashi Iwai * dock and built-in headphones; fix both pin configs
31660f6fcb73STakashi Iwai */
3167196543d5STakashi Iwai if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) {
3168196543d5STakashi Iwai fixup_hp_headphone(codec, 0x0a);
3169196543d5STakashi Iwai fixup_hp_headphone(codec, 0x0f);
31700f6fcb73STakashi Iwai }
31710f6fcb73STakashi Iwai
317236c9db7aSTakashi Iwai if (find_mute_led_cfg(codec, 1))
31734e76a883STakashi Iwai codec_dbg(codec, "mute LED gpio %d polarity %d\n",
31740f6fcb73STakashi Iwai spec->gpio_led,
31750f6fcb73STakashi Iwai spec->gpio_led_polarity);
31760f6fcb73STakashi Iwai
31770f6fcb73STakashi Iwai }
31780f6fcb73STakashi Iwai
31790f6fcb73STakashi Iwai static const struct hda_fixup stac92hd71bxx_fixups[] = {
31800f6fcb73STakashi Iwai [STAC_92HD71BXX_REF] = {
31810f6fcb73STakashi Iwai .type = HDA_FIXUP_FUNC,
31820f6fcb73STakashi Iwai .v.func = stac92hd71bxx_fixup_ref,
31830f6fcb73STakashi Iwai },
31840f6fcb73STakashi Iwai [STAC_DELL_M4_1] = {
31850f6fcb73STakashi Iwai .type = HDA_FIXUP_PINS,
31860f6fcb73STakashi Iwai .v.pins = dell_m4_1_pin_configs,
31870f6fcb73STakashi Iwai },
31880f6fcb73STakashi Iwai [STAC_DELL_M4_2] = {
31890f6fcb73STakashi Iwai .type = HDA_FIXUP_PINS,
31900f6fcb73STakashi Iwai .v.pins = dell_m4_2_pin_configs,
31910f6fcb73STakashi Iwai },
31920f6fcb73STakashi Iwai [STAC_DELL_M4_3] = {
31930f6fcb73STakashi Iwai .type = HDA_FIXUP_PINS,
31940f6fcb73STakashi Iwai .v.pins = dell_m4_3_pin_configs,
31950f6fcb73STakashi Iwai },
31960f6fcb73STakashi Iwai [STAC_HP_M4] = {
31970f6fcb73STakashi Iwai .type = HDA_FIXUP_FUNC,
31980f6fcb73STakashi Iwai .v.func = stac92hd71bxx_fixup_hp_m4,
31990f6fcb73STakashi Iwai .chained = true,
32000f6fcb73STakashi Iwai .chain_id = STAC_92HD71BXX_HP,
32010f6fcb73STakashi Iwai },
32020f6fcb73STakashi Iwai [STAC_HP_DV4] = {
32030f6fcb73STakashi Iwai .type = HDA_FIXUP_FUNC,
32040f6fcb73STakashi Iwai .v.func = stac92hd71bxx_fixup_hp_dv4,
32050f6fcb73STakashi Iwai .chained = true,
32060f6fcb73STakashi Iwai .chain_id = STAC_HP_DV5,
32070f6fcb73STakashi Iwai },
32080f6fcb73STakashi Iwai [STAC_HP_DV5] = {
32090f6fcb73STakashi Iwai .type = HDA_FIXUP_FUNC,
32100f6fcb73STakashi Iwai .v.func = stac92hd71bxx_fixup_hp_dv5,
32110f6fcb73STakashi Iwai .chained = true,
32120f6fcb73STakashi Iwai .chain_id = STAC_92HD71BXX_HP,
32130f6fcb73STakashi Iwai },
32140f6fcb73STakashi Iwai [STAC_HP_HDX] = {
32150f6fcb73STakashi Iwai .type = HDA_FIXUP_FUNC,
32160f6fcb73STakashi Iwai .v.func = stac92hd71bxx_fixup_hp_hdx,
32170f6fcb73STakashi Iwai .chained = true,
32180f6fcb73STakashi Iwai .chain_id = STAC_92HD71BXX_HP,
32190f6fcb73STakashi Iwai },
32200f6fcb73STakashi Iwai [STAC_92HD71BXX_HP] = {
32210f6fcb73STakashi Iwai .type = HDA_FIXUP_FUNC,
32220f6fcb73STakashi Iwai .v.func = stac92hd71bxx_fixup_hp,
32230f6fcb73STakashi Iwai },
3224e035b841SMatthew Ranostay };
3225e035b841SMatthew Ranostay
32260f6fcb73STakashi Iwai static const struct hda_model_fixup stac92hd71bxx_models[] = {
32270f6fcb73STakashi Iwai { .id = STAC_92HD71BXX_REF, .name = "ref" },
32280f6fcb73STakashi Iwai { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
32290f6fcb73STakashi Iwai { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
32300f6fcb73STakashi Iwai { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
32310f6fcb73STakashi Iwai { .id = STAC_HP_M4, .name = "hp-m4" },
32320f6fcb73STakashi Iwai { .id = STAC_HP_DV4, .name = "hp-dv4" },
32330f6fcb73STakashi Iwai { .id = STAC_HP_DV5, .name = "hp-dv5" },
32340f6fcb73STakashi Iwai { .id = STAC_HP_HDX, .name = "hp-hdx" },
323536c9db7aSTakashi Iwai { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" },
32360f6fcb73STakashi Iwai {}
3237e035b841SMatthew Ranostay };
3238e035b841SMatthew Ranostay
32390f6fcb73STakashi Iwai static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
3240e035b841SMatthew Ranostay /* SigmaTel reference board */
3241e035b841SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3242e035b841SMatthew Ranostay "DFI LanParty", STAC_92HD71BXX_REF),
3243577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3244577aa2c1SMatthew Ranostay "DFI LanParty", STAC_92HD71BXX_REF),
32455bdaaadaSVitaliy Kulikov SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
32465bdaaadaSVitaliy Kulikov "HP", STAC_HP_DV5),
324758d8395bSTakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
324858d8395bSTakashi Iwai "HP", STAC_HP_DV5),
32492ae466f8STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
32502a6ce6e5STakashi Iwai "HP dv4-7", STAC_HP_DV4),
32512ae466f8STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
32522ae466f8STakashi Iwai "HP dv4-7", STAC_HP_DV5),
32536fce61aeSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
32546fce61aeSTakashi Iwai "HP HDX", STAC_HP_HDX), /* HDX18 */
32559a9e2359SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
32562ae466f8STakashi Iwai "HP mini 1000", STAC_HP_M4),
3257ae6241fbSChristoph Plattner SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
3258ae6241fbSChristoph Plattner "HP HDX", STAC_HP_HDX), /* HDX16 */
32596e34c033STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
32606e34c033STakashi Iwai "HP dv6", STAC_HP_DV5),
3261e3d2530aSKunal Gangakhedkar SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
3262e3d2530aSKunal Gangakhedkar "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
32639b2167d5SLuke Yelavich SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
32649b2167d5SLuke Yelavich "HP DV6", STAC_HP_DV5),
32651972d025STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
32661972d025STakashi Iwai "HP", STAC_HP_DV5),
32670f6fcb73STakashi Iwai SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
3268a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
3269a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3270a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
3271a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3272a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
3273a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3274a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
3275a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3276a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
3277a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3278a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
3279a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3280a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
3281a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_1),
3282a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
3283a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_2),
3284a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
3285a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_2),
3286a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
3287a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_2),
3288a7662640SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
3289a7662640SMatthew Ranostay "unknown Dell", STAC_DELL_M4_2),
32903a7abfd2SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
32913a7abfd2SMatthew Ranostay "unknown Dell", STAC_DELL_M4_3),
3292e035b841SMatthew Ranostay {} /* terminator */
3293e035b841SMatthew Ranostay };
3294e035b841SMatthew Ranostay
32950a427846STakashi Iwai static const struct hda_pintbl ref922x_pin_configs[] = {
32960a427846STakashi Iwai { 0x0a, 0x01014010 },
32970a427846STakashi Iwai { 0x0b, 0x01016011 },
32980a427846STakashi Iwai { 0x0c, 0x01012012 },
32990a427846STakashi Iwai { 0x0d, 0x0221401f },
33000a427846STakashi Iwai { 0x0e, 0x01813122 },
33010a427846STakashi Iwai { 0x0f, 0x01011014 },
33020a427846STakashi Iwai { 0x10, 0x01441030 },
33030a427846STakashi Iwai { 0x11, 0x01c41030 },
33040a427846STakashi Iwai { 0x15, 0x40000100 },
33050a427846STakashi Iwai { 0x1b, 0x40000100 },
33060a427846STakashi Iwai {}
33072f2f4251SMatt };
33082f2f4251SMatt
3309dfe495d0STakashi Iwai /*
3310dfe495d0STakashi Iwai STAC 922X pin configs for
3311dfe495d0STakashi Iwai 102801A7
3312dfe495d0STakashi Iwai 102801AB
3313dfe495d0STakashi Iwai 102801A9
3314dfe495d0STakashi Iwai 102801D1
3315dfe495d0STakashi Iwai 102801D2
3316dfe495d0STakashi Iwai */
33170a427846STakashi Iwai static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
33180a427846STakashi Iwai { 0x0a, 0x02214030 },
33190a427846STakashi Iwai { 0x0b, 0x01a19021 },
33200a427846STakashi Iwai { 0x0c, 0x01111012 },
33210a427846STakashi Iwai { 0x0d, 0x01114010 },
33220a427846STakashi Iwai { 0x0e, 0x02a19020 },
33230a427846STakashi Iwai { 0x0f, 0x01117011 },
33240a427846STakashi Iwai { 0x10, 0x400001f0 },
33250a427846STakashi Iwai { 0x11, 0x400001f1 },
33260a427846STakashi Iwai { 0x15, 0x01813122 },
33270a427846STakashi Iwai { 0x1b, 0x400001f2 },
33280a427846STakashi Iwai {}
3329dfe495d0STakashi Iwai };
3330dfe495d0STakashi Iwai
3331dfe495d0STakashi Iwai /*
3332dfe495d0STakashi Iwai STAC 922X pin configs for
3333dfe495d0STakashi Iwai 102801AC
3334dfe495d0STakashi Iwai 102801D0
3335dfe495d0STakashi Iwai */
33360a427846STakashi Iwai static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
33370a427846STakashi Iwai { 0x0a, 0x02214030 },
33380a427846STakashi Iwai { 0x0b, 0x01a19021 },
33390a427846STakashi Iwai { 0x0c, 0x01111012 },
33400a427846STakashi Iwai { 0x0d, 0x01114010 },
33410a427846STakashi Iwai { 0x0e, 0x02a19020 },
33420a427846STakashi Iwai { 0x0f, 0x01117011 },
33430a427846STakashi Iwai { 0x10, 0x01451140 },
33440a427846STakashi Iwai { 0x11, 0x400001f0 },
33450a427846STakashi Iwai { 0x15, 0x01813122 },
33460a427846STakashi Iwai { 0x1b, 0x400001f1 },
33470a427846STakashi Iwai {}
3348dfe495d0STakashi Iwai };
3349dfe495d0STakashi Iwai
3350dfe495d0STakashi Iwai /*
3351dfe495d0STakashi Iwai STAC 922X pin configs for
3352dfe495d0STakashi Iwai 102801BF
3353dfe495d0STakashi Iwai */
33540a427846STakashi Iwai static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
33550a427846STakashi Iwai { 0x0a, 0x0321101f },
33560a427846STakashi Iwai { 0x0b, 0x01112024 },
33570a427846STakashi Iwai { 0x0c, 0x01111222 },
33580a427846STakashi Iwai { 0x0d, 0x91174220 },
33590a427846STakashi Iwai { 0x0e, 0x03a11050 },
33600a427846STakashi Iwai { 0x0f, 0x01116221 },
33610a427846STakashi Iwai { 0x10, 0x90a70330 },
33620a427846STakashi Iwai { 0x11, 0x01452340 },
33630a427846STakashi Iwai { 0x15, 0x40C003f1 },
33640a427846STakashi Iwai { 0x1b, 0x405003f0 },
33650a427846STakashi Iwai {}
3366dfe495d0STakashi Iwai };
3367dfe495d0STakashi Iwai
3368dfe495d0STakashi Iwai /*
3369dfe495d0STakashi Iwai STAC 9221 A1 pin configs for
3370dfe495d0STakashi Iwai 102801D7 (Dell XPS M1210)
3371dfe495d0STakashi Iwai */
33720a427846STakashi Iwai static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
33730a427846STakashi Iwai { 0x0a, 0x02211211 },
33740a427846STakashi Iwai { 0x0b, 0x408103ff },
33750a427846STakashi Iwai { 0x0c, 0x02a1123e },
33760a427846STakashi Iwai { 0x0d, 0x90100310 },
33770a427846STakashi Iwai { 0x0e, 0x408003f1 },
33780a427846STakashi Iwai { 0x0f, 0x0221121f },
33790a427846STakashi Iwai { 0x10, 0x03451340 },
33800a427846STakashi Iwai { 0x11, 0x40c003f2 },
33810a427846STakashi Iwai { 0x15, 0x508003f3 },
33820a427846STakashi Iwai { 0x1b, 0x405003f4 },
33830a427846STakashi Iwai {}
3384dfe495d0STakashi Iwai };
3385dfe495d0STakashi Iwai
33860a427846STakashi Iwai static const struct hda_pintbl d945gtp3_pin_configs[] = {
33870a427846STakashi Iwai { 0x0a, 0x0221401f },
33880a427846STakashi Iwai { 0x0b, 0x01a19022 },
33890a427846STakashi Iwai { 0x0c, 0x01813021 },
33900a427846STakashi Iwai { 0x0d, 0x01014010 },
33910a427846STakashi Iwai { 0x0e, 0x40000100 },
33920a427846STakashi Iwai { 0x0f, 0x40000100 },
33930a427846STakashi Iwai { 0x10, 0x40000100 },
33940a427846STakashi Iwai { 0x11, 0x40000100 },
33950a427846STakashi Iwai { 0x15, 0x02a19120 },
33960a427846STakashi Iwai { 0x1b, 0x40000100 },
33970a427846STakashi Iwai {}
3398403d1944SMatt Porter };
3399403d1944SMatt Porter
34000a427846STakashi Iwai static const struct hda_pintbl d945gtp5_pin_configs[] = {
34010a427846STakashi Iwai { 0x0a, 0x0221401f },
34020a427846STakashi Iwai { 0x0b, 0x01011012 },
34030a427846STakashi Iwai { 0x0c, 0x01813024 },
34040a427846STakashi Iwai { 0x0d, 0x01014010 },
34050a427846STakashi Iwai { 0x0e, 0x01a19021 },
34060a427846STakashi Iwai { 0x0f, 0x01016011 },
34070a427846STakashi Iwai { 0x10, 0x01452130 },
34080a427846STakashi Iwai { 0x11, 0x40000100 },
34090a427846STakashi Iwai { 0x15, 0x02a19320 },
34100a427846STakashi Iwai { 0x1b, 0x40000100 },
34110a427846STakashi Iwai {}
3412403d1944SMatt Porter };
3413403d1944SMatt Porter
34140a427846STakashi Iwai static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
34150a427846STakashi Iwai { 0x0a, 0x0121e21f },
34160a427846STakashi Iwai { 0x0b, 0x400000ff },
34170a427846STakashi Iwai { 0x0c, 0x9017e110 },
34180a427846STakashi Iwai { 0x0d, 0x400000fd },
34190a427846STakashi Iwai { 0x0e, 0x400000fe },
34200a427846STakashi Iwai { 0x0f, 0x0181e020 },
34210a427846STakashi Iwai { 0x10, 0x1145e030 },
34220a427846STakashi Iwai { 0x11, 0x11c5e240 },
34230a427846STakashi Iwai { 0x15, 0x400000fc },
34240a427846STakashi Iwai { 0x1b, 0x400000fb },
34250a427846STakashi Iwai {}
34263fc24d85STakashi Iwai };
34273fc24d85STakashi Iwai
34280a427846STakashi Iwai static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
34290a427846STakashi Iwai { 0x0a, 0x0121e21f },
34300a427846STakashi Iwai { 0x0b, 0x90a7012e },
34310a427846STakashi Iwai { 0x0c, 0x9017e110 },
34320a427846STakashi Iwai { 0x0d, 0x400000fd },
34330a427846STakashi Iwai { 0x0e, 0x400000fe },
34340a427846STakashi Iwai { 0x0f, 0x0181e020 },
34350a427846STakashi Iwai { 0x10, 0x1145e230 },
34360a427846STakashi Iwai { 0x11, 0x500000fa },
34370a427846STakashi Iwai { 0x15, 0x400000fc },
34380a427846STakashi Iwai { 0x1b, 0x400000fb },
34390a427846STakashi Iwai {}
3440f16928fbSSylvain FORET };
3441f16928fbSSylvain FORET
34420a427846STakashi Iwai static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
34430a427846STakashi Iwai { 0x0a, 0x0121e21f },
34440a427846STakashi Iwai { 0x0b, 0x90a7012e },
34450a427846STakashi Iwai { 0x0c, 0x9017e110 },
34460a427846STakashi Iwai { 0x0d, 0x400000fd },
34470a427846STakashi Iwai { 0x0e, 0x400000fe },
34480a427846STakashi Iwai { 0x0f, 0x0181e020 },
34490a427846STakashi Iwai { 0x10, 0x1145e230 },
34500a427846STakashi Iwai { 0x11, 0x11c5e240 },
34510a427846STakashi Iwai { 0x15, 0x400000fc },
34520a427846STakashi Iwai { 0x1b, 0x400000fb },
34530a427846STakashi Iwai {}
34545d5d3bc3SIvan N. Zlatev };
34555d5d3bc3SIvan N. Zlatev
34560a427846STakashi Iwai static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
34570a427846STakashi Iwai { 0x0a, 0x0321e21f },
34580a427846STakashi Iwai { 0x0b, 0x03a1e02e },
34590a427846STakashi Iwai { 0x0c, 0x9017e110 },
34600a427846STakashi Iwai { 0x0d, 0x9017e11f },
34610a427846STakashi Iwai { 0x0e, 0x400000fe },
34620a427846STakashi Iwai { 0x0f, 0x0381e020 },
34630a427846STakashi Iwai { 0x10, 0x1345e230 },
34640a427846STakashi Iwai { 0x11, 0x13c5e240 },
34650a427846STakashi Iwai { 0x15, 0x400000fc },
34660a427846STakashi Iwai { 0x1b, 0x400000fb },
34670a427846STakashi Iwai {}
34685d5d3bc3SIvan N. Zlatev };
34695d5d3bc3SIvan N. Zlatev
34700a427846STakashi Iwai static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
34710a427846STakashi Iwai { 0x0a, 0x0321e21f },
34720a427846STakashi Iwai { 0x0b, 0x03a1e02e },
34730a427846STakashi Iwai { 0x0c, 0x9017e110 },
34740a427846STakashi Iwai { 0x0d, 0x9017e11f },
34750a427846STakashi Iwai { 0x0e, 0x400000fe },
34760a427846STakashi Iwai { 0x0f, 0x0381e020 },
34770a427846STakashi Iwai { 0x10, 0x1345e230 },
34780a427846STakashi Iwai { 0x11, 0x13c5e240 },
34790a427846STakashi Iwai { 0x15, 0x400000fc },
34800a427846STakashi Iwai { 0x1b, 0x400000fb },
34810a427846STakashi Iwai {}
34820dae0f83STakashi Iwai };
34830dae0f83STakashi Iwai
34840a427846STakashi Iwai static const struct hda_pintbl ecs202_pin_configs[] = {
34850a427846STakashi Iwai { 0x0a, 0x0221401f },
34860a427846STakashi Iwai { 0x0b, 0x02a19020 },
34870a427846STakashi Iwai { 0x0c, 0x01a19020 },
34880a427846STakashi Iwai { 0x0d, 0x01114010 },
34890a427846STakashi Iwai { 0x0e, 0x408000f0 },
34900a427846STakashi Iwai { 0x0f, 0x01813022 },
34910a427846STakashi Iwai { 0x10, 0x074510a0 },
34920a427846STakashi Iwai { 0x11, 0x40c400f1 },
34930a427846STakashi Iwai { 0x15, 0x9037012e },
34940a427846STakashi Iwai { 0x1b, 0x40e000f2 },
34950a427846STakashi Iwai {}
34968c650087SMauro Carvalho Chehab };
349776c08828STakashi Iwai
34980a427846STakashi Iwai /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
34990a427846STakashi Iwai static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
3500697aebabSTakashi Iwai SND_PCI_QUIRK(0x0000, 0x0100, "Mac Mini", STAC_INTEL_MAC_V3),
35010a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
35020a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
35030a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
35040a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
35050a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
35060a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
35070a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
35080a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
35090a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
35100a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
35110a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
35120a427846STakashi Iwai SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
35130a427846STakashi Iwai {}
35140a427846STakashi Iwai };
35150a427846STakashi Iwai
35160a427846STakashi Iwai static const struct hda_fixup stac922x_fixups[];
35170a427846STakashi Iwai
35180a427846STakashi Iwai /* 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)35190a427846STakashi Iwai static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
35200a427846STakashi Iwai const struct hda_fixup *fix,
35210a427846STakashi Iwai int action)
35220a427846STakashi Iwai {
35230a427846STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
35240a427846STakashi Iwai return;
3525f5662e1cSDavid Henningsson
3526f5662e1cSDavid Henningsson codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
35270a427846STakashi Iwai snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
35280a427846STakashi Iwai stac922x_fixups);
3529f5662e1cSDavid Henningsson if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
35300a427846STakashi Iwai snd_hda_apply_fixup(codec, action);
35310a427846STakashi Iwai }
35320a427846STakashi Iwai
stac922x_fixup_intel_mac_gpio(struct hda_codec * codec,const struct hda_fixup * fix,int action)35330a427846STakashi Iwai static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
35340a427846STakashi Iwai const struct hda_fixup *fix,
35350a427846STakashi Iwai int action)
35360a427846STakashi Iwai {
35370a427846STakashi Iwai struct sigmatel_spec *spec = codec->spec;
35380a427846STakashi Iwai
35390a427846STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
35400a427846STakashi Iwai spec->gpio_mask = spec->gpio_dir = 0x03;
35410a427846STakashi Iwai spec->gpio_data = 0x03;
35420a427846STakashi Iwai }
35430a427846STakashi Iwai }
35440a427846STakashi Iwai
35450a427846STakashi Iwai static const struct hda_fixup stac922x_fixups[] = {
35460a427846STakashi Iwai [STAC_D945_REF] = {
35470a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35480a427846STakashi Iwai .v.pins = ref922x_pin_configs,
35490a427846STakashi Iwai },
35500a427846STakashi Iwai [STAC_D945GTP3] = {
35510a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35520a427846STakashi Iwai .v.pins = d945gtp3_pin_configs,
35530a427846STakashi Iwai },
35540a427846STakashi Iwai [STAC_D945GTP5] = {
35550a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35560a427846STakashi Iwai .v.pins = d945gtp5_pin_configs,
35570a427846STakashi Iwai },
35580a427846STakashi Iwai [STAC_INTEL_MAC_AUTO] = {
35590a427846STakashi Iwai .type = HDA_FIXUP_FUNC,
35600a427846STakashi Iwai .v.func = stac922x_fixup_intel_mac_auto,
35610a427846STakashi Iwai },
35620a427846STakashi Iwai [STAC_INTEL_MAC_V1] = {
35630a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35640a427846STakashi Iwai .v.pins = intel_mac_v1_pin_configs,
35650a427846STakashi Iwai .chained = true,
35660a427846STakashi Iwai .chain_id = STAC_922X_INTEL_MAC_GPIO,
35670a427846STakashi Iwai },
35680a427846STakashi Iwai [STAC_INTEL_MAC_V2] = {
35690a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35700a427846STakashi Iwai .v.pins = intel_mac_v2_pin_configs,
35710a427846STakashi Iwai .chained = true,
35720a427846STakashi Iwai .chain_id = STAC_922X_INTEL_MAC_GPIO,
35730a427846STakashi Iwai },
35740a427846STakashi Iwai [STAC_INTEL_MAC_V3] = {
35750a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35760a427846STakashi Iwai .v.pins = intel_mac_v3_pin_configs,
35770a427846STakashi Iwai .chained = true,
35780a427846STakashi Iwai .chain_id = STAC_922X_INTEL_MAC_GPIO,
35790a427846STakashi Iwai },
35800a427846STakashi Iwai [STAC_INTEL_MAC_V4] = {
35810a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35820a427846STakashi Iwai .v.pins = intel_mac_v4_pin_configs,
35830a427846STakashi Iwai .chained = true,
35840a427846STakashi Iwai .chain_id = STAC_922X_INTEL_MAC_GPIO,
35850a427846STakashi Iwai },
35860a427846STakashi Iwai [STAC_INTEL_MAC_V5] = {
35870a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35880a427846STakashi Iwai .v.pins = intel_mac_v5_pin_configs,
35890a427846STakashi Iwai .chained = true,
35900a427846STakashi Iwai .chain_id = STAC_922X_INTEL_MAC_GPIO,
35910a427846STakashi Iwai },
35920a427846STakashi Iwai [STAC_922X_INTEL_MAC_GPIO] = {
35930a427846STakashi Iwai .type = HDA_FIXUP_FUNC,
35940a427846STakashi Iwai .v.func = stac922x_fixup_intel_mac_gpio,
35950a427846STakashi Iwai },
35960a427846STakashi Iwai [STAC_ECS_202] = {
35970a427846STakashi Iwai .type = HDA_FIXUP_PINS,
35980a427846STakashi Iwai .v.pins = ecs202_pin_configs,
35990a427846STakashi Iwai },
36000a427846STakashi Iwai [STAC_922X_DELL_D81] = {
36010a427846STakashi Iwai .type = HDA_FIXUP_PINS,
36020a427846STakashi Iwai .v.pins = dell_922x_d81_pin_configs,
36030a427846STakashi Iwai },
36040a427846STakashi Iwai [STAC_922X_DELL_D82] = {
36050a427846STakashi Iwai .type = HDA_FIXUP_PINS,
36060a427846STakashi Iwai .v.pins = dell_922x_d82_pin_configs,
36070a427846STakashi Iwai },
36080a427846STakashi Iwai [STAC_922X_DELL_M81] = {
36090a427846STakashi Iwai .type = HDA_FIXUP_PINS,
36100a427846STakashi Iwai .v.pins = dell_922x_m81_pin_configs,
36110a427846STakashi Iwai },
36120a427846STakashi Iwai [STAC_922X_DELL_M82] = {
36130a427846STakashi Iwai .type = HDA_FIXUP_PINS,
36140a427846STakashi Iwai .v.pins = dell_922x_m82_pin_configs,
36150a427846STakashi Iwai },
36160a427846STakashi Iwai };
36170a427846STakashi Iwai
36180a427846STakashi Iwai static const struct hda_model_fixup stac922x_models[] = {
36190a427846STakashi Iwai { .id = STAC_D945_REF, .name = "ref" },
36200a427846STakashi Iwai { .id = STAC_D945GTP5, .name = "5stack" },
36210a427846STakashi Iwai { .id = STAC_D945GTP3, .name = "3stack" },
36220a427846STakashi Iwai { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
36230a427846STakashi Iwai { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
36240a427846STakashi Iwai { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
36250a427846STakashi Iwai { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
36260a427846STakashi Iwai { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
36270a427846STakashi Iwai { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
36280a427846STakashi Iwai { .id = STAC_ECS_202, .name = "ecs202" },
36290a427846STakashi Iwai { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
36300a427846STakashi Iwai { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
36310a427846STakashi Iwai { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
36320a427846STakashi Iwai { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
3633dfe495d0STakashi Iwai /* for backward compatibility */
36340a427846STakashi Iwai { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
36350a427846STakashi Iwai { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
36360a427846STakashi Iwai { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
36370a427846STakashi Iwai { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
36380a427846STakashi Iwai { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
36390a427846STakashi Iwai { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
36400a427846STakashi Iwai {}
3641403d1944SMatt Porter };
3642403d1944SMatt Porter
36430a427846STakashi Iwai static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
3644f5fcc13cSTakashi Iwai /* SigmaTel reference board */
3645f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3646f5fcc13cSTakashi Iwai "DFI LanParty", STAC_D945_REF),
3647577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3648577aa2c1SMatthew Ranostay "DFI LanParty", STAC_D945_REF),
3649948a4db2STobin Davis /* Intel 945G based systems */
3650f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
3651f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3652f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
3653f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3654f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
3655f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3656f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
3657f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3658f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
3659f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3660f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
3661f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3662f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
3663f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3664f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
3665f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3666f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
3667f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3668f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
3669f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3670f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
3671f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3672f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
3673f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3674f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
3675f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3676f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
3677f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3678f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
3679f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP3),
3680f5fcc13cSTakashi Iwai /* Intel D945G 5-stack systems */
3681f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
3682f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP5),
3683f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
3684f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP5),
3685f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
3686f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP5),
3687f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
3688f5fcc13cSTakashi Iwai "Intel D945G", STAC_D945GTP5),
3689948a4db2STobin Davis /* Intel 945P based systems */
3690f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
3691f5fcc13cSTakashi Iwai "Intel D945P", STAC_D945GTP3),
3692f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
3693f5fcc13cSTakashi Iwai "Intel D945P", STAC_D945GTP3),
3694f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
3695f5fcc13cSTakashi Iwai "Intel D945P", STAC_D945GTP3),
3696f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
3697f5fcc13cSTakashi Iwai "Intel D945P", STAC_D945GTP3),
3698f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
3699f5fcc13cSTakashi Iwai "Intel D945P", STAC_D945GTP3),
3700f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
3701f5fcc13cSTakashi Iwai "Intel D945P", STAC_D945GTP5),
37028056d47eSTakashi Iwai /* other intel */
37038056d47eSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
37048056d47eSTakashi Iwai "Intel D945", STAC_D945_REF),
3705948a4db2STobin Davis /* other systems */
37060a427846STakashi Iwai
3707536319afSNicolas Boichat /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
37080a427846STakashi Iwai SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
37090a427846STakashi Iwai
3710dfe495d0STakashi Iwai /* Dell systems */
3711dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
3712dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D81),
3713dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
3714dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D81),
3715dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
3716dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D81),
3717dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
3718dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D82),
3719dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
3720dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_M81),
3721dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
3722dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D82),
3723dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
3724dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D81),
3725dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
3726dfe495d0STakashi Iwai "unknown Dell", STAC_922X_DELL_D81),
3727dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
3728dfe495d0STakashi Iwai "Dell XPS M1210", STAC_922X_DELL_M82),
37298c650087SMauro Carvalho Chehab /* ECS/PC Chips boards */
3730dea0a509STakashi Iwai SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
37318663ae55SHerton Ronaldo Krzesinski "ECS/PC chips", STAC_ECS_202),
3732403d1944SMatt Porter {} /* terminator */
3733403d1944SMatt Porter };
3734403d1944SMatt Porter
373529ac8363STakashi Iwai static const struct hda_pintbl ref927x_pin_configs[] = {
373629ac8363STakashi Iwai { 0x0a, 0x02214020 },
373729ac8363STakashi Iwai { 0x0b, 0x02a19080 },
373829ac8363STakashi Iwai { 0x0c, 0x0181304e },
373929ac8363STakashi Iwai { 0x0d, 0x01014010 },
374029ac8363STakashi Iwai { 0x0e, 0x01a19040 },
374129ac8363STakashi Iwai { 0x0f, 0x01011012 },
374229ac8363STakashi Iwai { 0x10, 0x01016011 },
374329ac8363STakashi Iwai { 0x11, 0x0101201f },
374429ac8363STakashi Iwai { 0x12, 0x183301f0 },
374529ac8363STakashi Iwai { 0x13, 0x18a001f0 },
374629ac8363STakashi Iwai { 0x14, 0x18a001f0 },
374729ac8363STakashi Iwai { 0x21, 0x01442070 },
374829ac8363STakashi Iwai { 0x22, 0x01c42190 },
374929ac8363STakashi Iwai { 0x23, 0x40000100 },
375029ac8363STakashi Iwai {}
37513cc08dc6SMatt Porter };
37523cc08dc6SMatt Porter
375329ac8363STakashi Iwai static const struct hda_pintbl d965_3st_pin_configs[] = {
375429ac8363STakashi Iwai { 0x0a, 0x0221401f },
375529ac8363STakashi Iwai { 0x0b, 0x02a19120 },
375629ac8363STakashi Iwai { 0x0c, 0x40000100 },
375729ac8363STakashi Iwai { 0x0d, 0x01014011 },
375829ac8363STakashi Iwai { 0x0e, 0x01a19021 },
375929ac8363STakashi Iwai { 0x0f, 0x01813024 },
376029ac8363STakashi Iwai { 0x10, 0x40000100 },
376129ac8363STakashi Iwai { 0x11, 0x40000100 },
376229ac8363STakashi Iwai { 0x12, 0x40000100 },
376329ac8363STakashi Iwai { 0x13, 0x40000100 },
376429ac8363STakashi Iwai { 0x14, 0x40000100 },
376529ac8363STakashi Iwai { 0x21, 0x40000100 },
376629ac8363STakashi Iwai { 0x22, 0x40000100 },
376729ac8363STakashi Iwai { 0x23, 0x40000100 },
376829ac8363STakashi Iwai {}
376981d3dbdeSTobin Davis };
377081d3dbdeSTobin Davis
377129ac8363STakashi Iwai static const struct hda_pintbl d965_5st_pin_configs[] = {
377229ac8363STakashi Iwai { 0x0a, 0x02214020 },
377329ac8363STakashi Iwai { 0x0b, 0x02a19080 },
377429ac8363STakashi Iwai { 0x0c, 0x0181304e },
377529ac8363STakashi Iwai { 0x0d, 0x01014010 },
377629ac8363STakashi Iwai { 0x0e, 0x01a19040 },
377729ac8363STakashi Iwai { 0x0f, 0x01011012 },
377829ac8363STakashi Iwai { 0x10, 0x01016011 },
377929ac8363STakashi Iwai { 0x11, 0x40000100 },
378029ac8363STakashi Iwai { 0x12, 0x40000100 },
378129ac8363STakashi Iwai { 0x13, 0x40000100 },
378229ac8363STakashi Iwai { 0x14, 0x40000100 },
378329ac8363STakashi Iwai { 0x21, 0x01442070 },
378429ac8363STakashi Iwai { 0x22, 0x40000100 },
378529ac8363STakashi Iwai { 0x23, 0x40000100 },
378629ac8363STakashi Iwai {}
378793ed1503STobin Davis };
378893ed1503STobin Davis
378929ac8363STakashi Iwai static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
379029ac8363STakashi Iwai { 0x0a, 0x40000100 },
379129ac8363STakashi Iwai { 0x0b, 0x40000100 },
379229ac8363STakashi Iwai { 0x0c, 0x0181304e },
379329ac8363STakashi Iwai { 0x0d, 0x01014010 },
379429ac8363STakashi Iwai { 0x0e, 0x01a19040 },
379529ac8363STakashi Iwai { 0x0f, 0x01011012 },
379629ac8363STakashi Iwai { 0x10, 0x01016011 },
379729ac8363STakashi Iwai { 0x11, 0x40000100 },
379829ac8363STakashi Iwai { 0x12, 0x40000100 },
379929ac8363STakashi Iwai { 0x13, 0x40000100 },
380029ac8363STakashi Iwai { 0x14, 0x40000100 },
380129ac8363STakashi Iwai { 0x21, 0x01442070 },
380229ac8363STakashi Iwai { 0x22, 0x40000100 },
380329ac8363STakashi Iwai { 0x23, 0x40000100 },
380429ac8363STakashi Iwai {}
3805679d92edSTakashi Iwai };
3806679d92edSTakashi Iwai
380729ac8363STakashi Iwai static const struct hda_pintbl dell_3st_pin_configs[] = {
380829ac8363STakashi Iwai { 0x0a, 0x02211230 },
380929ac8363STakashi Iwai { 0x0b, 0x02a11220 },
381029ac8363STakashi Iwai { 0x0c, 0x01a19040 },
381129ac8363STakashi Iwai { 0x0d, 0x01114210 },
381229ac8363STakashi Iwai { 0x0e, 0x01111212 },
381329ac8363STakashi Iwai { 0x0f, 0x01116211 },
381429ac8363STakashi Iwai { 0x10, 0x01813050 },
381529ac8363STakashi Iwai { 0x11, 0x01112214 },
381629ac8363STakashi Iwai { 0x12, 0x403003fa },
381729ac8363STakashi Iwai { 0x13, 0x90a60040 },
381829ac8363STakashi Iwai { 0x14, 0x90a60040 },
381929ac8363STakashi Iwai { 0x21, 0x404003fb },
382029ac8363STakashi Iwai { 0x22, 0x40c003fc },
382129ac8363STakashi Iwai { 0x23, 0x40000100 },
382229ac8363STakashi Iwai {}
38234ff076e5STobin Davis };
38244ff076e5STobin Davis
stac927x_fixup_ref_no_jd(struct hda_codec * codec,const struct hda_fixup * fix,int action)382529ac8363STakashi Iwai static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
382629ac8363STakashi Iwai const struct hda_fixup *fix, int action)
382729ac8363STakashi Iwai {
382829ac8363STakashi Iwai /* no jack detecion for ref-no-jd model */
382936c9db7aSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE)
383036c9db7aSTakashi Iwai codec->no_jack_detect = 1;
383129ac8363STakashi Iwai }
383229ac8363STakashi Iwai
stac927x_fixup_ref(struct hda_codec * codec,const struct hda_fixup * fix,int action)383329ac8363STakashi Iwai static void stac927x_fixup_ref(struct hda_codec *codec,
383429ac8363STakashi Iwai const struct hda_fixup *fix, int action)
383529ac8363STakashi Iwai {
383629ac8363STakashi Iwai struct sigmatel_spec *spec = codec->spec;
383729ac8363STakashi Iwai
383829ac8363STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
383929ac8363STakashi Iwai snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
384029ac8363STakashi Iwai spec->eapd_mask = spec->gpio_mask = 0;
384129ac8363STakashi Iwai spec->gpio_dir = spec->gpio_data = 0;
384229ac8363STakashi Iwai }
384329ac8363STakashi Iwai }
384429ac8363STakashi Iwai
stac927x_fixup_dell_dmic(struct hda_codec * codec,const struct hda_fixup * fix,int action)384529ac8363STakashi Iwai static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
384629ac8363STakashi Iwai const struct hda_fixup *fix, int action)
384729ac8363STakashi Iwai {
384829ac8363STakashi Iwai struct sigmatel_spec *spec = codec->spec;
384929ac8363STakashi Iwai
385029ac8363STakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
385129ac8363STakashi Iwai return;
385229ac8363STakashi Iwai
38537639a06cSTakashi Iwai if (codec->core.subsystem_id != 0x1028022f) {
385429ac8363STakashi Iwai /* GPIO2 High = Enable EAPD */
385529ac8363STakashi Iwai spec->eapd_mask = spec->gpio_mask = 0x04;
385629ac8363STakashi Iwai spec->gpio_dir = spec->gpio_data = 0x04;
385729ac8363STakashi Iwai }
385829ac8363STakashi Iwai
385929ac8363STakashi Iwai snd_hda_add_verbs(codec, dell_3st_core_init);
386029ac8363STakashi Iwai spec->volknob_init = 1;
386129ac8363STakashi Iwai }
386229ac8363STakashi Iwai
stac927x_fixup_volknob(struct hda_codec * codec,const struct hda_fixup * fix,int action)386329ac8363STakashi Iwai static void stac927x_fixup_volknob(struct hda_codec *codec,
386429ac8363STakashi Iwai const struct hda_fixup *fix, int action)
386529ac8363STakashi Iwai {
386629ac8363STakashi Iwai struct sigmatel_spec *spec = codec->spec;
386729ac8363STakashi Iwai
386829ac8363STakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
386929ac8363STakashi Iwai snd_hda_add_verbs(codec, stac927x_volknob_core_init);
387029ac8363STakashi Iwai spec->volknob_init = 1;
387129ac8363STakashi Iwai }
387229ac8363STakashi Iwai }
387329ac8363STakashi Iwai
387429ac8363STakashi Iwai static const struct hda_fixup stac927x_fixups[] = {
387529ac8363STakashi Iwai [STAC_D965_REF_NO_JD] = {
387629ac8363STakashi Iwai .type = HDA_FIXUP_FUNC,
387729ac8363STakashi Iwai .v.func = stac927x_fixup_ref_no_jd,
387829ac8363STakashi Iwai .chained = true,
387929ac8363STakashi Iwai .chain_id = STAC_D965_REF,
388029ac8363STakashi Iwai },
388129ac8363STakashi Iwai [STAC_D965_REF] = {
388229ac8363STakashi Iwai .type = HDA_FIXUP_FUNC,
388329ac8363STakashi Iwai .v.func = stac927x_fixup_ref,
388429ac8363STakashi Iwai },
388529ac8363STakashi Iwai [STAC_D965_3ST] = {
388629ac8363STakashi Iwai .type = HDA_FIXUP_PINS,
388729ac8363STakashi Iwai .v.pins = d965_3st_pin_configs,
388829ac8363STakashi Iwai .chained = true,
388929ac8363STakashi Iwai .chain_id = STAC_D965_VERBS,
389029ac8363STakashi Iwai },
389129ac8363STakashi Iwai [STAC_D965_5ST] = {
389229ac8363STakashi Iwai .type = HDA_FIXUP_PINS,
389329ac8363STakashi Iwai .v.pins = d965_5st_pin_configs,
389429ac8363STakashi Iwai .chained = true,
389529ac8363STakashi Iwai .chain_id = STAC_D965_VERBS,
389629ac8363STakashi Iwai },
389729ac8363STakashi Iwai [STAC_D965_VERBS] = {
389829ac8363STakashi Iwai .type = HDA_FIXUP_VERBS,
389929ac8363STakashi Iwai .v.verbs = d965_core_init,
390029ac8363STakashi Iwai },
390129ac8363STakashi Iwai [STAC_D965_5ST_NO_FP] = {
390229ac8363STakashi Iwai .type = HDA_FIXUP_PINS,
390329ac8363STakashi Iwai .v.pins = d965_5st_no_fp_pin_configs,
390429ac8363STakashi Iwai },
3905078502b5SDarren Stevens [STAC_NEMO_DEFAULT] = {
3906078502b5SDarren Stevens .type = HDA_FIXUP_PINS,
3907078502b5SDarren Stevens .v.pins = nemo_pin_configs,
3908078502b5SDarren Stevens },
390929ac8363STakashi Iwai [STAC_DELL_3ST] = {
391029ac8363STakashi Iwai .type = HDA_FIXUP_PINS,
391129ac8363STakashi Iwai .v.pins = dell_3st_pin_configs,
391229ac8363STakashi Iwai .chained = true,
391329ac8363STakashi Iwai .chain_id = STAC_927X_DELL_DMIC,
391429ac8363STakashi Iwai },
391529ac8363STakashi Iwai [STAC_DELL_BIOS] = {
391629ac8363STakashi Iwai .type = HDA_FIXUP_PINS,
391729ac8363STakashi Iwai .v.pins = (const struct hda_pintbl[]) {
391829ac8363STakashi Iwai /* correct the front output jack as a hp out */
3919f3e351eeSTakashi Iwai { 0x0f, 0x0221101f },
392029ac8363STakashi Iwai /* correct the front input jack as a mic */
392129ac8363STakashi Iwai { 0x0e, 0x02a79130 },
392229ac8363STakashi Iwai {}
392329ac8363STakashi Iwai },
392429ac8363STakashi Iwai .chained = true,
392529ac8363STakashi Iwai .chain_id = STAC_927X_DELL_DMIC,
392629ac8363STakashi Iwai },
3927eefb8be4STakashi Iwai [STAC_DELL_BIOS_AMIC] = {
3928eefb8be4STakashi Iwai .type = HDA_FIXUP_PINS,
3929eefb8be4STakashi Iwai .v.pins = (const struct hda_pintbl[]) {
3930eefb8be4STakashi Iwai /* configure the analog microphone on some laptops */
3931eefb8be4STakashi Iwai { 0x0c, 0x90a79130 },
3932eefb8be4STakashi Iwai {}
3933eefb8be4STakashi Iwai },
3934eefb8be4STakashi Iwai .chained = true,
3935eefb8be4STakashi Iwai .chain_id = STAC_DELL_BIOS,
3936eefb8be4STakashi Iwai },
393729ac8363STakashi Iwai [STAC_DELL_BIOS_SPDIF] = {
393829ac8363STakashi Iwai .type = HDA_FIXUP_PINS,
393929ac8363STakashi Iwai .v.pins = (const struct hda_pintbl[]) {
394029ac8363STakashi Iwai /* correct the device field to SPDIF out */
394129ac8363STakashi Iwai { 0x21, 0x01442070 },
394229ac8363STakashi Iwai {}
394329ac8363STakashi Iwai },
394429ac8363STakashi Iwai .chained = true,
394529ac8363STakashi Iwai .chain_id = STAC_DELL_BIOS,
394629ac8363STakashi Iwai },
394729ac8363STakashi Iwai [STAC_927X_DELL_DMIC] = {
394829ac8363STakashi Iwai .type = HDA_FIXUP_FUNC,
394929ac8363STakashi Iwai .v.func = stac927x_fixup_dell_dmic,
395029ac8363STakashi Iwai },
395129ac8363STakashi Iwai [STAC_927X_VOLKNOB] = {
395229ac8363STakashi Iwai .type = HDA_FIXUP_FUNC,
395329ac8363STakashi Iwai .v.func = stac927x_fixup_volknob,
395429ac8363STakashi Iwai },
39553cc08dc6SMatt Porter };
39563cc08dc6SMatt Porter
395729ac8363STakashi Iwai static const struct hda_model_fixup stac927x_models[] = {
395829ac8363STakashi Iwai { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
395929ac8363STakashi Iwai { .id = STAC_D965_REF, .name = "ref" },
396029ac8363STakashi Iwai { .id = STAC_D965_3ST, .name = "3stack" },
396129ac8363STakashi Iwai { .id = STAC_D965_5ST, .name = "5stack" },
396229ac8363STakashi Iwai { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
396329ac8363STakashi Iwai { .id = STAC_DELL_3ST, .name = "dell-3stack" },
396429ac8363STakashi Iwai { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3965078502b5SDarren Stevens { .id = STAC_NEMO_DEFAULT, .name = "nemo-default" },
3966eefb8be4STakashi Iwai { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
396729ac8363STakashi Iwai { .id = STAC_927X_VOLKNOB, .name = "volknob" },
396829ac8363STakashi Iwai {}
3969f5fcc13cSTakashi Iwai };
3970f5fcc13cSTakashi Iwai
397129ac8363STakashi Iwai static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
3972f5fcc13cSTakashi Iwai /* SigmaTel reference board */
3973f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3974f5fcc13cSTakashi Iwai "DFI LanParty", STAC_D965_REF),
3975577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3976577aa2c1SMatthew Ranostay "DFI LanParty", STAC_D965_REF),
397781d3dbdeSTobin Davis /* Intel 946 based systems */
3978f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3979f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
398093ed1503STobin Davis /* 965 based 3 stack systems */
3981dea0a509STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3982dea0a509STakashi Iwai "Intel D965", STAC_D965_3ST),
3983dea0a509STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3984dea0a509STakashi Iwai "Intel D965", STAC_D965_3ST),
39854ff076e5STobin Davis /* Dell 3 stack systems */
3986dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
39874ff076e5STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
39884ff076e5STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
39898e9068b1SMatthew Ranostay /* Dell 3 stack systems with verb table in BIOS */
39902f32d909SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
399166668b6fSDaniel T Chen SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
39922f32d909SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
399329ac8363STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
399484d3dc20SChengu Wang SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
39958e9068b1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
39968e9068b1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
39978e9068b1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
399829ac8363STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
399993ed1503STobin Davis /* 965 based 5 stack systems */
4000dea0a509STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
4001dea0a509STakashi Iwai "Intel D965", STAC_D965_5ST),
4002dea0a509STakashi Iwai SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
4003dea0a509STakashi Iwai "Intel D965", STAC_D965_5ST),
4004078502b5SDarren Stevens /* Nemo */
4005078502b5SDarren Stevens SND_PCI_QUIRK(0x1888, 0x1000, "AmigaOne X1000", STAC_NEMO_DEFAULT),
400654930531STakashi Iwai /* volume-knob fixes */
400754930531STakashi Iwai SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
40083cc08dc6SMatt Porter {} /* terminator */
40093cc08dc6SMatt Porter };
40103cc08dc6SMatt Porter
4011fe6322caSTakashi Iwai static const struct hda_pintbl ref9205_pin_configs[] = {
4012fe6322caSTakashi Iwai { 0x0a, 0x40000100 },
4013fe6322caSTakashi Iwai { 0x0b, 0x40000100 },
4014fe6322caSTakashi Iwai { 0x0c, 0x01016011 },
4015fe6322caSTakashi Iwai { 0x0d, 0x01014010 },
4016fe6322caSTakashi Iwai { 0x0e, 0x01813122 },
4017fe6322caSTakashi Iwai { 0x0f, 0x01a19021 },
4018fe6322caSTakashi Iwai { 0x14, 0x01019020 },
4019fe6322caSTakashi Iwai { 0x16, 0x40000100 },
4020fe6322caSTakashi Iwai { 0x17, 0x90a000f0 },
4021fe6322caSTakashi Iwai { 0x18, 0x90a000f0 },
4022fe6322caSTakashi Iwai { 0x21, 0x01441030 },
4023fe6322caSTakashi Iwai { 0x22, 0x01c41030 },
4024fe6322caSTakashi Iwai {}
4025f3302a59SMatt Porter };
4026f3302a59SMatt Porter
4027dfe495d0STakashi Iwai /*
4028dfe495d0STakashi Iwai STAC 9205 pin configs for
4029dfe495d0STakashi Iwai 102801F1
4030dfe495d0STakashi Iwai 102801F2
4031dfe495d0STakashi Iwai 102801FC
4032dfe495d0STakashi Iwai 102801FD
4033dfe495d0STakashi Iwai 10280204
4034dfe495d0STakashi Iwai 1028021F
40353fa2ef74SMatthew Ranostay 10280228 (Dell Vostro 1500)
403695e70e87SAnisse Astier 10280229 (Dell Vostro 1700)
4037dfe495d0STakashi Iwai */
4038fe6322caSTakashi Iwai static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
4039fe6322caSTakashi Iwai { 0x0a, 0x0321101F },
4040fe6322caSTakashi Iwai { 0x0b, 0x03A11020 },
4041fe6322caSTakashi Iwai { 0x0c, 0x400003FA },
4042fe6322caSTakashi Iwai { 0x0d, 0x90170310 },
4043fe6322caSTakashi Iwai { 0x0e, 0x400003FB },
4044fe6322caSTakashi Iwai { 0x0f, 0x400003FC },
4045fe6322caSTakashi Iwai { 0x14, 0x400003FD },
4046fe6322caSTakashi Iwai { 0x16, 0x40F000F9 },
4047fe6322caSTakashi Iwai { 0x17, 0x90A60330 },
4048fe6322caSTakashi Iwai { 0x18, 0x400003FF },
4049fe6322caSTakashi Iwai { 0x21, 0x0144131F },
4050fe6322caSTakashi Iwai { 0x22, 0x40C003FE },
4051fe6322caSTakashi Iwai {}
4052dfe495d0STakashi Iwai };
4053dfe495d0STakashi Iwai
4054dfe495d0STakashi Iwai /*
4055dfe495d0STakashi Iwai STAC 9205 pin configs for
4056dfe495d0STakashi Iwai 102801F9
4057dfe495d0STakashi Iwai 102801FA
4058dfe495d0STakashi Iwai 102801FE
4059dfe495d0STakashi Iwai 102801FF (Dell Precision M4300)
4060dfe495d0STakashi Iwai 10280206
4061dfe495d0STakashi Iwai 10280200
4062dfe495d0STakashi Iwai 10280201
4063dfe495d0STakashi Iwai */
4064fe6322caSTakashi Iwai static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
4065fe6322caSTakashi Iwai { 0x0a, 0x0321101f },
4066fe6322caSTakashi Iwai { 0x0b, 0x03a11020 },
4067fe6322caSTakashi Iwai { 0x0c, 0x90a70330 },
4068fe6322caSTakashi Iwai { 0x0d, 0x90170310 },
4069fe6322caSTakashi Iwai { 0x0e, 0x400000fe },
4070fe6322caSTakashi Iwai { 0x0f, 0x400000ff },
4071fe6322caSTakashi Iwai { 0x14, 0x400000fd },
4072fe6322caSTakashi Iwai { 0x16, 0x40f000f9 },
4073fe6322caSTakashi Iwai { 0x17, 0x400000fa },
4074fe6322caSTakashi Iwai { 0x18, 0x400000fc },
4075fe6322caSTakashi Iwai { 0x21, 0x0144131f },
4076fe6322caSTakashi Iwai { 0x22, 0x40c003f8 },
4077fe6322caSTakashi Iwai /* Enable SPDIF in/out */
4078fe6322caSTakashi Iwai { 0x1f, 0x01441030 },
4079fe6322caSTakashi Iwai { 0x20, 0x1c410030 },
4080fe6322caSTakashi Iwai {}
4081ae0a8ed8STobin Davis };
4082ae0a8ed8STobin Davis
4083fe6322caSTakashi Iwai static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
4084fe6322caSTakashi Iwai { 0x0a, 0x0421101f },
4085fe6322caSTakashi Iwai { 0x0b, 0x04a11020 },
4086fe6322caSTakashi Iwai { 0x0c, 0x400003fa },
4087fe6322caSTakashi Iwai { 0x0d, 0x90170310 },
4088fe6322caSTakashi Iwai { 0x0e, 0x400003fb },
4089fe6322caSTakashi Iwai { 0x0f, 0x400003fc },
4090fe6322caSTakashi Iwai { 0x14, 0x400003fd },
4091fe6322caSTakashi Iwai { 0x16, 0x400003f9 },
4092fe6322caSTakashi Iwai { 0x17, 0x90a60330 },
4093fe6322caSTakashi Iwai { 0x18, 0x400003ff },
4094fe6322caSTakashi Iwai { 0x21, 0x01441340 },
4095fe6322caSTakashi Iwai { 0x22, 0x40c003fe },
4096fe6322caSTakashi Iwai {}
4097ae0a8ed8STobin Davis };
4098ae0a8ed8STobin Davis
stac9205_fixup_ref(struct hda_codec * codec,const struct hda_fixup * fix,int action)4099fe6322caSTakashi Iwai static void stac9205_fixup_ref(struct hda_codec *codec,
4100fe6322caSTakashi Iwai const struct hda_fixup *fix, int action)
4101fe6322caSTakashi Iwai {
4102fe6322caSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
4103fe6322caSTakashi Iwai
4104fe6322caSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4105fe6322caSTakashi Iwai snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
4106fe6322caSTakashi Iwai /* SPDIF-In enabled */
4107fe6322caSTakashi Iwai spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
4108fe6322caSTakashi Iwai }
4109fe6322caSTakashi Iwai }
4110fe6322caSTakashi Iwai
stac9205_fixup_dell_m43(struct hda_codec * codec,const struct hda_fixup * fix,int action)4111fe6322caSTakashi Iwai static void stac9205_fixup_dell_m43(struct hda_codec *codec,
4112fe6322caSTakashi Iwai const struct hda_fixup *fix, int action)
4113fe6322caSTakashi Iwai {
4114fe6322caSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
41151a4f69d5STakashi Iwai struct hda_jack_callback *jack;
4116fe6322caSTakashi Iwai
4117fe6322caSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4118fe6322caSTakashi Iwai snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
4119fe6322caSTakashi Iwai
4120fe6322caSTakashi Iwai /* Enable unsol response for GPIO4/Dock HP connection */
41217639a06cSTakashi Iwai snd_hda_codec_write_cache(codec, codec->core.afg, 0,
4122fe6322caSTakashi Iwai AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
41237639a06cSTakashi Iwai jack = snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
412436c9db7aSTakashi Iwai stac_vref_event);
4125bda17b82STakashi Iwai if (!IS_ERR(jack))
412636c9db7aSTakashi Iwai jack->private_data = 0x01;
4127fe6322caSTakashi Iwai
4128fe6322caSTakashi Iwai spec->gpio_dir = 0x0b;
4129fe6322caSTakashi Iwai spec->eapd_mask = 0x01;
4130fe6322caSTakashi Iwai spec->gpio_mask = 0x1b;
4131fe6322caSTakashi Iwai spec->gpio_mute = 0x10;
4132fe6322caSTakashi Iwai /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
4133fe6322caSTakashi Iwai * GPIO3 Low = DRM
4134fe6322caSTakashi Iwai */
4135fe6322caSTakashi Iwai spec->gpio_data = 0x01;
4136fe6322caSTakashi Iwai }
4137fe6322caSTakashi Iwai }
4138fe6322caSTakashi Iwai
stac9205_fixup_eapd(struct hda_codec * codec,const struct hda_fixup * fix,int action)4139fe6322caSTakashi Iwai static void stac9205_fixup_eapd(struct hda_codec *codec,
4140fe6322caSTakashi Iwai const struct hda_fixup *fix, int action)
4141fe6322caSTakashi Iwai {
4142fe6322caSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
4143fe6322caSTakashi Iwai
4144fe6322caSTakashi Iwai if (action == HDA_FIXUP_ACT_PRE_PROBE)
4145fe6322caSTakashi Iwai spec->eapd_switch = 0;
4146fe6322caSTakashi Iwai }
4147fe6322caSTakashi Iwai
4148fe6322caSTakashi Iwai static const struct hda_fixup stac9205_fixups[] = {
4149fe6322caSTakashi Iwai [STAC_9205_REF] = {
4150fe6322caSTakashi Iwai .type = HDA_FIXUP_FUNC,
4151fe6322caSTakashi Iwai .v.func = stac9205_fixup_ref,
4152fe6322caSTakashi Iwai },
4153fe6322caSTakashi Iwai [STAC_9205_DELL_M42] = {
4154fe6322caSTakashi Iwai .type = HDA_FIXUP_PINS,
4155fe6322caSTakashi Iwai .v.pins = dell_9205_m42_pin_configs,
4156fe6322caSTakashi Iwai },
4157fe6322caSTakashi Iwai [STAC_9205_DELL_M43] = {
4158fe6322caSTakashi Iwai .type = HDA_FIXUP_FUNC,
4159fe6322caSTakashi Iwai .v.func = stac9205_fixup_dell_m43,
4160fe6322caSTakashi Iwai },
4161fe6322caSTakashi Iwai [STAC_9205_DELL_M44] = {
4162fe6322caSTakashi Iwai .type = HDA_FIXUP_PINS,
4163fe6322caSTakashi Iwai .v.pins = dell_9205_m44_pin_configs,
4164fe6322caSTakashi Iwai },
4165fe6322caSTakashi Iwai [STAC_9205_EAPD] = {
4166fe6322caSTakashi Iwai .type = HDA_FIXUP_FUNC,
4167fe6322caSTakashi Iwai .v.func = stac9205_fixup_eapd,
4168fe6322caSTakashi Iwai },
4169fe6322caSTakashi Iwai {}
4170f3302a59SMatt Porter };
4171f3302a59SMatt Porter
4172fe6322caSTakashi Iwai static const struct hda_model_fixup stac9205_models[] = {
4173fe6322caSTakashi Iwai { .id = STAC_9205_REF, .name = "ref" },
4174fe6322caSTakashi Iwai { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
4175fe6322caSTakashi Iwai { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
4176fe6322caSTakashi Iwai { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
4177fe6322caSTakashi Iwai { .id = STAC_9205_EAPD, .name = "eapd" },
4178fe6322caSTakashi Iwai {}
4179f5fcc13cSTakashi Iwai };
4180f5fcc13cSTakashi Iwai
4181fe6322caSTakashi Iwai static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
4182f5fcc13cSTakashi Iwai /* SigmaTel reference board */
4183f5fcc13cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
4184f5fcc13cSTakashi Iwai "DFI LanParty", STAC_9205_REF),
418502358fcfSHerton Ronaldo Krzesinski SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
418602358fcfSHerton Ronaldo Krzesinski "SigmaTel", STAC_9205_REF),
4187577aa2c1SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
4188577aa2c1SMatthew Ranostay "DFI LanParty", STAC_9205_REF),
4189d9a4268eSTakashi Iwai /* Dell */
4190dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
4191dfe495d0STakashi Iwai "unknown Dell", STAC_9205_DELL_M42),
4192dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
4193dfe495d0STakashi Iwai "unknown Dell", STAC_9205_DELL_M42),
4194ae0a8ed8STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
4195b44ef2f1SMatthew Ranostay "Dell Precision", STAC_9205_DELL_M43),
4196ae0a8ed8STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
4197ae0a8ed8STobin Davis "Dell Precision", STAC_9205_DELL_M43),
4198ae0a8ed8STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
4199ae0a8ed8STobin Davis "Dell Precision", STAC_9205_DELL_M43),
4200dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
4201dfe495d0STakashi Iwai "unknown Dell", STAC_9205_DELL_M42),
4202dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
4203dfe495d0STakashi Iwai "unknown Dell", STAC_9205_DELL_M42),
4204ae0a8ed8STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
4205ae0a8ed8STobin Davis "Dell Precision", STAC_9205_DELL_M43),
4206ae0a8ed8STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
4207dfe495d0STakashi Iwai "Dell Precision M4300", STAC_9205_DELL_M43),
4208dfe495d0STakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
4209dfe495d0STakashi Iwai "unknown Dell", STAC_9205_DELL_M42),
42104549915cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
42114549915cSTakashi Iwai "Dell Precision", STAC_9205_DELL_M43),
42124549915cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
42134549915cSTakashi Iwai "Dell Precision", STAC_9205_DELL_M43),
42144549915cSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
42154549915cSTakashi Iwai "Dell Precision", STAC_9205_DELL_M43),
4216ae0a8ed8STobin Davis SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
4217ae0a8ed8STobin Davis "Dell Inspiron", STAC_9205_DELL_M44),
42183fa2ef74SMatthew Ranostay SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
42193fa2ef74SMatthew Ranostay "Dell Vostro 1500", STAC_9205_DELL_M42),
422095e70e87SAnisse Astier SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
422195e70e87SAnisse Astier "Dell Vostro 1700", STAC_9205_DELL_M42),
4222d9a4268eSTakashi Iwai /* Gateway */
422342b95f0cSHao Song SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
4224d9a4268eSTakashi Iwai SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
4225f3302a59SMatt Porter {} /* terminator */
4226f3302a59SMatt Porter };
4227f3302a59SMatt Porter
stac92hd95_fixup_hp_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)42288b3dfdafSTakashi Iwai static void stac92hd95_fixup_hp_led(struct hda_codec *codec,
42298b3dfdafSTakashi Iwai const struct hda_fixup *fix, int action)
42308b3dfdafSTakashi Iwai {
42318b3dfdafSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
42328b3dfdafSTakashi Iwai
42338b3dfdafSTakashi Iwai if (action != HDA_FIXUP_ACT_PRE_PROBE)
42348b3dfdafSTakashi Iwai return;
42358b3dfdafSTakashi Iwai
42368b3dfdafSTakashi Iwai if (find_mute_led_cfg(codec, spec->default_polarity))
42378b3dfdafSTakashi Iwai codec_dbg(codec, "mute LED gpio %d polarity %d\n",
42388b3dfdafSTakashi Iwai spec->gpio_led,
42398b3dfdafSTakashi Iwai spec->gpio_led_polarity);
42408b3dfdafSTakashi Iwai }
42418b3dfdafSTakashi Iwai
42428b3dfdafSTakashi Iwai static const struct hda_fixup stac92hd95_fixups[] = {
42438b3dfdafSTakashi Iwai [STAC_92HD95_HP_LED] = {
42448b3dfdafSTakashi Iwai .type = HDA_FIXUP_FUNC,
42458b3dfdafSTakashi Iwai .v.func = stac92hd95_fixup_hp_led,
42468b3dfdafSTakashi Iwai },
42478b3dfdafSTakashi Iwai [STAC_92HD95_HP_BASS] = {
42488b3dfdafSTakashi Iwai .type = HDA_FIXUP_VERBS,
42498b3dfdafSTakashi Iwai .v.verbs = (const struct hda_verb[]) {
42508b3dfdafSTakashi Iwai {0x1a, 0x795, 0x00}, /* HPF to 100Hz */
42518b3dfdafSTakashi Iwai {}
42528b3dfdafSTakashi Iwai },
42538b3dfdafSTakashi Iwai .chained = true,
42548b3dfdafSTakashi Iwai .chain_id = STAC_92HD95_HP_LED,
42558b3dfdafSTakashi Iwai },
42568b3dfdafSTakashi Iwai };
42578b3dfdafSTakashi Iwai
42588b3dfdafSTakashi Iwai static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
42598b3dfdafSTakashi Iwai SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
42608b3dfdafSTakashi Iwai {} /* terminator */
42618b3dfdafSTakashi Iwai };
42628b3dfdafSTakashi Iwai
42638b3dfdafSTakashi Iwai static const struct hda_model_fixup stac92hd95_models[] = {
42648b3dfdafSTakashi Iwai { .id = STAC_92HD95_HP_LED, .name = "hp-led" },
42658b3dfdafSTakashi Iwai { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" },
42668b3dfdafSTakashi Iwai {}
42678b3dfdafSTakashi Iwai };
42688b3dfdafSTakashi Iwai
42698b3dfdafSTakashi Iwai
stac_parse_auto_config(struct hda_codec * codec)427036c9db7aSTakashi Iwai static int stac_parse_auto_config(struct hda_codec *codec)
4271eb06ed8fSTakashi Iwai {
4272eb06ed8fSTakashi Iwai struct sigmatel_spec *spec = codec->spec;
4273dc04d1b4STakashi Iwai int err;
4274f390dad4SDavid Henningsson int flags = 0;
4275eb06ed8fSTakashi Iwai
4276f390dad4SDavid Henningsson if (spec->headset_jack)
4277f390dad4SDavid Henningsson flags |= HDA_PINCFG_HEADSET_MIC;
4278f390dad4SDavid Henningsson
4279f390dad4SDavid Henningsson err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags);
4280c21ca4a8STakashi Iwai if (err < 0)
4281c21ca4a8STakashi Iwai return err;
4282dc04d1b4STakashi Iwai
428336c9db7aSTakashi Iwai /* add hooks */
428436c9db7aSTakashi Iwai spec->gen.pcm_playback_hook = stac_playback_pcm_hook;
428536c9db7aSTakashi Iwai spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
428636c9db7aSTakashi Iwai
428736c9db7aSTakashi Iwai spec->gen.automute_hook = stac_update_outputs;
428836c9db7aSTakashi Iwai
4289e65bf997SJaroslav Kysela if (spec->gpio_led)
4290e65bf997SJaroslav Kysela snd_hda_gen_add_mute_led_cdev(codec, stac_vmaster_hook);
4291e65bf997SJaroslav Kysela
429236c9db7aSTakashi Iwai err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
4293eb06ed8fSTakashi Iwai if (err < 0)
4294c7d4b2faSMatt return err;
4295dc04d1b4STakashi Iwai
42966b275b14STakashi Iwai if (spec->vref_mute_led_nid) {
42976b275b14STakashi Iwai err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
42986b275b14STakashi Iwai if (err < 0)
42996b275b14STakashi Iwai return err;
43006b275b14STakashi Iwai }
43016b275b14STakashi Iwai
43021cd2224cSMatthew Ranostay /* setup analog beep controls */
43031cd2224cSMatthew Ranostay if (spec->anabeep_nid > 0) {
430436c9db7aSTakashi Iwai err = stac_auto_create_beep_ctls(codec,
43051cd2224cSMatthew Ranostay spec->anabeep_nid);
43061cd2224cSMatthew Ranostay if (err < 0)
43071cd2224cSMatthew Ranostay return err;
43081cd2224cSMatthew Ranostay }
43091cd2224cSMatthew Ranostay
43101cd2224cSMatthew Ranostay /* setup digital beep controls and input device */
43111cd2224cSMatthew Ranostay #ifdef CONFIG_SND_HDA_INPUT_BEEP
43127504b6cdSTakashi Iwai if (spec->gen.beep_nid) {
43137504b6cdSTakashi Iwai hda_nid_t nid = spec->gen.beep_nid;
43144d4e9bb3STakashi Iwai unsigned int caps;
43151cd2224cSMatthew Ranostay
431636c9db7aSTakashi Iwai err = stac_auto_create_beep_ctls(codec, nid);
43171cd2224cSMatthew Ranostay if (err < 0)
43181cd2224cSMatthew Ranostay return err;
4319d8d881ddSTakashi Iwai if (codec->beep) {
4320fa797966STakashi Iwai /* IDT/STAC codecs have linear beep tone parameter */
43211b0e372dSDaniel J Blueman codec->beep->linear_tone = spec->linear_tone_beep;
43224c8d695cSTakashi Iwai /* keep power up while beep is enabled */
43234c8d695cSTakashi Iwai codec->beep->keep_power_at_enable = 1;
43244d4e9bb3STakashi Iwai /* if no beep switch is available, make its own one */
43254d4e9bb3STakashi Iwai caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4326d8d881ddSTakashi Iwai if (!(caps & AC_AMPCAP_MUTE)) {
432736c9db7aSTakashi Iwai err = stac_beep_switch_ctl(codec);
43284d4e9bb3STakashi Iwai if (err < 0)
43294d4e9bb3STakashi Iwai return err;
43304d4e9bb3STakashi Iwai }
43311cd2224cSMatthew Ranostay }
4332d8d881ddSTakashi Iwai }
43331cd2224cSMatthew Ranostay #endif
43341cd2224cSMatthew Ranostay
433536c9db7aSTakashi Iwai if (spec->aloopback_ctl &&
433636c9db7aSTakashi Iwai snd_hda_get_bool_hint(codec, "loopback") == 1) {
4337a551d914STakashi Iwai unsigned int wr_verb =
4338a551d914STakashi Iwai spec->aloopback_ctl->private_value >> 16;
4339a551d914STakashi Iwai if (snd_hdac_regmap_add_vendor_verb(&codec->core, wr_verb))
4340a551d914STakashi Iwai return -ENOMEM;
434136c9db7aSTakashi Iwai if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
434274aeaabcSMatthew Ranostay return -ENOMEM;
434336c9db7aSTakashi Iwai }
434436c9db7aSTakashi Iwai
434542875479STakashi Iwai if (spec->have_spdif_mux) {
434642875479STakashi Iwai err = stac_create_spdif_mux_ctls(codec);
434742875479STakashi Iwai if (err < 0)
434842875479STakashi Iwai return err;
434942875479STakashi Iwai }
435042875479STakashi Iwai
43517a9744cbSTakashi Iwai stac_init_power_map(codec);
4352aa699c49STakashi Iwai
43537a9744cbSTakashi Iwai return 0;
43547a9744cbSTakashi Iwai }
435529adc4b9SDavid Henningsson
stac_init(struct hda_codec * codec)435636c9db7aSTakashi Iwai static int stac_init(struct hda_codec *codec)
4357b76c850fSMatthew Ranostay {
4358b76c850fSMatthew Ranostay struct sigmatel_spec *spec = codec->spec;
4359e4973e1eSTakashi Iwai int i;
4360c7d4b2faSMatt
43616565e4faSTakashi Iwai /* override some hints */
43626565e4faSTakashi Iwai stac_store_hints(codec);
43636565e4faSTakashi Iwai
4364f73d3585STakashi Iwai /* set up GPIO */
4365f73d3585STakashi Iwai /* turn on EAPD statically when spec->eapd_switch isn't set.
4366f73d3585STakashi Iwai * otherwise, unsol event will turn it on/off dynamically
4367f73d3585STakashi Iwai */
4368f73d3585STakashi Iwai if (!spec->eapd_switch)
43691ea9a69dSTakashi Iwai spec->gpio_data |= spec->eapd_mask;
43701ea9a69dSTakashi Iwai stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4371f73d3585STakashi Iwai
437236c9db7aSTakashi Iwai snd_hda_gen_init(codec);
4373c882246dSTakashi Iwai
4374c882246dSTakashi Iwai /* sync the power-map */
4375c882246dSTakashi Iwai if (spec->num_pwrs)
43767639a06cSTakashi Iwai snd_hda_codec_write(codec, codec->core.afg, 0,
4377c882246dSTakashi Iwai AC_VERB_IDT_SET_POWER_MAP,
4378c882246dSTakashi Iwai spec->power_map_bits);
437936c9db7aSTakashi Iwai
438036c9db7aSTakashi Iwai /* power down inactive ADCs */
438136c9db7aSTakashi Iwai if (spec->powerdown_adcs) {
438236c9db7aSTakashi Iwai for (i = 0; i < spec->gen.num_all_adcs; i++) {
438336c9db7aSTakashi Iwai if (spec->active_adcs & (1 << i))
438436c9db7aSTakashi Iwai continue;
438536c9db7aSTakashi Iwai snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0,
438636c9db7aSTakashi Iwai AC_VERB_SET_POWER_STATE,
438736c9db7aSTakashi Iwai AC_PWRST_D3);
438836c9db7aSTakashi Iwai }
438936c9db7aSTakashi Iwai }
439036c9db7aSTakashi Iwai
4391c7d4b2faSMatt return 0;
4392c7d4b2faSMatt }
4393c7d4b2faSMatt
43947504b6cdSTakashi Iwai #define stac_free snd_hda_gen_free
43952f2f4251SMatt
4396cd6a6503SJie Yang #ifdef CONFIG_SND_PROC_FS
stac92hd_proc_hook(struct snd_info_buffer * buffer,struct hda_codec * codec,hda_nid_t nid)43972d34e1b3STakashi Iwai static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
43982d34e1b3STakashi Iwai struct hda_codec *codec, hda_nid_t nid)
43992d34e1b3STakashi Iwai {
44007639a06cSTakashi Iwai if (nid == codec->core.afg)
44012d34e1b3STakashi Iwai snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4402c882246dSTakashi Iwai snd_hda_codec_read(codec, nid, 0,
4403c882246dSTakashi Iwai AC_VERB_IDT_GET_POWER_MAP, 0));
44042d34e1b3STakashi Iwai }
44052d34e1b3STakashi Iwai
analog_loop_proc_hook(struct snd_info_buffer * buffer,struct hda_codec * codec,unsigned int verb)44062d34e1b3STakashi Iwai static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
44072d34e1b3STakashi Iwai struct hda_codec *codec,
44082d34e1b3STakashi Iwai unsigned int verb)
44092d34e1b3STakashi Iwai {
44102d34e1b3STakashi Iwai snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
44117639a06cSTakashi Iwai snd_hda_codec_read(codec, codec->core.afg, 0, verb, 0));
44122d34e1b3STakashi Iwai }
44132d34e1b3STakashi Iwai
44142d34e1b3STakashi Iwai /* stac92hd71bxx, stac92hd73xx */
stac92hd7x_proc_hook(struct snd_info_buffer * buffer,struct hda_codec * codec,hda_nid_t nid)44152d34e1b3STakashi Iwai static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
44162d34e1b3STakashi Iwai struct hda_codec *codec, hda_nid_t nid)
44172d34e1b3STakashi Iwai {
44182d34e1b3STakashi Iwai stac92hd_proc_hook(buffer, codec, nid);
44197639a06cSTakashi Iwai if (nid == codec->core.afg)
44202d34e1b3STakashi Iwai analog_loop_proc_hook(buffer, codec, 0xfa0);
44212d34e1b3STakashi Iwai }
44222d34e1b3STakashi Iwai
stac9205_proc_hook(struct snd_info_buffer * buffer,struct hda_codec * codec,hda_nid_t nid)44232d34e1b3STakashi Iwai static void stac9205_proc_hook(struct snd_info_buffer *buffer,
44242d34e1b3STakashi Iwai struct hda_codec *codec, hda_nid_t nid)
44252d34e1b3STakashi Iwai {
44267639a06cSTakashi Iwai if (nid == codec->core.afg)
44272d34e1b3STakashi Iwai analog_loop_proc_hook(buffer, codec, 0xfe0);
44282d34e1b3STakashi Iwai }
44292d34e1b3STakashi Iwai
stac927x_proc_hook(struct snd_info_buffer * buffer,struct hda_codec * codec,hda_nid_t nid)44302d34e1b3STakashi Iwai static void stac927x_proc_hook(struct snd_info_buffer *buffer,
44312d34e1b3STakashi Iwai struct hda_codec *codec, hda_nid_t nid)
44322d34e1b3STakashi Iwai {
44337639a06cSTakashi Iwai if (nid == codec->core.afg)
44342d34e1b3STakashi Iwai analog_loop_proc_hook(buffer, codec, 0xfeb);
44352d34e1b3STakashi Iwai }
44362d34e1b3STakashi Iwai #else
44372d34e1b3STakashi Iwai #define stac92hd_proc_hook NULL
44382d34e1b3STakashi Iwai #define stac92hd7x_proc_hook NULL
44392d34e1b3STakashi Iwai #define stac9205_proc_hook NULL
44402d34e1b3STakashi Iwai #define stac927x_proc_hook NULL
44412d34e1b3STakashi Iwai #endif
44422d34e1b3STakashi Iwai
stac_suspend(struct hda_codec * codec)444336c9db7aSTakashi Iwai static int stac_suspend(struct hda_codec *codec)
444445eebda7SVitaliy Kulikov {
4445f8b32a6dSNathan Chancellor struct sigmatel_spec *spec = codec->spec;
4446f8b32a6dSNathan Chancellor
4447f8b32a6dSNathan Chancellor snd_hda_shutup_pins(codec);
4448f8b32a6dSNathan Chancellor
4449f8b32a6dSNathan Chancellor if (spec->eapd_mask)
4450f8b32a6dSNathan Chancellor stac_gpio_set(codec, spec->gpio_mask,
4451f8b32a6dSNathan Chancellor spec->gpio_dir, spec->gpio_data &
4452f8b32a6dSNathan Chancellor ~spec->eapd_mask);
4453f8b32a6dSNathan Chancellor
445445eebda7SVitaliy Kulikov return 0;
445545eebda7SVitaliy Kulikov }
445645eebda7SVitaliy Kulikov
445736c9db7aSTakashi Iwai static const struct hda_codec_ops stac_patch_ops = {
4458aa699c49STakashi Iwai .build_controls = snd_hda_gen_build_controls,
445936c9db7aSTakashi Iwai .build_pcms = snd_hda_gen_build_pcms,
446036c9db7aSTakashi Iwai .init = stac_init,
446136c9db7aSTakashi Iwai .free = stac_free,
446229adc4b9SDavid Henningsson .unsol_event = snd_hda_jack_unsol_event,
446336c9db7aSTakashi Iwai .suspend = stac_suspend,
44642f2f4251SMatt };
44652f2f4251SMatt
alloc_stac_spec(struct hda_codec * codec)446636c9db7aSTakashi Iwai static int alloc_stac_spec(struct hda_codec *codec)
4467361dab3eSTakashi Iwai {
4468361dab3eSTakashi Iwai struct sigmatel_spec *spec;
4469361dab3eSTakashi Iwai
4470361dab3eSTakashi Iwai spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4471361dab3eSTakashi Iwai if (!spec)
4472361dab3eSTakashi Iwai return -ENOMEM;
447336c9db7aSTakashi Iwai snd_hda_gen_spec_init(&spec->gen);
4474361dab3eSTakashi Iwai codec->spec = spec;
4475361dab3eSTakashi Iwai codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
4476d89c6c0cSTakashi Iwai spec->gen.dac_min_mute = true;
4477225068abSTakashi Iwai codec->patch_ops = stac_patch_ops;
4478361dab3eSTakashi Iwai return 0;
4479361dab3eSTakashi Iwai }
4480361dab3eSTakashi Iwai
patch_stac9200(struct hda_codec * codec)44812f2f4251SMatt static int patch_stac9200(struct hda_codec *codec)
44822f2f4251SMatt {
44832f2f4251SMatt struct sigmatel_spec *spec;
4484c7d4b2faSMatt int err;
44852f2f4251SMatt
448636c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4487361dab3eSTakashi Iwai if (err < 0)
4488361dab3eSTakashi Iwai return err;
44892f2f4251SMatt
4490361dab3eSTakashi Iwai spec = codec->spec;
44911b0e372dSDaniel J Blueman spec->linear_tone_beep = 1;
449236c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
449336c9db7aSTakashi Iwai
4494ba615b86STakashi Iwai codec->power_filter = snd_hda_codec_eapd_power_filter;
449536c9db7aSTakashi Iwai
449636c9db7aSTakashi Iwai snd_hda_add_verbs(codec, stac9200_eapd_init);
4497d39a3ae8STakashi Iwai
4498d39a3ae8STakashi Iwai snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
4499d39a3ae8STakashi Iwai stac9200_fixups);
4500d39a3ae8STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4501117f257dSTakashi Iwai
450236c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
4503c7d4b2faSMatt if (err < 0) {
450436c9db7aSTakashi Iwai stac_free(codec);
4505c7d4b2faSMatt return err;
4506c7d4b2faSMatt }
45072f2f4251SMatt
4508d39a3ae8STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4509d39a3ae8STakashi Iwai
45102f2f4251SMatt return 0;
45112f2f4251SMatt }
45122f2f4251SMatt
patch_stac925x(struct hda_codec * codec)45138e21c34cSTobin Davis static int patch_stac925x(struct hda_codec *codec)
45148e21c34cSTobin Davis {
45158e21c34cSTobin Davis struct sigmatel_spec *spec;
45168e21c34cSTobin Davis int err;
45178e21c34cSTobin Davis
451836c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4519361dab3eSTakashi Iwai if (err < 0)
4520361dab3eSTakashi Iwai return err;
45218e21c34cSTobin Davis
4522361dab3eSTakashi Iwai spec = codec->spec;
45231b0e372dSDaniel J Blueman spec->linear_tone_beep = 1;
452436c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
452536c9db7aSTakashi Iwai
452636c9db7aSTakashi Iwai snd_hda_add_verbs(codec, stac925x_core_init);
45279cb36c2aSMauro Carvalho Chehab
4528d2077d40STakashi Iwai snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
4529d2077d40STakashi Iwai stac925x_fixups);
4530d2077d40STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4531d2077d40STakashi Iwai
453236c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
45338e21c34cSTobin Davis if (err < 0) {
453436c9db7aSTakashi Iwai stac_free(codec);
45358e21c34cSTobin Davis return err;
45368e21c34cSTobin Davis }
45378e21c34cSTobin Davis
4538d2077d40STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4539d2077d40STakashi Iwai
45408e21c34cSTobin Davis return 0;
45418e21c34cSTobin Davis }
45428e21c34cSTobin Davis
patch_stac92hd73xx(struct hda_codec * codec)4543e1f0d669SMatthew Ranostay static int patch_stac92hd73xx(struct hda_codec *codec)
4544e1f0d669SMatthew Ranostay {
4545e1f0d669SMatthew Ranostay struct sigmatel_spec *spec;
4546361dab3eSTakashi Iwai int err;
4547c21ca4a8STakashi Iwai int num_dacs;
4548e1f0d669SMatthew Ranostay
454936c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4550361dab3eSTakashi Iwai if (err < 0)
4551361dab3eSTakashi Iwai return err;
4552e1f0d669SMatthew Ranostay
4553361dab3eSTakashi Iwai spec = codec->spec;
4554c7e10080STakashi Iwai /* enable power_save_node only for new 92HD89xx chips, as it causes
4555c7e10080STakashi Iwai * click noises on old 92HD73xx chips.
4556c7e10080STakashi Iwai */
4557c7e10080STakashi Iwai if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
4558967b1307STakashi Iwai codec->power_save_node = 1;
45591b0e372dSDaniel J Blueman spec->linear_tone_beep = 0;
45602748746fSTakashi Iwai spec->gen.mixer_nid = 0x1d;
456142875479STakashi Iwai spec->have_spdif_mux = 1;
456255e30141STakashi Iwai
456336c9db7aSTakashi Iwai num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1;
4564c21ca4a8STakashi Iwai if (num_dacs < 3 || num_dacs > 5) {
45654e76a883STakashi Iwai codec_warn(codec,
45664e76a883STakashi Iwai "Could not determine number of channels defaulting to DAC count\n");
456736c9db7aSTakashi Iwai num_dacs = 5;
4568e1f0d669SMatthew Ranostay }
456955e30141STakashi Iwai
4570c21ca4a8STakashi Iwai switch (num_dacs) {
4571e1f0d669SMatthew Ranostay case 0x3: /* 6 Channel */
457236c9db7aSTakashi Iwai spec->aloopback_ctl = &stac92hd73xx_6ch_loopback;
4573e1f0d669SMatthew Ranostay break;
4574e1f0d669SMatthew Ranostay case 0x4: /* 8 Channel */
457536c9db7aSTakashi Iwai spec->aloopback_ctl = &stac92hd73xx_8ch_loopback;
4576e1f0d669SMatthew Ranostay break;
4577e1f0d669SMatthew Ranostay case 0x5: /* 10 Channel */
457836c9db7aSTakashi Iwai spec->aloopback_ctl = &stac92hd73xx_10ch_loopback;
4579d78d7a90STakashi Iwai break;
4580c21ca4a8STakashi Iwai }
4581e1f0d669SMatthew Ranostay
4582e1f0d669SMatthew Ranostay spec->aloopback_mask = 0x01;
4583e1f0d669SMatthew Ranostay spec->aloopback_shift = 8;
4584e1f0d669SMatthew Ranostay
45857504b6cdSTakashi Iwai spec->gen.beep_nid = 0x1c; /* digital beep */
45866479c631STakashi Iwai
4587b2c4f4d7SMatthew Ranostay /* GPIO0 High = Enable EAPD */
4588b2c4f4d7SMatthew Ranostay spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4589b2c4f4d7SMatthew Ranostay spec->gpio_data = 0x01;
459055e30141STakashi Iwai
459155e30141STakashi Iwai spec->eapd_switch = 1;
4592a7662640SMatthew Ranostay
4593a64135a2SMatthew Ranostay spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
4594a64135a2SMatthew Ranostay spec->pwr_nids = stac92hd73xx_pwr_nids;
4595a64135a2SMatthew Ranostay
459636c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
4597f4f678d2STakashi Iwai spec->gen.power_down_unused = 1;
459836c9db7aSTakashi Iwai
459936c9db7aSTakashi Iwai snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
460036c9db7aSTakashi Iwai stac92hd73xx_fixups);
460155e30141STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
460255e30141STakashi Iwai
460355e30141STakashi Iwai if (!spec->volknob_init)
460455e30141STakashi Iwai snd_hda_add_verbs(codec, stac92hd73xx_core_init);
460555e30141STakashi Iwai
460636c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
4607e1f0d669SMatthew Ranostay if (err < 0) {
460836c9db7aSTakashi Iwai stac_free(codec);
4609e1f0d669SMatthew Ranostay return err;
4610e1f0d669SMatthew Ranostay }
4611e1f0d669SMatthew Ranostay
4612303985f8SDavid Henningsson /* Don't GPIO-mute speakers if there are no internal speakers, because
4613303985f8SDavid Henningsson * the GPIO might be necessary for Headphone
4614303985f8SDavid Henningsson */
4615303985f8SDavid Henningsson if (spec->eapd_switch && !has_builtin_speaker(codec))
4616303985f8SDavid Henningsson spec->eapd_switch = 0;
4617303985f8SDavid Henningsson
46182d34e1b3STakashi Iwai codec->proc_widget_hook = stac92hd7x_proc_hook;
46192d34e1b3STakashi Iwai
462055e30141STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
462155e30141STakashi Iwai
4622e1f0d669SMatthew Ranostay return 0;
4623e1f0d669SMatthew Ranostay }
4624e1f0d669SMatthew Ranostay
stac_setup_gpio(struct hda_codec * codec)4625372f8c75STakashi Iwai static void stac_setup_gpio(struct hda_codec *codec)
4626d0513fc6SMatthew Ranostay {
4627372f8c75STakashi Iwai struct sigmatel_spec *spec = codec->spec;
4628e108c7b7SVitaliy Kulikov
46291ea9a69dSTakashi Iwai spec->gpio_mask |= spec->eapd_mask;
4630b4e81876STakashi Iwai if (spec->gpio_led) {
4631f1a73746STakashi Iwai if (!spec->vref_mute_led_nid) {
4632b4e81876STakashi Iwai spec->gpio_mask |= spec->gpio_led;
4633b4e81876STakashi Iwai spec->gpio_dir |= spec->gpio_led;
4634b4e81876STakashi Iwai spec->gpio_data |= spec->gpio_led;
463545eebda7SVitaliy Kulikov } else {
4636dfc6e469STakashi Iwai codec->power_filter = stac_vref_led_power_filter;
463745eebda7SVitaliy Kulikov }
4638b4e81876STakashi Iwai }
4639b4e81876STakashi Iwai
464062cbde18STakashi Iwai if (spec->mic_mute_led_gpio) {
464162cbde18STakashi Iwai spec->gpio_mask |= spec->mic_mute_led_gpio;
464262cbde18STakashi Iwai spec->gpio_dir |= spec->mic_mute_led_gpio;
46437fe30711STakashi Iwai spec->mic_enabled = 0;
464462cbde18STakashi Iwai spec->gpio_data |= spec->mic_mute_led_gpio;
464523a2b469STakashi Iwai snd_hda_gen_add_micmute_led_cdev(codec, stac_capture_led_update);
464662cbde18STakashi Iwai }
4647372f8c75STakashi Iwai }
4648372f8c75STakashi Iwai
patch_stac92hd83xxx(struct hda_codec * codec)4649372f8c75STakashi Iwai static int patch_stac92hd83xxx(struct hda_codec *codec)
4650372f8c75STakashi Iwai {
4651372f8c75STakashi Iwai struct sigmatel_spec *spec;
4652372f8c75STakashi Iwai int err;
4653372f8c75STakashi Iwai
465436c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4655372f8c75STakashi Iwai if (err < 0)
4656372f8c75STakashi Iwai return err;
4657372f8c75STakashi Iwai
46587639a06cSTakashi Iwai /* longer delay needed for D3 */
46597639a06cSTakashi Iwai codec->core.power_caps &= ~AC_PWRST_EPSS;
4660372f8c75STakashi Iwai
4661372f8c75STakashi Iwai spec = codec->spec;
4662967b1307STakashi Iwai codec->power_save_node = 1;
4663372f8c75STakashi Iwai spec->linear_tone_beep = 0;
466436c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
4665f4f678d2STakashi Iwai spec->gen.power_down_unused = 1;
46662748746fSTakashi Iwai spec->gen.mixer_nid = 0x1b;
466736c9db7aSTakashi Iwai
46687504b6cdSTakashi Iwai spec->gen.beep_nid = 0x21; /* digital beep */
4669372f8c75STakashi Iwai spec->pwr_nids = stac92hd83xxx_pwr_nids;
4670372f8c75STakashi Iwai spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
467136c9db7aSTakashi Iwai spec->default_polarity = -1; /* no default cfg */
467236c9db7aSTakashi Iwai
467336c9db7aSTakashi Iwai snd_hda_add_verbs(codec, stac92hd83xxx_core_init);
4674372f8c75STakashi Iwai
4675372f8c75STakashi Iwai snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl,
4676372f8c75STakashi Iwai stac92hd83xxx_fixups);
4677372f8c75STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4678372f8c75STakashi Iwai
4679372f8c75STakashi Iwai stac_setup_gpio(codec);
468062cbde18STakashi Iwai
468136c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
4682d0513fc6SMatthew Ranostay if (err < 0) {
468336c9db7aSTakashi Iwai stac_free(codec);
4684d0513fc6SMatthew Ranostay return err;
4685d0513fc6SMatthew Ranostay }
4686d0513fc6SMatthew Ranostay
46872d34e1b3STakashi Iwai codec->proc_widget_hook = stac92hd_proc_hook;
46882d34e1b3STakashi Iwai
4689372f8c75STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4690372f8c75STakashi Iwai
4691d0513fc6SMatthew Ranostay return 0;
4692d0513fc6SMatthew Ranostay }
4693d0513fc6SMatthew Ranostay
46944e637c6eSVitaliy Kulikov static const hda_nid_t stac92hd95_pwr_nids[] = {
46954e637c6eSVitaliy Kulikov 0x0a, 0x0b, 0x0c, 0x0d
46964e637c6eSVitaliy Kulikov };
46974e637c6eSVitaliy Kulikov
patch_stac92hd95(struct hda_codec * codec)46984e637c6eSVitaliy Kulikov static int patch_stac92hd95(struct hda_codec *codec)
46994e637c6eSVitaliy Kulikov {
47004e637c6eSVitaliy Kulikov struct sigmatel_spec *spec;
47014e637c6eSVitaliy Kulikov int err;
47024e637c6eSVitaliy Kulikov
47034e637c6eSVitaliy Kulikov err = alloc_stac_spec(codec);
47044e637c6eSVitaliy Kulikov if (err < 0)
47054e637c6eSVitaliy Kulikov return err;
47064e637c6eSVitaliy Kulikov
47077639a06cSTakashi Iwai /* longer delay needed for D3 */
47087639a06cSTakashi Iwai codec->core.power_caps &= ~AC_PWRST_EPSS;
47094e637c6eSVitaliy Kulikov
47104e637c6eSVitaliy Kulikov spec = codec->spec;
4711967b1307STakashi Iwai codec->power_save_node = 1;
47124e637c6eSVitaliy Kulikov spec->linear_tone_beep = 0;
47134e637c6eSVitaliy Kulikov spec->gen.own_eapd_ctl = 1;
47144e637c6eSVitaliy Kulikov spec->gen.power_down_unused = 1;
47154e637c6eSVitaliy Kulikov
47167504b6cdSTakashi Iwai spec->gen.beep_nid = 0x19; /* digital beep */
47174e637c6eSVitaliy Kulikov spec->pwr_nids = stac92hd95_pwr_nids;
47184e637c6eSVitaliy Kulikov spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
47198b3dfdafSTakashi Iwai spec->default_polarity = 0;
47204e637c6eSVitaliy Kulikov
47218b3dfdafSTakashi Iwai snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl,
47228b3dfdafSTakashi Iwai stac92hd95_fixups);
47238b3dfdafSTakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
47248b3dfdafSTakashi Iwai
47258b3dfdafSTakashi Iwai stac_setup_gpio(codec);
47268b3dfdafSTakashi Iwai
47274e637c6eSVitaliy Kulikov err = stac_parse_auto_config(codec);
47284e637c6eSVitaliy Kulikov if (err < 0) {
47294e637c6eSVitaliy Kulikov stac_free(codec);
47304e637c6eSVitaliy Kulikov return err;
47314e637c6eSVitaliy Kulikov }
47324e637c6eSVitaliy Kulikov
47334e637c6eSVitaliy Kulikov codec->proc_widget_hook = stac92hd_proc_hook;
47344e637c6eSVitaliy Kulikov
47358b3dfdafSTakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
47368b3dfdafSTakashi Iwai
47374e637c6eSVitaliy Kulikov return 0;
47384e637c6eSVitaliy Kulikov }
47394e637c6eSVitaliy Kulikov
patch_stac92hd71bxx(struct hda_codec * codec)4740e035b841SMatthew Ranostay static int patch_stac92hd71bxx(struct hda_codec *codec)
4741e035b841SMatthew Ranostay {
4742e035b841SMatthew Ranostay struct sigmatel_spec *spec;
4743a551d914STakashi Iwai const hda_nid_t *unmute_nids = stac92hd71bxx_unmute_nids;
4744361dab3eSTakashi Iwai int err;
4745e035b841SMatthew Ranostay
474636c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4747361dab3eSTakashi Iwai if (err < 0)
4748361dab3eSTakashi Iwai return err;
4749e035b841SMatthew Ranostay
4750361dab3eSTakashi Iwai spec = codec->spec;
4751c545f799STakashi Iwai /* disabled power_save_node since it causes noises on a Dell machine */
4752c545f799STakashi Iwai /* codec->power_save_node = 1; */
47531b0e372dSDaniel J Blueman spec->linear_tone_beep = 0;
475436c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
4755f4f678d2STakashi Iwai spec->gen.power_down_unused = 1;
47562748746fSTakashi Iwai spec->gen.mixer_nid = 0x17;
475742875479STakashi Iwai spec->have_spdif_mux = 1;
4758e035b841SMatthew Ranostay
475941c3b648STakashi Iwai /* GPIO0 = EAPD */
476041c3b648STakashi Iwai spec->gpio_mask = 0x01;
476141c3b648STakashi Iwai spec->gpio_dir = 0x01;
476241c3b648STakashi Iwai spec->gpio_data = 0x01;
476341c3b648STakashi Iwai
47647639a06cSTakashi Iwai switch (codec->core.vendor_id) {
4765541eee87SMatthew Ranostay case 0x111d76b6: /* 4 Port without Analog Mixer */
4766541eee87SMatthew Ranostay case 0x111d76b7:
4767a551d914STakashi Iwai unmute_nids++;
4768541eee87SMatthew Ranostay break;
4769aafc4412SMatthew Ranostay case 0x111d7608: /* 5 Port with Analog Mixer */
47707639a06cSTakashi Iwai if ((codec->core.revision_id & 0xf) == 0 ||
47717639a06cSTakashi Iwai (codec->core.revision_id & 0xf) == 1)
47728daaaa97SMatthew Ranostay spec->stream_delay = 40; /* 40 milliseconds */
47738daaaa97SMatthew Ranostay
4774aafc4412SMatthew Ranostay /* disable VSW */
4775a551d914STakashi Iwai unmute_nids++;
4776330ee995STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
4777330ee995STakashi Iwai snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
4778aafc4412SMatthew Ranostay break;
4779aafc4412SMatthew Ranostay case 0x111d7603: /* 6 Port with Analog Mixer */
47807639a06cSTakashi Iwai if ((codec->core.revision_id & 0xf) == 1)
47818daaaa97SMatthew Ranostay spec->stream_delay = 40; /* 40 milliseconds */
47828daaaa97SMatthew Ranostay
47835207e10eSTakashi Iwai break;
478444179323STakashi Iwai }
4785541eee87SMatthew Ranostay
47865e68fb3cSDavid Henningsson if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
47870f6fcb73STakashi Iwai snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
47885e68fb3cSDavid Henningsson
4789a551d914STakashi Iwai if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) {
4790a551d914STakashi Iwai const hda_nid_t *p;
4791a551d914STakashi Iwai for (p = unmute_nids; *p; p++)
4792a551d914STakashi Iwai snd_hda_codec_amp_init_stereo(codec, *p, HDA_INPUT, 0,
4793a551d914STakashi Iwai 0xff, 0x00);
4794a551d914STakashi Iwai }
4795ca8d33fcSMatthew Ranostay
479636c9db7aSTakashi Iwai spec->aloopback_ctl = &stac92hd71bxx_loopback;
47974b33c767SMatthew Ranostay spec->aloopback_mask = 0x50;
4798541eee87SMatthew Ranostay spec->aloopback_shift = 0;
4799541eee87SMatthew Ranostay
48008daaaa97SMatthew Ranostay spec->powerdown_adcs = 1;
48017504b6cdSTakashi Iwai spec->gen.beep_nid = 0x26; /* digital beep */
480236c9db7aSTakashi Iwai spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
4803aafc4412SMatthew Ranostay spec->pwr_nids = stac92hd71bxx_pwr_nids;
4804e035b841SMatthew Ranostay
480536c9db7aSTakashi Iwai snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
480636c9db7aSTakashi Iwai stac92hd71bxx_fixups);
48070f6fcb73STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
48085bdaaadaSVitaliy Kulikov
4809372f8c75STakashi Iwai stac_setup_gpio(codec);
4810e035b841SMatthew Ranostay
481136c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
4812e035b841SMatthew Ranostay if (err < 0) {
481336c9db7aSTakashi Iwai stac_free(codec);
4814e035b841SMatthew Ranostay return err;
4815e035b841SMatthew Ranostay }
4816e035b841SMatthew Ranostay
48172d34e1b3STakashi Iwai codec->proc_widget_hook = stac92hd7x_proc_hook;
48182d34e1b3STakashi Iwai
48190f6fcb73STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
48200f6fcb73STakashi Iwai
4821e035b841SMatthew Ranostay return 0;
482286d190e7STakashi Iwai }
4823e035b841SMatthew Ranostay
patch_stac922x(struct hda_codec * codec)48242f2f4251SMatt static int patch_stac922x(struct hda_codec *codec)
48252f2f4251SMatt {
48262f2f4251SMatt struct sigmatel_spec *spec;
4827c7d4b2faSMatt int err;
48282f2f4251SMatt
482936c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4830361dab3eSTakashi Iwai if (err < 0)
4831361dab3eSTakashi Iwai return err;
48322f2f4251SMatt
4833361dab3eSTakashi Iwai spec = codec->spec;
48341b0e372dSDaniel J Blueman spec->linear_tone_beep = 1;
483536c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
48365d5d3bc3SIvan N. Zlatev
48370a427846STakashi Iwai snd_hda_add_verbs(codec, stac922x_core_init);
48380a427846STakashi Iwai
4839807a4636STakashi Iwai /* Fix Mux capture level; max to 2 */
4840807a4636STakashi Iwai snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
4841807a4636STakashi Iwai (0 << AC_AMPCAP_OFFSET_SHIFT) |
4842807a4636STakashi Iwai (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4843807a4636STakashi Iwai (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4844807a4636STakashi Iwai (0 << AC_AMPCAP_MUTE_SHIFT));
4845807a4636STakashi Iwai
484636c9db7aSTakashi Iwai snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
484736c9db7aSTakashi Iwai stac922x_fixups);
484836c9db7aSTakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
484936c9db7aSTakashi Iwai
485036c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
485136c9db7aSTakashi Iwai if (err < 0) {
485236c9db7aSTakashi Iwai stac_free(codec);
485336c9db7aSTakashi Iwai return err;
485436c9db7aSTakashi Iwai }
485536c9db7aSTakashi Iwai
48560a427846STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
48570a427846STakashi Iwai
48583cc08dc6SMatt Porter return 0;
48593cc08dc6SMatt Porter }
48603cc08dc6SMatt Porter
486142875479STakashi Iwai static const char * const stac927x_spdif_labels[] = {
486242875479STakashi Iwai "Digital Playback", "ADAT", "Analog Mux 1",
486342875479STakashi Iwai "Analog Mux 2", "Analog Mux 3", NULL
486442875479STakashi Iwai };
486542875479STakashi Iwai
patch_stac927x(struct hda_codec * codec)48663cc08dc6SMatt Porter static int patch_stac927x(struct hda_codec *codec)
48673cc08dc6SMatt Porter {
48683cc08dc6SMatt Porter struct sigmatel_spec *spec;
48693cc08dc6SMatt Porter int err;
48703cc08dc6SMatt Porter
487136c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4872361dab3eSTakashi Iwai if (err < 0)
4873361dab3eSTakashi Iwai return err;
48743cc08dc6SMatt Porter
4875361dab3eSTakashi Iwai spec = codec->spec;
48761b0e372dSDaniel J Blueman spec->linear_tone_beep = 1;
487736c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
487842875479STakashi Iwai spec->have_spdif_mux = 1;
487942875479STakashi Iwai spec->spdif_labels = stac927x_spdif_labels;
48803cc08dc6SMatt Porter
48817504b6cdSTakashi Iwai spec->gen.beep_nid = 0x23; /* digital beep */
48828e9068b1SMatthew Ranostay
4883af6ee302STakashi Iwai /* GPIO0 High = Enable EAPD */
4884af6ee302STakashi Iwai spec->eapd_mask = spec->gpio_mask = 0x01;
4885af6ee302STakashi Iwai spec->gpio_dir = spec->gpio_data = 0x01;
4886af6ee302STakashi Iwai
488736c9db7aSTakashi Iwai spec->aloopback_ctl = &stac927x_loopback;
4888e1f0d669SMatthew Ranostay spec->aloopback_mask = 0x40;
4889e1f0d669SMatthew Ranostay spec->aloopback_shift = 0;
4890c0cea0d0SMatthew Ranostay spec->eapd_switch = 1;
48913cc08dc6SMatt Porter
489236c9db7aSTakashi Iwai snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
489336c9db7aSTakashi Iwai stac927x_fixups);
4894f6655d52STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4895f6655d52STakashi Iwai
489629ac8363STakashi Iwai if (!spec->volknob_init)
489729ac8363STakashi Iwai snd_hda_add_verbs(codec, stac927x_core_init);
489829ac8363STakashi Iwai
489936c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
4900c7d4b2faSMatt if (err < 0) {
490136c9db7aSTakashi Iwai stac_free(codec);
4902c7d4b2faSMatt return err;
4903c7d4b2faSMatt }
49042f2f4251SMatt
49052d34e1b3STakashi Iwai codec->proc_widget_hook = stac927x_proc_hook;
49062d34e1b3STakashi Iwai
490752987656STakashi Iwai /*
490852987656STakashi Iwai * !!FIXME!!
490952987656STakashi Iwai * The STAC927x seem to require fairly long delays for certain
491052987656STakashi Iwai * command sequences. With too short delays (even if the answer
491152987656STakashi Iwai * is set to RIRB properly), it results in the silence output
491252987656STakashi Iwai * on some hardwares like Dell.
491352987656STakashi Iwai *
491452987656STakashi Iwai * The below flag enables the longer delay (see get_response
491552987656STakashi Iwai * in hda_intel.c).
491652987656STakashi Iwai */
49175f2cb361STakashi Iwai codec->bus->core.needs_damn_long_delay = 1;
491852987656STakashi Iwai
491929ac8363STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4920e28d8322STakashi Iwai
49212f2f4251SMatt return 0;
49222f2f4251SMatt }
49232f2f4251SMatt
patch_stac9205(struct hda_codec * codec)4924f3302a59SMatt Porter static int patch_stac9205(struct hda_codec *codec)
4925f3302a59SMatt Porter {
4926f3302a59SMatt Porter struct sigmatel_spec *spec;
49278259980eSTakashi Iwai int err;
4928f3302a59SMatt Porter
492936c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
4930361dab3eSTakashi Iwai if (err < 0)
4931361dab3eSTakashi Iwai return err;
4932f3302a59SMatt Porter
4933361dab3eSTakashi Iwai spec = codec->spec;
49341b0e372dSDaniel J Blueman spec->linear_tone_beep = 1;
493536c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
493642875479STakashi Iwai spec->have_spdif_mux = 1;
4937f3302a59SMatt Porter
49387504b6cdSTakashi Iwai spec->gen.beep_nid = 0x23; /* digital beep */
4939f3302a59SMatt Porter
4940fe6322caSTakashi Iwai snd_hda_add_verbs(codec, stac9205_core_init);
494136c9db7aSTakashi Iwai spec->aloopback_ctl = &stac9205_loopback;
49426479c631STakashi Iwai
4943e1f0d669SMatthew Ranostay spec->aloopback_mask = 0x40;
4944e1f0d669SMatthew Ranostay spec->aloopback_shift = 0;
494533382403SMatt Porter
4946ae0a8ed8STobin Davis /* GPIO0 High = EAPD */
49470fc9dec4SMatthew Ranostay spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
49484fe5195cSMatthew Ranostay spec->gpio_data = 0x01;
4949fe6322caSTakashi Iwai
4950fe6322caSTakashi Iwai /* Turn on/off EAPD per HP plugging */
4951fe6322caSTakashi Iwai spec->eapd_switch = 1;
4952fe6322caSTakashi Iwai
495336c9db7aSTakashi Iwai snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
495436c9db7aSTakashi Iwai stac9205_fixups);
4955fe6322caSTakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
495687d48363SMatthew Ranostay
495736c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
4958f3302a59SMatt Porter if (err < 0) {
495936c9db7aSTakashi Iwai stac_free(codec);
4960f3302a59SMatt Porter return err;
4961f3302a59SMatt Porter }
4962f3302a59SMatt Porter
49632d34e1b3STakashi Iwai codec->proc_widget_hook = stac9205_proc_hook;
49642d34e1b3STakashi Iwai
4965fe6322caSTakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4966fe6322caSTakashi Iwai
4967f3302a59SMatt Porter return 0;
4968f3302a59SMatt Porter }
4969f3302a59SMatt Porter
49702f2f4251SMatt /*
49716d859065SGuillaume Munch * STAC9872 hack
4972db064e50STakashi Iwai */
4973db064e50STakashi Iwai
49742b63536fSTakashi Iwai static const struct hda_verb stac9872_core_init[] = {
49751624cb9aSTakashi Iwai {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
4976db064e50STakashi Iwai {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
4977db064e50STakashi Iwai {}
4978db064e50STakashi Iwai };
4979db064e50STakashi Iwai
4980fc268c10STakashi Iwai static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
4981fc268c10STakashi Iwai { 0x0a, 0x03211020 },
4982fc268c10STakashi Iwai { 0x0b, 0x411111f0 },
4983fc268c10STakashi Iwai { 0x0c, 0x411111f0 },
4984fc268c10STakashi Iwai { 0x0d, 0x03a15030 },
4985fc268c10STakashi Iwai { 0x0e, 0x411111f0 },
4986fc268c10STakashi Iwai { 0x0f, 0x90170110 },
4987fc268c10STakashi Iwai { 0x11, 0x411111f0 },
4988fc268c10STakashi Iwai { 0x13, 0x411111f0 },
4989fc268c10STakashi Iwai { 0x14, 0x90a7013e },
4990fc268c10STakashi Iwai {}
4991307282c8STakashi Iwai };
4992307282c8STakashi Iwai
4993fc268c10STakashi Iwai static const struct hda_model_fixup stac9872_models[] = {
4994fc268c10STakashi Iwai { .id = STAC_9872_VAIO, .name = "vaio" },
4995fc268c10STakashi Iwai {}
4996307282c8STakashi Iwai };
4997307282c8STakashi Iwai
4998fc268c10STakashi Iwai static const struct hda_fixup stac9872_fixups[] = {
4999fc268c10STakashi Iwai [STAC_9872_VAIO] = {
5000fc268c10STakashi Iwai .type = HDA_FIXUP_PINS,
5001fc268c10STakashi Iwai .v.pins = stac9872_vaio_pin_configs,
5002fc268c10STakashi Iwai },
5003307282c8STakashi Iwai };
5004307282c8STakashi Iwai
5005fc268c10STakashi Iwai static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
5006b04add95STakashi Iwai SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
5007b04add95STakashi Iwai "Sony VAIO F/S", STAC_9872_VAIO),
5008307282c8STakashi Iwai {} /* terminator */
5009307282c8STakashi Iwai };
5010307282c8STakashi Iwai
patch_stac9872(struct hda_codec * codec)50116d859065SGuillaume Munch static int patch_stac9872(struct hda_codec *codec)
5012db064e50STakashi Iwai {
5013db064e50STakashi Iwai struct sigmatel_spec *spec;
50141e137f92STakashi Iwai int err;
5015db064e50STakashi Iwai
501636c9db7aSTakashi Iwai err = alloc_stac_spec(codec);
5017361dab3eSTakashi Iwai if (err < 0)
5018361dab3eSTakashi Iwai return err;
5019361dab3eSTakashi Iwai
5020361dab3eSTakashi Iwai spec = codec->spec;
50211b0e372dSDaniel J Blueman spec->linear_tone_beep = 1;
502236c9db7aSTakashi Iwai spec->gen.own_eapd_ctl = 1;
502336c9db7aSTakashi Iwai
502436c9db7aSTakashi Iwai snd_hda_add_verbs(codec, stac9872_core_init);
5025caa10b6eSTakashi Iwai
5026fc268c10STakashi Iwai snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
5027fc268c10STakashi Iwai stac9872_fixups);
5028fc268c10STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5029caa10b6eSTakashi Iwai
503036c9db7aSTakashi Iwai err = stac_parse_auto_config(codec);
5031caa10b6eSTakashi Iwai if (err < 0) {
503236c9db7aSTakashi Iwai stac_free(codec);
5033caa10b6eSTakashi Iwai return -EINVAL;
5034caa10b6eSTakashi Iwai }
5035fc268c10STakashi Iwai
5036fc268c10STakashi Iwai snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5037fc268c10STakashi Iwai
5038caa10b6eSTakashi Iwai return 0;
5039caa10b6eSTakashi Iwai }
5040caa10b6eSTakashi Iwai
5041db064e50STakashi Iwai
5042db064e50STakashi Iwai /*
50432f2f4251SMatt * patch entries
50442f2f4251SMatt */
5045b9a94a9cSTakashi Iwai static const struct hda_device_id snd_hda_id_sigmatel[] = {
5046b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847690, "STAC9200", patch_stac9200),
5047b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847882, "STAC9220 A1", patch_stac922x),
5048b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847680, "STAC9221 A1", patch_stac922x),
5049b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847880, "STAC9220 A2", patch_stac922x),
5050b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847681, "STAC9220D/9223D A2", patch_stac922x),
5051b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847682, "STAC9221 A2", patch_stac922x),
5052b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
5053b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
5054b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
5055078502b5SDarren Stevens HDA_CODEC_ENTRY(0x83847638, "STAC92HD700", patch_stac927x),
5056b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
5057b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
5058b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
5059b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847615, "STAC9229", patch_stac927x),
5060b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847620, "STAC9274", patch_stac927x),
5061b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847621, "STAC9274D", patch_stac927x),
5062b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847622, "STAC9273X", patch_stac927x),
5063b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847623, "STAC9273D", patch_stac927x),
5064b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847624, "STAC9272X", patch_stac927x),
5065b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847625, "STAC9272D", patch_stac927x),
5066b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847626, "STAC9271X", patch_stac927x),
5067b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847627, "STAC9271D", patch_stac927x),
5068b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847628, "STAC9274X5NH", patch_stac927x),
5069b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847629, "STAC9274D5NH", patch_stac927x),
5070b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847632, "STAC9202", patch_stac925x),
5071b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847633, "STAC9202D", patch_stac925x),
5072b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847634, "STAC9250", patch_stac925x),
5073b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847635, "STAC9250D", patch_stac925x),
5074b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847636, "STAC9251", patch_stac925x),
5075b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847637, "STAC9250D", patch_stac925x),
5076b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847645, "92HD206X", patch_stac927x),
5077b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847646, "92HD206D", patch_stac927x),
50786d859065SGuillaume Munch /* The following does not take into account .id=0x83847661 when subsys =
50796d859065SGuillaume Munch * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
50806d859065SGuillaume Munch * currently not fully supported.
50816d859065SGuillaume Munch */
5082b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847661, "CXD9872RD/K", patch_stac9872),
5083b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847662, "STAC9872AK", patch_stac9872),
5084b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847664, "CXD9872AKD", patch_stac9872),
5085b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x83847698, "STAC9205", patch_stac9205),
5086b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a0, "STAC9205", patch_stac9205),
5087b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a1, "STAC9205D", patch_stac9205),
5088b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a2, "STAC9204", patch_stac9205),
5089b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a3, "STAC9204D", patch_stac9205),
5090b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a4, "STAC9255", patch_stac9205),
5091b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a5, "STAC9255D", patch_stac9205),
5092b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a6, "STAC9254", patch_stac9205),
5093b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x838476a7, "STAC9254D", patch_stac9205),
5094b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7603, "92HD75B3X5", patch_stac92hd71bxx),
5095b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7604, "92HD83C1X5", patch_stac92hd83xxx),
5096b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76d4, "92HD83C1C5", patch_stac92hd83xxx),
5097b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7605, "92HD81B1X5", patch_stac92hd83xxx),
5098b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76d5, "92HD81B1C5", patch_stac92hd83xxx),
5099b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76d1, "92HD87B1/3", patch_stac92hd83xxx),
5100b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76d9, "92HD87B2/4", patch_stac92hd83xxx),
5101b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7666, "92HD88B3", patch_stac92hd83xxx),
5102b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7667, "92HD88B1", patch_stac92hd83xxx),
5103b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7668, "92HD88B2", patch_stac92hd83xxx),
5104b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7669, "92HD88B4", patch_stac92hd83xxx),
5105b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7608, "92HD75B2X5", patch_stac92hd71bxx),
5106b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7674, "92HD73D1X5", patch_stac92hd73xx),
5107b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7675, "92HD73C1X5", patch_stac92hd73xx),
5108b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7676, "92HD73E1X5", patch_stac92hd73xx),
5109b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d7695, "92HD95", patch_stac92hd95),
5110b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b0, "92HD71B8X", patch_stac92hd71bxx),
5111b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b1, "92HD71B8X", patch_stac92hd71bxx),
5112b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b2, "92HD71B7X", patch_stac92hd71bxx),
5113b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b3, "92HD71B7X", patch_stac92hd71bxx),
5114b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b4, "92HD71B6X", patch_stac92hd71bxx),
5115b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b5, "92HD71B6X", patch_stac92hd71bxx),
5116b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b6, "92HD71B5X", patch_stac92hd71bxx),
5117b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76b7, "92HD71B5X", patch_stac92hd71bxx),
5118b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c0, "92HD89C3", patch_stac92hd73xx),
5119b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c1, "92HD89C2", patch_stac92hd73xx),
5120b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c2, "92HD89C1", patch_stac92hd73xx),
5121b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c3, "92HD89B3", patch_stac92hd73xx),
5122b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c4, "92HD89B2", patch_stac92hd73xx),
5123b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c5, "92HD89B1", patch_stac92hd73xx),
5124b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c6, "92HD89E3", patch_stac92hd73xx),
5125b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c7, "92HD89E2", patch_stac92hd73xx),
5126b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c8, "92HD89E1", patch_stac92hd73xx),
5127b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76c9, "92HD89D3", patch_stac92hd73xx),
5128b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ca, "92HD89D2", patch_stac92hd73xx),
5129b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76cb, "92HD89D1", patch_stac92hd73xx),
5130b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76cc, "92HD89F3", patch_stac92hd73xx),
5131b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76cd, "92HD89F2", patch_stac92hd73xx),
5132b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ce, "92HD89F1", patch_stac92hd73xx),
5133b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76df, "92HD93BXX", patch_stac92hd83xxx),
5134b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76e0, "92HD91BXX", patch_stac92hd83xxx),
5135b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76e3, "92HD98BXX", patch_stac92hd83xxx),
5136b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76e5, "92HD99BXX", patch_stac92hd83xxx),
5137b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76e7, "92HD90BXX", patch_stac92hd83xxx),
5138b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76e8, "92HD66B1X5", patch_stac92hd83xxx),
5139b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76e9, "92HD66B2X5", patch_stac92hd83xxx),
5140b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ea, "92HD66B3X5", patch_stac92hd83xxx),
5141b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76eb, "92HD66C1X5", patch_stac92hd83xxx),
5142b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ec, "92HD66C2X5", patch_stac92hd83xxx),
5143b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ed, "92HD66C3X5", patch_stac92hd83xxx),
5144b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ee, "92HD66B1X3", patch_stac92hd83xxx),
5145b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76ef, "92HD66B2X3", patch_stac92hd83xxx),
5146b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76f0, "92HD66B3X3", patch_stac92hd83xxx),
5147b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76f1, "92HD66C1X3", patch_stac92hd83xxx),
5148b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76f2, "92HD66C2X3", patch_stac92hd83xxx),
5149b9a94a9cSTakashi Iwai HDA_CODEC_ENTRY(0x111d76f3, "92HD66C3/65", patch_stac92hd83xxx),
51502f2f4251SMatt {} /* terminator */
51512f2f4251SMatt };
5152b9a94a9cSTakashi Iwai MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_sigmatel);
51531289e9e8STakashi Iwai
51541289e9e8STakashi Iwai MODULE_LICENSE("GPL");
51551289e9e8STakashi Iwai MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
51561289e9e8STakashi Iwai
5157d8a766a1STakashi Iwai static struct hda_codec_driver sigmatel_driver = {
5158b9a94a9cSTakashi Iwai .id = snd_hda_id_sigmatel,
51591289e9e8STakashi Iwai };
51601289e9e8STakashi Iwai
5161d8a766a1STakashi Iwai module_hda_codec_driver(sigmatel_driver);
5162