Merge branch 'test/hda-gen-parser' into test/hda-migrate
[deliverable/linux.git] / sound / pci / hda / patch_sigmatel.c
CommitLineData
2f2f4251
M
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for SigmaTel STAC92xx
5 *
6 * Copyright (c) 2005 Embedded Alley Solutions, Inc.
403d1944 7 * Matt Porter <mporter@embeddedalley.com>
2f2f4251
M
8 *
9 * Based on patch_cmedia.c and patch_realtek.c
10 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
11 *
12 * This driver is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This driver is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
2f2f4251
M
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
5bdaaada 31#include <linux/dmi.h>
da155d5b 32#include <linux/module.h>
2f2f4251 33#include <sound/core.h>
c7d4b2fa 34#include <sound/asoundef.h>
45a6ac16 35#include <sound/jack.h>
a74ccea5 36#include <sound/tlv.h>
2f2f4251
M
37#include "hda_codec.h"
38#include "hda_local.h"
128bc4ba 39#include "hda_auto_parser.h"
1cd2224c 40#include "hda_beep.h"
1835a0f9 41#include "hda_jack.h"
2f2f4251 42
c6e4c666
TI
43enum {
44 STAC_VREF_EVENT = 1,
45 STAC_INSERT_EVENT,
46 STAC_PWR_EVENT,
47 STAC_HP_EVENT,
fefd67f3 48 STAC_LO_EVENT,
3d21d3f7 49 STAC_MIC_EVENT,
c6e4c666 50};
4e55096e 51
f5fcc13c
TI
52enum {
53 STAC_REF,
bf277785 54 STAC_9200_OQO,
dfe495d0
TI
55 STAC_9200_DELL_D21,
56 STAC_9200_DELL_D22,
57 STAC_9200_DELL_D23,
58 STAC_9200_DELL_M21,
59 STAC_9200_DELL_M22,
60 STAC_9200_DELL_M23,
61 STAC_9200_DELL_M24,
62 STAC_9200_DELL_M25,
63 STAC_9200_DELL_M26,
64 STAC_9200_DELL_M27,
58eec423
MCC
65 STAC_9200_M4,
66 STAC_9200_M4_2,
117f257d 67 STAC_9200_PANASONIC,
d39a3ae8 68 STAC_9200_EAPD_INIT,
f5fcc13c
TI
69 STAC_9200_MODELS
70};
71
72enum {
73 STAC_9205_REF,
dfe495d0 74 STAC_9205_DELL_M42,
ae0a8ed8
TD
75 STAC_9205_DELL_M43,
76 STAC_9205_DELL_M44,
d9a4268e 77 STAC_9205_EAPD,
f5fcc13c
TI
78 STAC_9205_MODELS
79};
80
e1f0d669 81enum {
9e43f0de 82 STAC_92HD73XX_NO_JD, /* no jack-detection */
e1f0d669 83 STAC_92HD73XX_REF,
ae709440 84 STAC_92HD73XX_INTEL,
661cd8fb
TI
85 STAC_DELL_M6_AMIC,
86 STAC_DELL_M6_DMIC,
87 STAC_DELL_M6_BOTH,
6b3ab21e 88 STAC_DELL_EQ,
842ae638 89 STAC_ALIENWARE_M17X,
e1f0d669
MR
90 STAC_92HD73XX_MODELS
91};
92
d0513fc6
MR
93enum {
94 STAC_92HD83XXX_REF,
32ed3f46 95 STAC_92HD83XXX_PWR_REF,
8bb0ac55 96 STAC_DELL_S14,
f7f9bdfa 97 STAC_DELL_VOSTRO_3500,
0c27c180 98 STAC_92HD83XXX_HP_cNB11_INTQUAD,
48315590 99 STAC_HP_DV7_4000,
5556e147 100 STAC_HP_ZEPHYR,
a3e19973 101 STAC_92HD83XXX_HP_LED,
ff8a1e27 102 STAC_92HD83XXX_HP_INV_LED,
62cbde18 103 STAC_92HD83XXX_HP_MIC_LED,
8d032a8f 104 STAC_92HD83XXX_HEADSET_JACK,
372f8c75 105 STAC_92HD83XXX_HP,
d0513fc6
MR
106 STAC_92HD83XXX_MODELS
107};
108
e035b841
MR
109enum {
110 STAC_92HD71BXX_REF,
a7662640
MR
111 STAC_DELL_M4_1,
112 STAC_DELL_M4_2,
3a7abfd2 113 STAC_DELL_M4_3,
6a14f585 114 STAC_HP_M4,
2a6ce6e5 115 STAC_HP_DV4,
1b0652eb 116 STAC_HP_DV5,
ae6241fb 117 STAC_HP_HDX,
514bf54c 118 STAC_HP_DV4_1222NR,
0f6fcb73
TI
119 STAC_92HD71BXX_HP,
120 STAC_92HD71BXX_NO_DMIC,
121 STAC_92HD71BXX_NO_SMUX,
e035b841
MR
122 STAC_92HD71BXX_MODELS
123};
124
8e21c34c
TD
125enum {
126 STAC_925x_REF,
9cb36c2a
MCC
127 STAC_M1,
128 STAC_M1_2,
129 STAC_M2,
8e21c34c 130 STAC_M2_2,
9cb36c2a
MCC
131 STAC_M3,
132 STAC_M5,
133 STAC_M6,
8e21c34c
TD
134 STAC_925x_MODELS
135};
136
f5fcc13c
TI
137enum {
138 STAC_D945_REF,
139 STAC_D945GTP3,
140 STAC_D945GTP5,
5d5d3bc3
IZ
141 STAC_INTEL_MAC_V1,
142 STAC_INTEL_MAC_V2,
143 STAC_INTEL_MAC_V3,
144 STAC_INTEL_MAC_V4,
145 STAC_INTEL_MAC_V5,
0a427846 146 STAC_INTEL_MAC_AUTO,
8c650087 147 STAC_ECS_202,
dfe495d0
TI
148 STAC_922X_DELL_D81,
149 STAC_922X_DELL_D82,
150 STAC_922X_DELL_M81,
151 STAC_922X_DELL_M82,
0a427846 152 STAC_922X_INTEL_MAC_GPIO,
f5fcc13c
TI
153 STAC_922X_MODELS
154};
155
156enum {
e28d8322 157 STAC_D965_REF_NO_JD, /* no jack-detection */
f5fcc13c
TI
158 STAC_D965_REF,
159 STAC_D965_3ST,
160 STAC_D965_5ST,
679d92ed 161 STAC_D965_5ST_NO_FP,
29ac8363 162 STAC_D965_VERBS,
4ff076e5 163 STAC_DELL_3ST,
8e9068b1 164 STAC_DELL_BIOS,
29ac8363
TI
165 STAC_DELL_BIOS_SPDIF,
166 STAC_927X_DELL_DMIC,
54930531 167 STAC_927X_VOLKNOB,
f5fcc13c
TI
168 STAC_927X_MODELS
169};
403d1944 170
307282c8 171enum {
307282c8
TI
172 STAC_9872_VAIO,
173 STAC_9872_MODELS
174};
175
3d21d3f7
TI
176struct sigmatel_mic_route {
177 hda_nid_t pin;
02d33322
TI
178 signed char mux_idx;
179 signed char dmux_idx;
3d21d3f7
TI
180};
181
699d8995
VK
182#define MAX_PINS_NUM 16
183#define MAX_ADCS_NUM 4
184#define MAX_DMICS_NUM 4
185
2f2f4251 186struct sigmatel_spec {
c8b6bf9b 187 struct snd_kcontrol_new *mixers[4];
c7d4b2fa
M
188 unsigned int num_mixers;
189
c0cea0d0 190 unsigned int eapd_switch: 1;
c7d4b2fa 191 unsigned int surr_switch: 1;
3cc08dc6 192 unsigned int alt_switch: 1;
82bc955f 193 unsigned int hp_detect: 1;
00ef50c2 194 unsigned int spdif_mute: 1;
7c7767eb 195 unsigned int check_volume_offset:1;
3d21d3f7 196 unsigned int auto_mic:1;
1b0e372d 197 unsigned int linear_tone_beep:1;
8d032a8f 198 unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
29ac8363 199 unsigned int volknob_init:1; /* special volume-knob initialization */
c7d4b2fa 200
4fe5195c 201 /* gpio lines */
0fc9dec4 202 unsigned int eapd_mask;
4fe5195c
MR
203 unsigned int gpio_mask;
204 unsigned int gpio_dir;
205 unsigned int gpio_data;
206 unsigned int gpio_mute;
86d190e7 207 unsigned int gpio_led;
c357aab0 208 unsigned int gpio_led_polarity;
f1a73746 209 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
45eebda7 210 unsigned int vref_led;
372f8c75 211 int default_polarity;
4fe5195c 212
62cbde18
TI
213 unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
214 bool mic_mute_led_on; /* current mic mute state */
215
8daaaa97
MR
216 /* stream */
217 unsigned int stream_delay;
218
4fe5195c 219 /* analog loopback */
2b63536f 220 const struct snd_kcontrol_new *aloopback_ctl;
e1f0d669
MR
221 unsigned char aloopback_mask;
222 unsigned char aloopback_shift;
8259980e 223
a64135a2 224 /* power management */
c882246d 225 unsigned int power_map_bits;
a64135a2 226 unsigned int num_pwrs;
2b63536f
TI
227 const hda_nid_t *pwr_nids;
228 const hda_nid_t *dac_list;
a64135a2 229
2f2f4251 230 /* playback */
b22b4821
MR
231 struct hda_input_mux *mono_mux;
232 unsigned int cur_mmux;
2f2f4251 233 struct hda_multi_out multiout;
3cc08dc6 234 hda_nid_t dac_nids[5];
c21ca4a8
TI
235 hda_nid_t hp_dacs[5];
236 hda_nid_t speaker_dacs[5];
2f2f4251 237
7c7767eb
TI
238 int volume_offset;
239
2f2f4251 240 /* capture */
2b63536f 241 const hda_nid_t *adc_nids;
2f2f4251 242 unsigned int num_adcs;
2b63536f 243 const hda_nid_t *mux_nids;
dabbed6f 244 unsigned int num_muxes;
2b63536f 245 const hda_nid_t *dmic_nids;
8b65727b 246 unsigned int num_dmics;
2b63536f 247 const hda_nid_t *dmux_nids;
1697055e 248 unsigned int num_dmuxes;
2b63536f 249 const hda_nid_t *smux_nids;
d9737751 250 unsigned int num_smuxes;
5207e10e 251 unsigned int num_analog_muxes;
6479c631 252
2b63536f
TI
253 const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
254 const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
6479c631
TI
255 unsigned int num_caps; /* number of capture volume/switch elements */
256
3d21d3f7
TI
257 struct sigmatel_mic_route ext_mic;
258 struct sigmatel_mic_route int_mic;
9907790a 259 struct sigmatel_mic_route dock_mic;
3d21d3f7 260
ea734963 261 const char * const *spdif_labels;
d9737751 262
dabbed6f 263 hda_nid_t dig_in_nid;
b22b4821 264 hda_nid_t mono_nid;
1cd2224c
MR
265 hda_nid_t anabeep_nid;
266 hda_nid_t digbeep_nid;
2f2f4251 267
2f2f4251 268 /* pin widgets */
2b63536f 269 const hda_nid_t *pin_nids;
2f2f4251 270 unsigned int num_pins;
2f2f4251
M
271
272 /* codec specific stuff */
2b63536f
TI
273 const struct hda_verb *init;
274 const struct snd_kcontrol_new *mixer;
2f2f4251
M
275
276 /* capture source */
8b65727b 277 struct hda_input_mux *dinput_mux;
e1f0d669 278 unsigned int cur_dmux[2];
c7d4b2fa 279 struct hda_input_mux *input_mux;
3cc08dc6 280 unsigned int cur_mux[3];
d9737751
MR
281 struct hda_input_mux *sinput_mux;
282 unsigned int cur_smux[2];
2a9c7816
MR
283 unsigned int cur_amux;
284 hda_nid_t *amp_nids;
8daaaa97 285 unsigned int powerdown_adcs;
2f2f4251 286
403d1944
MP
287 /* i/o switches */
288 unsigned int io_switch[2];
0fb87bb4 289 unsigned int clfe_swap;
c21ca4a8
TI
290 hda_nid_t line_switch; /* shared line-in for input and output */
291 hda_nid_t mic_switch; /* shared mic-in for input and output */
292 hda_nid_t hp_switch; /* NID of HP as line-out */
5f10c4a9 293 unsigned int aloopback;
2f2f4251 294
c7d4b2fa
M
295 struct hda_pcm pcm_rec[2]; /* PCM information */
296
297 /* dynamic controls and input_mux */
298 struct auto_pin_cfg autocfg;
603c4019 299 struct snd_array kctls;
8b65727b 300 struct hda_input_mux private_dimux;
c7d4b2fa 301 struct hda_input_mux private_imux;
d9737751 302 struct hda_input_mux private_smux;
b22b4821 303 struct hda_input_mux private_mono_mux;
699d8995
VK
304
305 /* auto spec */
306 unsigned auto_pin_cnt;
307 hda_nid_t auto_pin_nids[MAX_PINS_NUM];
308 unsigned auto_adc_cnt;
309 hda_nid_t auto_adc_nids[MAX_ADCS_NUM];
310 hda_nid_t auto_mux_nids[MAX_ADCS_NUM];
311 hda_nid_t auto_dmux_nids[MAX_ADCS_NUM];
312 unsigned long auto_capvols[MAX_ADCS_NUM];
313 unsigned auto_dmic_cnt;
314 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
2faa3bf1 315
d2f344b5 316 struct hda_vmaster_mute_hook vmaster_mute;
2f2f4251
M
317};
318
c882246d
TI
319#define AC_VERB_IDT_SET_POWER_MAP 0x7ec
320#define AC_VERB_IDT_GET_POWER_MAP 0xfec
321
2b63536f 322static const hda_nid_t stac9200_adc_nids[1] = {
2f2f4251
M
323 0x03,
324};
325
2b63536f 326static const hda_nid_t stac9200_mux_nids[1] = {
2f2f4251
M
327 0x0c,
328};
329
2b63536f 330static const hda_nid_t stac9200_dac_nids[1] = {
2f2f4251
M
331 0x02,
332};
333
2b63536f 334static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
a64135a2
MR
335 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
336 0x0f, 0x10, 0x11
337};
338
2b63536f 339static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
0ffa9807
MR
340 0x26, 0,
341};
342
2b63536f 343static const hda_nid_t stac92hd73xx_adc_nids[2] = {
e1f0d669
MR
344 0x1a, 0x1b
345};
346
347#define STAC92HD73XX_NUM_DMICS 2
2b63536f 348static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
e1f0d669
MR
349 0x13, 0x14, 0
350};
351
352#define STAC92HD73_DAC_COUNT 5
e1f0d669 353
2b63536f 354static const hda_nid_t stac92hd73xx_mux_nids[2] = {
e2aec171 355 0x20, 0x21,
e1f0d669
MR
356};
357
2b63536f 358static const hda_nid_t stac92hd73xx_dmux_nids[2] = {
e1f0d669
MR
359 0x20, 0x21,
360};
361
2b63536f 362static const hda_nid_t stac92hd73xx_smux_nids[2] = {
d9737751
MR
363 0x22, 0x23,
364};
365
6479c631 366#define STAC92HD73XX_NUM_CAPS 2
2b63536f 367static const unsigned long stac92hd73xx_capvols[] = {
6479c631
TI
368 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
369 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
370};
371#define stac92hd73xx_capsws stac92hd73xx_capvols
372
d0513fc6 373#define STAC92HD83_DAC_COUNT 3
d0513fc6 374
afef2cfa
CC
375static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
376 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
377 0x0f, 0x10
d0513fc6
MR
378};
379
2b63536f 380static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
0ffa9807
MR
381 0x1e, 0,
382};
383
2b63536f 384static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
699d8995 385 0x11, 0x20,
ab5a6ebe
VK
386};
387
2b63536f 388static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
a64135a2
MR
389 0x0a, 0x0d, 0x0f
390};
391
2b63536f 392static const hda_nid_t stac92hd71bxx_adc_nids[2] = {
e035b841
MR
393 0x12, 0x13,
394};
395
2b63536f 396static const hda_nid_t stac92hd71bxx_mux_nids[2] = {
e035b841
MR
397 0x1a, 0x1b
398};
399
2b63536f 400static const hda_nid_t stac92hd71bxx_dmux_nids[2] = {
4b33c767 401 0x1c, 0x1d,
e1f0d669
MR
402};
403
2b63536f 404static const hda_nid_t stac92hd71bxx_smux_nids[2] = {
d9737751
MR
405 0x24, 0x25,
406};
407
e035b841 408#define STAC92HD71BXX_NUM_DMICS 2
2b63536f 409static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
e035b841
MR
410 0x18, 0x19, 0
411};
412
2b63536f
TI
413static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = {
414 0x18, 0
415};
416
417static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
0ffa9807
MR
418 0x22, 0
419};
420
6479c631 421#define STAC92HD71BXX_NUM_CAPS 2
2b63536f 422static const unsigned long stac92hd71bxx_capvols[] = {
6479c631
TI
423 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
424 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
425};
426#define stac92hd71bxx_capsws stac92hd71bxx_capvols
427
2b63536f 428static const hda_nid_t stac925x_adc_nids[1] = {
8e21c34c
TD
429 0x03,
430};
431
2b63536f 432static const hda_nid_t stac925x_mux_nids[1] = {
8e21c34c
TD
433 0x0f,
434};
435
2b63536f 436static const hda_nid_t stac925x_dac_nids[1] = {
8e21c34c
TD
437 0x02,
438};
439
f6e9852a 440#define STAC925X_NUM_DMICS 1
2b63536f 441static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
f6e9852a 442 0x15, 0
2c11f955
TD
443};
444
2b63536f 445static const hda_nid_t stac925x_dmux_nids[1] = {
1697055e
TI
446 0x14,
447};
448
2b63536f 449static const unsigned long stac925x_capvols[] = {
6479c631
TI
450 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
451};
2b63536f 452static const unsigned long stac925x_capsws[] = {
6479c631
TI
453 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
454};
455
2b63536f 456static const hda_nid_t stac922x_adc_nids[2] = {
2f2f4251
M
457 0x06, 0x07,
458};
459
2b63536f 460static const hda_nid_t stac922x_mux_nids[2] = {
2f2f4251
M
461 0x12, 0x13,
462};
463
6479c631 464#define STAC922X_NUM_CAPS 2
2b63536f 465static const unsigned long stac922x_capvols[] = {
6479c631
TI
466 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
467 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
468};
469#define stac922x_capsws stac922x_capvols
470
2b63536f 471static const hda_nid_t stac927x_slave_dig_outs[2] = {
45c1d85b
MR
472 0x1f, 0,
473};
474
2b63536f 475static const hda_nid_t stac927x_adc_nids[3] = {
3cc08dc6
MP
476 0x07, 0x08, 0x09
477};
478
2b63536f 479static const hda_nid_t stac927x_mux_nids[3] = {
3cc08dc6
MP
480 0x15, 0x16, 0x17
481};
482
2b63536f 483static const hda_nid_t stac927x_smux_nids[1] = {
d9737751
MR
484 0x21,
485};
486
2b63536f 487static const hda_nid_t stac927x_dac_nids[6] = {
b76c850f
MR
488 0x02, 0x03, 0x04, 0x05, 0x06, 0
489};
490
2b63536f 491static const hda_nid_t stac927x_dmux_nids[1] = {
e1f0d669
MR
492 0x1b,
493};
494
7f16859a 495#define STAC927X_NUM_DMICS 2
2b63536f 496static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
7f16859a
MR
497 0x13, 0x14, 0
498};
499
6479c631 500#define STAC927X_NUM_CAPS 3
2b63536f 501static const unsigned long stac927x_capvols[] = {
6479c631
TI
502 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
503 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
504 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
505};
2b63536f 506static const unsigned long stac927x_capsws[] = {
6479c631
TI
507 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
508 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
509 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
510};
511
ea734963 512static const char * const stac927x_spdif_labels[5] = {
65973632
MR
513 "Digital Playback", "ADAT", "Analog Mux 1",
514 "Analog Mux 2", "Analog Mux 3"
515};
516
2b63536f 517static const hda_nid_t stac9205_adc_nids[2] = {
f3302a59
MP
518 0x12, 0x13
519};
520
2b63536f 521static const hda_nid_t stac9205_mux_nids[2] = {
f3302a59
MP
522 0x19, 0x1a
523};
524
2b63536f 525static const hda_nid_t stac9205_dmux_nids[1] = {
1697055e 526 0x1d,
e1f0d669
MR
527};
528
2b63536f 529static const hda_nid_t stac9205_smux_nids[1] = {
d9737751
MR
530 0x21,
531};
532
f6e9852a 533#define STAC9205_NUM_DMICS 2
2b63536f 534static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
f6e9852a 535 0x17, 0x18, 0
8b65727b
MP
536};
537
6479c631 538#define STAC9205_NUM_CAPS 2
2b63536f 539static const unsigned long stac9205_capvols[] = {
6479c631
TI
540 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
541 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
542};
2b63536f 543static const unsigned long stac9205_capsws[] = {
6479c631
TI
544 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
545 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
546};
547
2b63536f 548static const hda_nid_t stac9200_pin_nids[8] = {
93ed1503
TD
549 0x08, 0x09, 0x0d, 0x0e,
550 0x0f, 0x10, 0x11, 0x12,
2f2f4251
M
551};
552
2b63536f 553static const hda_nid_t stac925x_pin_nids[8] = {
8e21c34c
TD
554 0x07, 0x08, 0x0a, 0x0b,
555 0x0c, 0x0d, 0x10, 0x11,
556};
557
2b63536f 558static const hda_nid_t stac922x_pin_nids[10] = {
2f2f4251
M
559 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
560 0x0f, 0x10, 0x11, 0x15, 0x1b,
561};
562
2b63536f 563static const hda_nid_t stac92hd73xx_pin_nids[13] = {
e1f0d669
MR
564 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
565 0x0f, 0x10, 0x11, 0x12, 0x13,
d9737751 566 0x14, 0x22, 0x23
e1f0d669
MR
567};
568
616f89e7 569#define STAC92HD71BXX_NUM_PINS 13
2b63536f 570static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
616f89e7
HRK
571 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
572 0x00, 0x14, 0x18, 0x19, 0x1e,
573 0x1f, 0x20, 0x27
574};
2b63536f 575static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
e035b841
MR
576 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
577 0x0f, 0x14, 0x18, 0x19, 0x1e,
616f89e7 578 0x1f, 0x20, 0x27
e035b841
MR
579};
580
2b63536f 581static const hda_nid_t stac927x_pin_nids[14] = {
3cc08dc6
MP
582 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
583 0x0f, 0x10, 0x11, 0x12, 0x13,
584 0x14, 0x21, 0x22, 0x23,
585};
586
2b63536f 587static const hda_nid_t stac9205_pin_nids[12] = {
f3302a59
MP
588 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
589 0x0f, 0x14, 0x16, 0x17, 0x18,
590 0x21, 0x22,
f3302a59
MP
591};
592
0f6fcb73
TI
593static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
594 unsigned char type, int data);
595static int stac_add_hp_bass_switch(struct hda_codec *codec);
596static void stac92xx_auto_set_pinctl(struct hda_codec *codec,
597 hda_nid_t nid, int pin_type);
372f8c75 598static int hp_bnb2011_with_dock(struct hda_codec *codec);
0f6fcb73
TI
599static int hp_blike_system(u32 subsystem_id);
600static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity);
601
8b65727b
MP
602static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
603 struct snd_ctl_elem_info *uinfo)
604{
605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
606 struct sigmatel_spec *spec = codec->spec;
607 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
608}
609
610static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
611 struct snd_ctl_elem_value *ucontrol)
612{
613 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
614 struct sigmatel_spec *spec = codec->spec;
e1f0d669 615 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8b65727b 616
e1f0d669 617 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
8b65727b
MP
618 return 0;
619}
620
621static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
622 struct snd_ctl_elem_value *ucontrol)
623{
624 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
625 struct sigmatel_spec *spec = codec->spec;
e1f0d669 626 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8b65727b
MP
627
628 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
e1f0d669 629 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
8b65727b
MP
630}
631
d9737751
MR
632static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_info *uinfo)
634{
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct sigmatel_spec *spec = codec->spec;
637 return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
638}
639
640static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_value *ucontrol)
642{
643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644 struct sigmatel_spec *spec = codec->spec;
645 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
646
647 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
648 return 0;
649}
650
651static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
652 struct snd_ctl_elem_value *ucontrol)
653{
654 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
655 struct sigmatel_spec *spec = codec->spec;
00ef50c2 656 struct hda_input_mux *smux = &spec->private_smux;
d9737751 657 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
00ef50c2
MR
658 int err, val;
659 hda_nid_t nid;
d9737751 660
00ef50c2 661 err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
d9737751 662 spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
00ef50c2
MR
663 if (err < 0)
664 return err;
665
666 if (spec->spdif_mute) {
667 if (smux_idx == 0)
668 nid = spec->multiout.dig_out_nid;
669 else
670 nid = codec->slave_dig_outs[smux_idx - 1];
671 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
c9b46f91 672 val = HDA_AMP_MUTE;
00ef50c2 673 else
c9b46f91 674 val = 0;
00ef50c2 675 /* un/mute SPDIF out */
c9b46f91
TI
676 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
677 HDA_AMP_MUTE, val);
00ef50c2
MR
678 }
679 return 0;
d9737751
MR
680}
681
45eebda7
VK
682static int stac_vrefout_set(struct hda_codec *codec,
683 hda_nid_t nid, unsigned int new_vref)
684{
685 int error, pinctl;
686
687 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
688 pinctl = snd_hda_codec_read(codec, nid, 0,
689 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
690
691 if (pinctl < 0)
692 return pinctl;
693
694 pinctl &= 0xff;
695 pinctl &= ~AC_PINCTL_VREFEN;
696 pinctl |= (new_vref & AC_PINCTL_VREFEN);
697
cdd03ced 698 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
45eebda7
VK
699 if (error < 0)
700 return error;
701
702 return 1;
703}
704
2fc99890
NL
705static unsigned int stac92xx_vref_set(struct hda_codec *codec,
706 hda_nid_t nid, unsigned int new_vref)
707{
b8621516 708 int error;
2fc99890
NL
709 unsigned int pincfg;
710 pincfg = snd_hda_codec_read(codec, nid, 0,
711 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
712
713 pincfg &= 0xff;
714 pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
715 pincfg |= new_vref;
716
717 if (new_vref == AC_PINCTL_VREF_HIZ)
718 pincfg |= AC_PINCTL_OUT_EN;
719 else
720 pincfg |= AC_PINCTL_IN_EN;
721
cdd03ced 722 error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg);
2fc99890
NL
723 if (error < 0)
724 return error;
725 else
726 return 1;
727}
728
729static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid)
730{
731 unsigned int vref;
732 vref = snd_hda_codec_read(codec, nid, 0,
733 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
734 vref &= AC_PINCTL_VREFEN;
735 return vref;
736}
737
c8b6bf9b 738static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2f2f4251
M
739{
740 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
741 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa 742 return snd_hda_input_mux_info(spec->input_mux, uinfo);
2f2f4251
M
743}
744
c8b6bf9b 745static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2f2f4251
M
746{
747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
748 struct sigmatel_spec *spec = codec->spec;
749 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
750
751 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
752 return 0;
753}
754
c8b6bf9b 755static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2f2f4251
M
756{
757 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
758 struct sigmatel_spec *spec = codec->spec;
759 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5207e10e 760 const struct hda_input_mux *imux = spec->input_mux;
094a4245 761 unsigned int idx, prev_idx, didx;
5207e10e
TI
762
763 idx = ucontrol->value.enumerated.item[0];
764 if (idx >= imux->num_items)
765 idx = imux->num_items - 1;
766 prev_idx = spec->cur_mux[adc_idx];
767 if (prev_idx == idx)
768 return 0;
769 if (idx < spec->num_analog_muxes) {
770 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
771 AC_VERB_SET_CONNECT_SEL,
772 imux->items[idx].index);
094a4245
VK
773 if (prev_idx >= spec->num_analog_muxes &&
774 spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) {
5207e10e
TI
775 imux = spec->dinput_mux;
776 /* 0 = analog */
777 snd_hda_codec_write_cache(codec,
778 spec->dmux_nids[adc_idx], 0,
779 AC_VERB_SET_CONNECT_SEL,
780 imux->items[0].index);
781 }
782 } else {
783 imux = spec->dinput_mux;
094a4245
VK
784 /* first dimux item is hardcoded to select analog imux,
785 * so lets skip it
786 */
787 didx = idx - spec->num_analog_muxes + 1;
5207e10e
TI
788 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
789 AC_VERB_SET_CONNECT_SEL,
094a4245 790 imux->items[didx].index);
5207e10e
TI
791 }
792 spec->cur_mux[adc_idx] = idx;
793 return 1;
2f2f4251
M
794}
795
b22b4821
MR
796static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
797 struct snd_ctl_elem_info *uinfo)
798{
799 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
800 struct sigmatel_spec *spec = codec->spec;
801 return snd_hda_input_mux_info(spec->mono_mux, uinfo);
802}
803
804static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
805 struct snd_ctl_elem_value *ucontrol)
806{
807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
808 struct sigmatel_spec *spec = codec->spec;
809
810 ucontrol->value.enumerated.item[0] = spec->cur_mmux;
811 return 0;
812}
813
814static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
815 struct snd_ctl_elem_value *ucontrol)
816{
817 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
818 struct sigmatel_spec *spec = codec->spec;
819
820 return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
821 spec->mono_nid, &spec->cur_mmux);
822}
823
5f10c4a9
ML
824#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
825
826static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
828{
829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
e1f0d669 830 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5f10c4a9
ML
831 struct sigmatel_spec *spec = codec->spec;
832
e1f0d669
MR
833 ucontrol->value.integer.value[0] = !!(spec->aloopback &
834 (spec->aloopback_mask << idx));
5f10c4a9
ML
835 return 0;
836}
837
838static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
839 struct snd_ctl_elem_value *ucontrol)
840{
841 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
842 struct sigmatel_spec *spec = codec->spec;
e1f0d669 843 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5f10c4a9 844 unsigned int dac_mode;
e1f0d669 845 unsigned int val, idx_val;
5f10c4a9 846
e1f0d669
MR
847 idx_val = spec->aloopback_mask << idx;
848 if (ucontrol->value.integer.value[0])
849 val = spec->aloopback | idx_val;
850 else
851 val = spec->aloopback & ~idx_val;
68ea7b2f 852 if (spec->aloopback == val)
5f10c4a9
ML
853 return 0;
854
68ea7b2f 855 spec->aloopback = val;
5f10c4a9 856
e1f0d669
MR
857 /* Only return the bits defined by the shift value of the
858 * first two bytes of the mask
859 */
5f10c4a9 860 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
e1f0d669
MR
861 kcontrol->private_value & 0xFFFF, 0x0);
862 dac_mode >>= spec->aloopback_shift;
5f10c4a9 863
e1f0d669 864 if (spec->aloopback & idx_val) {
5f10c4a9 865 snd_hda_power_up(codec);
e1f0d669 866 dac_mode |= idx_val;
5f10c4a9
ML
867 } else {
868 snd_hda_power_down(codec);
e1f0d669 869 dac_mode &= ~idx_val;
5f10c4a9
ML
870 }
871
872 snd_hda_codec_write_cache(codec, codec->afg, 0,
873 kcontrol->private_value >> 16, dac_mode);
874
875 return 1;
876}
877
2b63536f 878static const struct hda_verb stac9200_core_init[] = {
2f2f4251 879 /* set dac0mux for dac converter */
c7d4b2fa 880 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2f2f4251
M
881 {}
882};
883
2b63536f 884static const struct hda_verb stac9200_eapd_init[] = {
1194b5b7
TI
885 /* set dac0mux for dac converter */
886 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
887 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
888 {}
889};
890
2b63536f 891static const struct hda_verb dell_eq_core_init[] = {
d654a660
MR
892 /* set master volume to max value without distortion
893 * and direct control */
894 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
e1f0d669
MR
895 {}
896};
897
2b63536f 898static const struct hda_verb stac92hd73xx_core_init[] = {
e1f0d669
MR
899 /* set master volume and direct control */
900 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
e1f0d669
MR
901 {}
902};
903
2b63536f 904static const struct hda_verb stac92hd83xxx_core_init[] = {
d0513fc6
MR
905 /* power state controls amps */
906 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
574f3c4f 907 {}
d0513fc6
MR
908};
909
5556e147
VK
910static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
911 { 0x22, 0x785, 0x43 },
912 { 0x22, 0x782, 0xe0 },
913 { 0x22, 0x795, 0x00 },
914 {}
915};
916
2b63536f 917static const struct hda_verb stac92hd71bxx_core_init[] = {
541eee87
MR
918 /* set master volume and direct control */
919 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
574f3c4f 920 {}
541eee87
MR
921};
922
2b63536f 923static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
ca8d33fc
MR
924 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
925 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e035b841
MR
926 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
927 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e035b841
MR
928 {}
929};
930
2b63536f 931static const struct hda_verb stac925x_core_init[] = {
8e21c34c
TD
932 /* set dac0mux for dac converter */
933 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
c9280d68
TI
934 /* mute the master volume */
935 { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8e21c34c
TD
936 {}
937};
938
2b63536f 939static const struct hda_verb stac922x_core_init[] = {
2f2f4251 940 /* set master volume and direct control */
c7d4b2fa 941 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
2f2f4251
M
942 {}
943};
944
2b63536f 945static const struct hda_verb d965_core_init[] = {
19039bd0
TI
946 /* unmute node 0x1b */
947 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
948 /* select node 0x03 as DAC */
949 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
950 {}
951};
952
2b63536f 953static const struct hda_verb dell_3st_core_init[] = {
ccca7cdc
TI
954 /* don't set delta bit */
955 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
956 /* unmute node 0x1b */
957 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
958 /* select node 0x03 as DAC */
959 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
960 {}
961};
962
2b63536f 963static const struct hda_verb stac927x_core_init[] = {
3cc08dc6
MP
964 /* set master volume and direct control */
965 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1cd2224c
MR
966 /* enable analog pc beep path */
967 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
3cc08dc6
MP
968 {}
969};
970
2b63536f 971static const struct hda_verb stac927x_volknob_core_init[] = {
54930531
TI
972 /* don't set delta bit */
973 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
974 /* enable analog pc beep path */
975 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
976 {}
977};
978
2b63536f 979static const struct hda_verb stac9205_core_init[] = {
f3302a59
MP
980 /* set master volume and direct control */
981 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
d0513fc6
MR
982 /* enable analog pc beep path */
983 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
f3302a59
MP
984 {}
985};
986
b22b4821
MR
987#define STAC_MONO_MUX \
988 { \
989 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
990 .name = "Mono Mux", \
991 .count = 1, \
992 .info = stac92xx_mono_mux_enum_info, \
993 .get = stac92xx_mono_mux_enum_get, \
994 .put = stac92xx_mono_mux_enum_put, \
995 }
996
e1f0d669 997#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
5f10c4a9
ML
998 { \
999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1000 .name = "Analog Loopback", \
e1f0d669 1001 .count = cnt, \
5f10c4a9
ML
1002 .info = stac92xx_aloopback_info, \
1003 .get = stac92xx_aloopback_get, \
1004 .put = stac92xx_aloopback_put, \
1005 .private_value = verb_read | (verb_write << 16), \
1006 }
1007
2fc99890
NL
1008#define DC_BIAS(xname, idx, nid) \
1009 { \
1010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1011 .name = xname, \
1012 .index = idx, \
1013 .info = stac92xx_dc_bias_info, \
1014 .get = stac92xx_dc_bias_get, \
1015 .put = stac92xx_dc_bias_put, \
1016 .private_value = nid, \
1017 }
1018
2b63536f 1019static const struct snd_kcontrol_new stac9200_mixer[] = {
2faa3bf1
TI
1020 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
1021 HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
2f2f4251
M
1022 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1023 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
2f2f4251
M
1024 { } /* end */
1025};
1026
2b63536f 1027static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
d78d7a90
TI
1028 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
1029 {}
1030};
1031
2b63536f 1032static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = {
e1f0d669 1033 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
d78d7a90
TI
1034 {}
1035};
e1f0d669 1036
2b63536f 1037static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
d78d7a90
TI
1038 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
1039 {}
1040};
1041
d0513fc6 1042
2b63536f 1043static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
d78d7a90
TI
1044 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1045};
541eee87 1046
2b63536f 1047static const struct snd_kcontrol_new stac925x_mixer[] = {
2faa3bf1
TI
1048 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
1049 HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
2f2f4251
M
1050 { } /* end */
1051};
1052
2b63536f 1053static const struct snd_kcontrol_new stac9205_loopback[] = {
d78d7a90
TI
1054 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
1055 {}
1056};
1057
2b63536f 1058static const struct snd_kcontrol_new stac927x_loopback[] = {
d78d7a90
TI
1059 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1060 {}
1061};
1062
1697055e
TI
1063static struct snd_kcontrol_new stac_dmux_mixer = {
1064 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1065 .name = "Digital Input Source",
1066 /* count set later */
1067 .info = stac92xx_dmux_enum_info,
1068 .get = stac92xx_dmux_enum_get,
1069 .put = stac92xx_dmux_enum_put,
1070};
1071
d9737751
MR
1072static struct snd_kcontrol_new stac_smux_mixer = {
1073 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
e3487970 1074 .name = "IEC958 Playback Source",
d9737751
MR
1075 /* count set later */
1076 .info = stac92xx_smux_enum_info,
1077 .get = stac92xx_smux_enum_get,
1078 .put = stac92xx_smux_enum_put,
1079};
1080
9322ca54
TI
1081static const char * const slave_pfxs[] = {
1082 "Front", "Surround", "Center", "LFE", "Side",
f37bc7a8 1083 "Headphone", "Speaker", "Bass Speaker", "IEC958", "PCM",
2134ea4f
TI
1084 NULL
1085};
1086
2faa3bf1
TI
1087static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
1088
1089static void stac92xx_vmaster_hook(void *private_data, int val)
1090{
1091 stac92xx_update_led_status(private_data, val);
1092}
1093
603c4019
TI
1094static void stac92xx_free_kctls(struct hda_codec *codec);
1095
2f2f4251
M
1096static int stac92xx_build_controls(struct hda_codec *codec)
1097{
1098 struct sigmatel_spec *spec = codec->spec;
2faa3bf1 1099 unsigned int vmaster_tlv[4];
2f2f4251 1100 int err;
c7d4b2fa 1101 int i;
2f2f4251 1102
6479c631
TI
1103 if (spec->mixer) {
1104 err = snd_hda_add_new_ctls(codec, spec->mixer);
1105 if (err < 0)
1106 return err;
1107 }
c7d4b2fa
M
1108
1109 for (i = 0; i < spec->num_mixers; i++) {
1110 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1111 if (err < 0)
1112 return err;
1113 }
5207e10e
TI
1114 if (!spec->auto_mic && spec->num_dmuxes > 0 &&
1115 snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
1697055e 1116 stac_dmux_mixer.count = spec->num_dmuxes;
3911a4c1 1117 err = snd_hda_ctl_add(codec, 0,
1697055e
TI
1118 snd_ctl_new1(&stac_dmux_mixer, codec));
1119 if (err < 0)
1120 return err;
1121 }
d9737751 1122 if (spec->num_smuxes > 0) {
00ef50c2
MR
1123 int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
1124 struct hda_input_mux *smux = &spec->private_smux;
1125 /* check for mute support on SPDIF out */
1126 if (wcaps & AC_WCAP_OUT_AMP) {
10a20af7 1127 snd_hda_add_imux_item(smux, "Off", 0, NULL);
00ef50c2
MR
1128 spec->spdif_mute = 1;
1129 }
d9737751 1130 stac_smux_mixer.count = spec->num_smuxes;
3911a4c1 1131 err = snd_hda_ctl_add(codec, 0,
d9737751
MR
1132 snd_ctl_new1(&stac_smux_mixer, codec));
1133 if (err < 0)
1134 return err;
1135 }
c7d4b2fa 1136
dabbed6f 1137 if (spec->multiout.dig_out_nid) {
dcda5806
TI
1138 err = snd_hda_create_dig_out_ctls(codec,
1139 spec->multiout.dig_out_nid,
1140 spec->multiout.dig_out_nid,
1141 spec->autocfg.dig_out_type[0]);
dabbed6f
M
1142 if (err < 0)
1143 return err;
9a08160b
TI
1144 err = snd_hda_create_spdif_share_sw(codec,
1145 &spec->multiout);
1146 if (err < 0)
1147 return err;
1148 spec->multiout.share_spdif = 1;
dabbed6f 1149 }
da74ae3e 1150 if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
dabbed6f
M
1151 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1152 if (err < 0)
1153 return err;
1154 }
2134ea4f
TI
1155
1156 /* if we have no master control, let's create it */
2faa3bf1
TI
1157 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1158 HDA_OUTPUT, vmaster_tlv);
1159 /* correct volume offset */
1160 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1161 /* minimum value is actually mute */
1162 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1163 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1164 vmaster_tlv, slave_pfxs,
1165 "Playback Volume");
1166 if (err < 0)
1167 return err;
1168
1169 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1170 NULL, slave_pfxs,
1171 "Playback Switch", true,
d2f344b5 1172 &spec->vmaster_mute.sw_kctl);
2faa3bf1
TI
1173 if (err < 0)
1174 return err;
1175
1176 if (spec->gpio_led) {
d2f344b5 1177 spec->vmaster_mute.hook = stac92xx_vmaster_hook;
f29735cb 1178 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
d2f344b5
TI
1179 if (err < 0)
1180 return err;
2134ea4f
TI
1181 }
1182
d78d7a90
TI
1183 if (spec->aloopback_ctl &&
1184 snd_hda_get_bool_hint(codec, "loopback") == 1) {
1185 err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl);
1186 if (err < 0)
1187 return err;
1188 }
1189
603c4019 1190 stac92xx_free_kctls(codec); /* no longer needed */
e4973e1e 1191
01a61e12
TI
1192 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
1193 if (err < 0)
1194 return err;
e4973e1e 1195
dabbed6f 1196 return 0;
2f2f4251
M
1197}
1198
d39a3ae8
TI
1199static const struct hda_pintbl ref9200_pin_configs[] = {
1200 { 0x08, 0x01c47010 },
1201 { 0x09, 0x01447010 },
1202 { 0x0d, 0x0221401f },
1203 { 0x0e, 0x01114010 },
1204 { 0x0f, 0x02a19020 },
1205 { 0x10, 0x01a19021 },
1206 { 0x11, 0x90100140 },
1207 { 0x12, 0x01813122 },
1208 {}
2f2f4251
M
1209};
1210
d39a3ae8
TI
1211static const struct hda_pintbl gateway9200_m4_pin_configs[] = {
1212 { 0x08, 0x400000fe },
1213 { 0x09, 0x404500f4 },
1214 { 0x0d, 0x400100f0 },
1215 { 0x0e, 0x90110010 },
1216 { 0x0f, 0x400100f1 },
1217 { 0x10, 0x02a1902e },
1218 { 0x11, 0x500000f2 },
1219 { 0x12, 0x500000f3 },
1220 {}
58eec423 1221};
d39a3ae8
TI
1222
1223static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = {
1224 { 0x08, 0x400000fe },
1225 { 0x09, 0x404500f4 },
1226 { 0x0d, 0x400100f0 },
1227 { 0x0e, 0x90110010 },
1228 { 0x0f, 0x400100f1 },
1229 { 0x10, 0x02a1902e },
1230 { 0x11, 0x500000f2 },
1231 { 0x12, 0x500000f3 },
1232 {}
58eec423
MCC
1233};
1234
1235/*
dfe495d0
TI
1236 STAC 9200 pin configs for
1237 102801A8
1238 102801DE
1239 102801E8
1240*/
d39a3ae8
TI
1241static const struct hda_pintbl dell9200_d21_pin_configs[] = {
1242 { 0x08, 0x400001f0 },
1243 { 0x09, 0x400001f1 },
1244 { 0x0d, 0x02214030 },
1245 { 0x0e, 0x01014010 },
1246 { 0x0f, 0x02a19020 },
1247 { 0x10, 0x01a19021 },
1248 { 0x11, 0x90100140 },
1249 { 0x12, 0x01813122 },
1250 {}
dfe495d0
TI
1251};
1252
1253/*
1254 STAC 9200 pin configs for
1255 102801C0
1256 102801C1
1257*/
d39a3ae8
TI
1258static const struct hda_pintbl dell9200_d22_pin_configs[] = {
1259 { 0x08, 0x400001f0 },
1260 { 0x09, 0x400001f1 },
1261 { 0x0d, 0x0221401f },
1262 { 0x0e, 0x01014010 },
1263 { 0x0f, 0x01813020 },
1264 { 0x10, 0x02a19021 },
1265 { 0x11, 0x90100140 },
1266 { 0x12, 0x400001f2 },
1267 {}
dfe495d0
TI
1268};
1269
1270/*
1271 STAC 9200 pin configs for
1272 102801C4 (Dell Dimension E310)
1273 102801C5
1274 102801C7
1275 102801D9
1276 102801DA
1277 102801E3
1278*/
d39a3ae8
TI
1279static const struct hda_pintbl dell9200_d23_pin_configs[] = {
1280 { 0x08, 0x400001f0 },
1281 { 0x09, 0x400001f1 },
1282 { 0x0d, 0x0221401f },
1283 { 0x0e, 0x01014010 },
1284 { 0x0f, 0x01813020 },
1285 { 0x10, 0x01a19021 },
1286 { 0x11, 0x90100140 },
1287 { 0x12, 0x400001f2 },
1288 {}
dfe495d0
TI
1289};
1290
1291
1292/*
1293 STAC 9200-32 pin configs for
1294 102801B5 (Dell Inspiron 630m)
1295 102801D8 (Dell Inspiron 640m)
1296*/
d39a3ae8
TI
1297static const struct hda_pintbl dell9200_m21_pin_configs[] = {
1298 { 0x08, 0x40c003fa },
1299 { 0x09, 0x03441340 },
1300 { 0x0d, 0x0321121f },
1301 { 0x0e, 0x90170310 },
1302 { 0x0f, 0x408003fb },
1303 { 0x10, 0x03a11020 },
1304 { 0x11, 0x401003fc },
1305 { 0x12, 0x403003fd },
1306 {}
dfe495d0
TI
1307};
1308
1309/*
1310 STAC 9200-32 pin configs for
1311 102801C2 (Dell Latitude D620)
1312 102801C8
1313 102801CC (Dell Latitude D820)
1314 102801D4
1315 102801D6
1316*/
d39a3ae8
TI
1317static const struct hda_pintbl dell9200_m22_pin_configs[] = {
1318 { 0x08, 0x40c003fa },
1319 { 0x09, 0x0144131f },
1320 { 0x0d, 0x0321121f },
1321 { 0x0e, 0x90170310 },
1322 { 0x0f, 0x90a70321 },
1323 { 0x10, 0x03a11020 },
1324 { 0x11, 0x401003fb },
1325 { 0x12, 0x40f000fc },
1326 {}
dfe495d0
TI
1327};
1328
1329/*
1330 STAC 9200-32 pin configs for
1331 102801CE (Dell XPS M1710)
1332 102801CF (Dell Precision M90)
1333*/
d39a3ae8
TI
1334static const struct hda_pintbl dell9200_m23_pin_configs[] = {
1335 { 0x08, 0x40c003fa },
1336 { 0x09, 0x01441340 },
1337 { 0x0d, 0x0421421f },
1338 { 0x0e, 0x90170310 },
1339 { 0x0f, 0x408003fb },
1340 { 0x10, 0x04a1102e },
1341 { 0x11, 0x90170311 },
1342 { 0x12, 0x403003fc },
1343 {}
dfe495d0
TI
1344};
1345
1346/*
1347 STAC 9200-32 pin configs for
1348 102801C9
1349 102801CA
1350 102801CB (Dell Latitude 120L)
1351 102801D3
1352*/
d39a3ae8
TI
1353static const struct hda_pintbl dell9200_m24_pin_configs[] = {
1354 { 0x08, 0x40c003fa },
1355 { 0x09, 0x404003fb },
1356 { 0x0d, 0x0321121f },
1357 { 0x0e, 0x90170310 },
1358 { 0x0f, 0x408003fc },
1359 { 0x10, 0x03a11020 },
1360 { 0x11, 0x401003fd },
1361 { 0x12, 0x403003fe },
1362 {}
dfe495d0
TI
1363};
1364
1365/*
1366 STAC 9200-32 pin configs for
1367 102801BD (Dell Inspiron E1505n)
1368 102801EE
1369 102801EF
1370*/
d39a3ae8
TI
1371static const struct hda_pintbl dell9200_m25_pin_configs[] = {
1372 { 0x08, 0x40c003fa },
1373 { 0x09, 0x01441340 },
1374 { 0x0d, 0x0421121f },
1375 { 0x0e, 0x90170310 },
1376 { 0x0f, 0x408003fb },
1377 { 0x10, 0x04a11020 },
1378 { 0x11, 0x401003fc },
1379 { 0x12, 0x403003fd },
1380 {}
dfe495d0
TI
1381};
1382
1383/*
1384 STAC 9200-32 pin configs for
1385 102801F5 (Dell Inspiron 1501)
1386 102801F6
1387*/
d39a3ae8
TI
1388static const struct hda_pintbl dell9200_m26_pin_configs[] = {
1389 { 0x08, 0x40c003fa },
1390 { 0x09, 0x404003fb },
1391 { 0x0d, 0x0421121f },
1392 { 0x0e, 0x90170310 },
1393 { 0x0f, 0x408003fc },
1394 { 0x10, 0x04a11020 },
1395 { 0x11, 0x401003fd },
1396 { 0x12, 0x403003fe },
1397 {}
dfe495d0
TI
1398};
1399
1400/*
1401 STAC 9200-32
1402 102801CD (Dell Inspiron E1705/9400)
1403*/
d39a3ae8
TI
1404static const struct hda_pintbl dell9200_m27_pin_configs[] = {
1405 { 0x08, 0x40c003fa },
1406 { 0x09, 0x01441340 },
1407 { 0x0d, 0x0421121f },
1408 { 0x0e, 0x90170310 },
1409 { 0x0f, 0x90170310 },
1410 { 0x10, 0x04a11020 },
1411 { 0x11, 0x90170310 },
1412 { 0x12, 0x40f003fc },
1413 {}
dfe495d0
TI
1414};
1415
d39a3ae8
TI
1416static const struct hda_pintbl oqo9200_pin_configs[] = {
1417 { 0x08, 0x40c000f0 },
1418 { 0x09, 0x404000f1 },
1419 { 0x0d, 0x0221121f },
1420 { 0x0e, 0x02211210 },
1421 { 0x0f, 0x90170111 },
1422 { 0x10, 0x90a70120 },
1423 { 0x11, 0x400000f2 },
1424 { 0x12, 0x400000f3 },
1425 {}
bf277785
TD
1426};
1427
dfe495d0 1428
d39a3ae8
TI
1429static void stac9200_fixup_panasonic(struct hda_codec *codec,
1430 const struct hda_fixup *fix, int action)
1431{
1432 struct sigmatel_spec *spec = codec->spec;
1433
1434 switch (action) {
1435 case HDA_FIXUP_ACT_PRE_PROBE:
1436 spec->gpio_mask = spec->gpio_dir = 0x09;
1437 spec->gpio_data = 0x00;
1438 break;
1439 case HDA_FIXUP_ACT_PROBE:
1440 /* CF-74 has no headphone detection, and the driver should *NOT*
1441 * do detection and HP/speaker toggle because the hardware does it.
1442 */
1443 spec->hp_detect = 0;
1444 break;
1445 }
1446}
1447
1448
1449static const struct hda_fixup stac9200_fixups[] = {
1450 [STAC_REF] = {
1451 .type = HDA_FIXUP_PINS,
1452 .v.pins = ref9200_pin_configs,
1453 },
1454 [STAC_9200_OQO] = {
1455 .type = HDA_FIXUP_PINS,
1456 .v.pins = oqo9200_pin_configs,
1457 .chained = true,
1458 .chain_id = STAC_9200_EAPD_INIT,
1459 },
1460 [STAC_9200_DELL_D21] = {
1461 .type = HDA_FIXUP_PINS,
1462 .v.pins = dell9200_d21_pin_configs,
1463 },
1464 [STAC_9200_DELL_D22] = {
1465 .type = HDA_FIXUP_PINS,
1466 .v.pins = dell9200_d22_pin_configs,
1467 },
1468 [STAC_9200_DELL_D23] = {
1469 .type = HDA_FIXUP_PINS,
1470 .v.pins = dell9200_d23_pin_configs,
1471 },
1472 [STAC_9200_DELL_M21] = {
1473 .type = HDA_FIXUP_PINS,
1474 .v.pins = dell9200_m21_pin_configs,
1475 },
1476 [STAC_9200_DELL_M22] = {
1477 .type = HDA_FIXUP_PINS,
1478 .v.pins = dell9200_m22_pin_configs,
1479 },
1480 [STAC_9200_DELL_M23] = {
1481 .type = HDA_FIXUP_PINS,
1482 .v.pins = dell9200_m23_pin_configs,
1483 },
1484 [STAC_9200_DELL_M24] = {
1485 .type = HDA_FIXUP_PINS,
1486 .v.pins = dell9200_m24_pin_configs,
1487 },
1488 [STAC_9200_DELL_M25] = {
1489 .type = HDA_FIXUP_PINS,
1490 .v.pins = dell9200_m25_pin_configs,
1491 },
1492 [STAC_9200_DELL_M26] = {
1493 .type = HDA_FIXUP_PINS,
1494 .v.pins = dell9200_m26_pin_configs,
1495 },
1496 [STAC_9200_DELL_M27] = {
1497 .type = HDA_FIXUP_PINS,
1498 .v.pins = dell9200_m27_pin_configs,
1499 },
1500 [STAC_9200_M4] = {
1501 .type = HDA_FIXUP_PINS,
1502 .v.pins = gateway9200_m4_pin_configs,
1503 .chained = true,
1504 .chain_id = STAC_9200_EAPD_INIT,
1505 },
1506 [STAC_9200_M4_2] = {
1507 .type = HDA_FIXUP_PINS,
1508 .v.pins = gateway9200_m4_2_pin_configs,
1509 .chained = true,
1510 .chain_id = STAC_9200_EAPD_INIT,
1511 },
1512 [STAC_9200_PANASONIC] = {
1513 .type = HDA_FIXUP_FUNC,
1514 .v.func = stac9200_fixup_panasonic,
1515 },
1516 [STAC_9200_EAPD_INIT] = {
1517 .type = HDA_FIXUP_VERBS,
1518 .v.verbs = (const struct hda_verb[]) {
1519 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1520 {}
1521 },
1522 },
403d1944
MP
1523};
1524
d39a3ae8
TI
1525static const struct hda_model_fixup stac9200_models[] = {
1526 { .id = STAC_REF, .name = "ref" },
1527 { .id = STAC_9200_OQO, .name = "oqo" },
1528 { .id = STAC_9200_DELL_D21, .name = "dell-d21" },
1529 { .id = STAC_9200_DELL_D22, .name = "dell-d22" },
1530 { .id = STAC_9200_DELL_D23, .name = "dell-d23" },
1531 { .id = STAC_9200_DELL_M21, .name = "dell-m21" },
1532 { .id = STAC_9200_DELL_M22, .name = "dell-m22" },
1533 { .id = STAC_9200_DELL_M23, .name = "dell-m23" },
1534 { .id = STAC_9200_DELL_M24, .name = "dell-m24" },
1535 { .id = STAC_9200_DELL_M25, .name = "dell-m25" },
1536 { .id = STAC_9200_DELL_M26, .name = "dell-m26" },
1537 { .id = STAC_9200_DELL_M27, .name = "dell-m27" },
1538 { .id = STAC_9200_M4, .name = "gateway-m4" },
1539 { .id = STAC_9200_M4_2, .name = "gateway-m4-2" },
1540 { .id = STAC_9200_PANASONIC, .name = "panasonic" },
1541 {}
1542};
1543
1544static const struct snd_pci_quirk stac9200_fixup_tbl[] = {
f5fcc13c
TI
1545 /* SigmaTel reference board */
1546 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1547 "DFI LanParty", STAC_REF),
577aa2c1
MR
1548 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1549 "DFI LanParty", STAC_REF),
e7377071 1550 /* Dell laptops have BIOS problem */
dfe495d0
TI
1551 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1552 "unknown Dell", STAC_9200_DELL_D21),
f5fcc13c 1553 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
dfe495d0
TI
1554 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1555 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1556 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1557 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1558 "unknown Dell", STAC_9200_DELL_D22),
1559 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1560 "unknown Dell", STAC_9200_DELL_D22),
f5fcc13c 1561 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
dfe495d0
TI
1562 "Dell Latitude D620", STAC_9200_DELL_M22),
1563 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1564 "unknown Dell", STAC_9200_DELL_D23),
1565 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1566 "unknown Dell", STAC_9200_DELL_D23),
1567 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1568 "unknown Dell", STAC_9200_DELL_M22),
1569 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1570 "unknown Dell", STAC_9200_DELL_M24),
1571 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1572 "unknown Dell", STAC_9200_DELL_M24),
f5fcc13c 1573 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
dfe495d0 1574 "Dell Latitude 120L", STAC_9200_DELL_M24),
877b866d 1575 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
dfe495d0 1576 "Dell Latitude D820", STAC_9200_DELL_M22),
46f02ca3 1577 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
dfe495d0 1578 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
46f02ca3 1579 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
dfe495d0 1580 "Dell XPS M1710", STAC_9200_DELL_M23),
f0f96745 1581 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
dfe495d0
TI
1582 "Dell Precision M90", STAC_9200_DELL_M23),
1583 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1584 "unknown Dell", STAC_9200_DELL_M22),
1585 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1586 "unknown Dell", STAC_9200_DELL_M22),
8286c53e 1587 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
dfe495d0 1588 "unknown Dell", STAC_9200_DELL_M22),
49c605db 1589 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
dfe495d0
TI
1590 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1591 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1592 "unknown Dell", STAC_9200_DELL_D23),
1593 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1594 "unknown Dell", STAC_9200_DELL_D23),
1595 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1596 "unknown Dell", STAC_9200_DELL_D21),
1597 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1598 "unknown Dell", STAC_9200_DELL_D23),
1599 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1600 "unknown Dell", STAC_9200_DELL_D21),
1601 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1602 "unknown Dell", STAC_9200_DELL_M25),
1603 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1604 "unknown Dell", STAC_9200_DELL_M25),
49c605db 1605 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
dfe495d0
TI
1606 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1607 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1608 "unknown Dell", STAC_9200_DELL_M26),
49c605db 1609 /* Panasonic */
117f257d 1610 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1194b5b7 1611 /* Gateway machines needs EAPD to be set on resume */
58eec423
MCC
1612 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
1613 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
1614 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
bf277785
TD
1615 /* OQO Mobile */
1616 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
403d1944
MP
1617 {} /* terminator */
1618};
1619
d2077d40
TI
1620static const struct hda_pintbl ref925x_pin_configs[] = {
1621 { 0x07, 0x40c003f0 },
1622 { 0x08, 0x424503f2 },
1623 { 0x0a, 0x01813022 },
1624 { 0x0b, 0x02a19021 },
1625 { 0x0c, 0x90a70320 },
1626 { 0x0d, 0x02214210 },
1627 { 0x10, 0x01019020 },
1628 { 0x11, 0x9033032e },
1629 {}
8e21c34c
TD
1630};
1631
d2077d40
TI
1632static const struct hda_pintbl stac925xM1_pin_configs[] = {
1633 { 0x07, 0x40c003f4 },
1634 { 0x08, 0x424503f2 },
1635 { 0x0a, 0x400000f3 },
1636 { 0x0b, 0x02a19020 },
1637 { 0x0c, 0x40a000f0 },
1638 { 0x0d, 0x90100210 },
1639 { 0x10, 0x400003f1 },
1640 { 0x11, 0x9033032e },
1641 {}
8e21c34c
TD
1642};
1643
d2077d40
TI
1644static const struct hda_pintbl stac925xM1_2_pin_configs[] = {
1645 { 0x07, 0x40c003f4 },
1646 { 0x08, 0x424503f2 },
1647 { 0x0a, 0x400000f3 },
1648 { 0x0b, 0x02a19020 },
1649 { 0x0c, 0x40a000f0 },
1650 { 0x0d, 0x90100210 },
1651 { 0x10, 0x400003f1 },
1652 { 0x11, 0x9033032e },
1653 {}
9cb36c2a 1654};
58eec423 1655
d2077d40
TI
1656static const struct hda_pintbl stac925xM2_pin_configs[] = {
1657 { 0x07, 0x40c003f4 },
1658 { 0x08, 0x424503f2 },
1659 { 0x0a, 0x400000f3 },
1660 { 0x0b, 0x02a19020 },
1661 { 0x0c, 0x40a000f0 },
1662 { 0x0d, 0x90100210 },
1663 { 0x10, 0x400003f1 },
1664 { 0x11, 0x9033032e },
1665 {}
2c11f955
TD
1666};
1667
d2077d40
TI
1668static const struct hda_pintbl stac925xM2_2_pin_configs[] = {
1669 { 0x07, 0x40c003f4 },
1670 { 0x08, 0x424503f2 },
1671 { 0x0a, 0x400000f3 },
1672 { 0x0b, 0x02a19020 },
1673 { 0x0c, 0x40a000f0 },
1674 { 0x0d, 0x90100210 },
1675 { 0x10, 0x400003f1 },
1676 { 0x11, 0x9033032e },
1677 {}
58eec423
MCC
1678};
1679
d2077d40
TI
1680static const struct hda_pintbl stac925xM3_pin_configs[] = {
1681 { 0x07, 0x40c003f4 },
1682 { 0x08, 0x424503f2 },
1683 { 0x0a, 0x400000f3 },
1684 { 0x0b, 0x02a19020 },
1685 { 0x0c, 0x40a000f0 },
1686 { 0x0d, 0x90100210 },
1687 { 0x10, 0x400003f1 },
1688 { 0x11, 0x503303f3 },
1689 {}
9cb36c2a 1690};
58eec423 1691
d2077d40
TI
1692static const struct hda_pintbl stac925xM5_pin_configs[] = {
1693 { 0x07, 0x40c003f4 },
1694 { 0x08, 0x424503f2 },
1695 { 0x0a, 0x400000f3 },
1696 { 0x0b, 0x02a19020 },
1697 { 0x0c, 0x40a000f0 },
1698 { 0x0d, 0x90100210 },
1699 { 0x10, 0x400003f1 },
1700 { 0x11, 0x9033032e },
1701 {}
9cb36c2a
MCC
1702};
1703
d2077d40
TI
1704static const struct hda_pintbl stac925xM6_pin_configs[] = {
1705 { 0x07, 0x40c003f4 },
1706 { 0x08, 0x424503f2 },
1707 { 0x0a, 0x400000f3 },
1708 { 0x0b, 0x02a19020 },
1709 { 0x0c, 0x40a000f0 },
1710 { 0x0d, 0x90100210 },
1711 { 0x10, 0x400003f1 },
1712 { 0x11, 0x90330320 },
1713 {}
8e21c34c
TD
1714};
1715
d2077d40
TI
1716static const struct hda_fixup stac925x_fixups[] = {
1717 [STAC_REF] = {
1718 .type = HDA_FIXUP_PINS,
1719 .v.pins = ref925x_pin_configs,
1720 },
1721 [STAC_M1] = {
1722 .type = HDA_FIXUP_PINS,
1723 .v.pins = stac925xM1_pin_configs,
1724 },
1725 [STAC_M1_2] = {
1726 .type = HDA_FIXUP_PINS,
1727 .v.pins = stac925xM1_2_pin_configs,
1728 },
1729 [STAC_M2] = {
1730 .type = HDA_FIXUP_PINS,
1731 .v.pins = stac925xM2_pin_configs,
1732 },
1733 [STAC_M2_2] = {
1734 .type = HDA_FIXUP_PINS,
1735 .v.pins = stac925xM2_2_pin_configs,
1736 },
1737 [STAC_M3] = {
1738 .type = HDA_FIXUP_PINS,
1739 .v.pins = stac925xM3_pin_configs,
1740 },
1741 [STAC_M5] = {
1742 .type = HDA_FIXUP_PINS,
1743 .v.pins = stac925xM5_pin_configs,
1744 },
1745 [STAC_M6] = {
1746 .type = HDA_FIXUP_PINS,
1747 .v.pins = stac925xM6_pin_configs,
1748 },
8e21c34c
TD
1749};
1750
d2077d40
TI
1751static const struct hda_model_fixup stac925x_models[] = {
1752 { .id = STAC_REF, .name = "ref" },
1753 { .id = STAC_M1, .name = "m1" },
1754 { .id = STAC_M1_2, .name = "m1-2" },
1755 { .id = STAC_M2, .name = "m2" },
1756 { .id = STAC_M2_2, .name = "m2-2" },
1757 { .id = STAC_M3, .name = "m3" },
1758 { .id = STAC_M5, .name = "m5" },
1759 { .id = STAC_M6, .name = "m6" },
1760 {}
8e21c34c
TD
1761};
1762
d2077d40
TI
1763static const struct snd_pci_quirk stac925x_fixup_tbl[] = {
1764 /* SigmaTel reference board */
1765 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1766 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
1767 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
1768
1769 /* Default table for unknown ID */
1770 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
1771
1772 /* gateway machines are checked via codec ssid */
58eec423
MCC
1773 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1774 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1775 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
1776 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
9cb36c2a 1777 SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
9cb36c2a
MCC
1778 /* Not sure about the brand name for those */
1779 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
1780 SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
1781 SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
1782 SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
9cb36c2a 1783 {} /* terminator */
8e21c34c
TD
1784};
1785
55e30141
TI
1786static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
1787 { 0x0a, 0x02214030 },
1788 { 0x0b, 0x02a19040 },
1789 { 0x0c, 0x01a19020 },
1790 { 0x0d, 0x02214030 },
1791 { 0x0e, 0x0181302e },
1792 { 0x0f, 0x01014010 },
1793 { 0x10, 0x01014020 },
1794 { 0x11, 0x01014030 },
1795 { 0x12, 0x02319040 },
1796 { 0x13, 0x90a000f0 },
1797 { 0x14, 0x90a000f0 },
1798 { 0x22, 0x01452050 },
1799 { 0x23, 0x01452050 },
1800 {}
a7662640
MR
1801};
1802
55e30141
TI
1803static const struct hda_pintbl dell_m6_pin_configs[] = {
1804 { 0x0a, 0x0321101f },
1805 { 0x0b, 0x4f00000f },
1806 { 0x0c, 0x4f0000f0 },
1807 { 0x0d, 0x90170110 },
1808 { 0x0e, 0x03a11020 },
1809 { 0x0f, 0x0321101f },
1810 { 0x10, 0x4f0000f0 },
1811 { 0x11, 0x4f0000f0 },
1812 { 0x12, 0x4f0000f0 },
1813 { 0x13, 0x90a60160 },
1814 { 0x14, 0x4f0000f0 },
1815 { 0x22, 0x4f0000f0 },
1816 { 0x23, 0x4f0000f0 },
1817 {}
e1f0d669
MR
1818};
1819
55e30141
TI
1820static const struct hda_pintbl alienware_m17x_pin_configs[] = {
1821 { 0x0a, 0x0321101f },
1822 { 0x0b, 0x0321101f },
1823 { 0x0c, 0x03a11020 },
1824 { 0x0d, 0x03014020 },
1825 { 0x0e, 0x90170110 },
1826 { 0x0f, 0x4f0000f0 },
1827 { 0x10, 0x4f0000f0 },
1828 { 0x11, 0x4f0000f0 },
1829 { 0x12, 0x4f0000f0 },
1830 { 0x13, 0x90a60160 },
1831 { 0x14, 0x4f0000f0 },
1832 { 0x22, 0x4f0000f0 },
1833 { 0x23, 0x904601b0 },
1834 {}
842ae638
TI
1835};
1836
55e30141
TI
1837static const struct hda_pintbl intel_dg45id_pin_configs[] = {
1838 { 0x0a, 0x02214230 },
1839 { 0x0b, 0x02A19240 },
1840 { 0x0c, 0x01013214 },
1841 { 0x0d, 0x01014210 },
1842 { 0x0e, 0x01A19250 },
1843 { 0x0f, 0x01011212 },
1844 { 0x10, 0x01016211 },
1845 {}
52dc4386
AF
1846};
1847
55e30141
TI
1848static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
1849 const struct hda_fixup *fix, int action)
1850{
1851 struct sigmatel_spec *spec = codec->spec;
1852
1853 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1854 return;
1855
1856 snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs);
1857 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
1858}
1859
1860static void stac92hd73xx_fixup_dell(struct hda_codec *codec)
1861{
1862 struct sigmatel_spec *spec = codec->spec;
1863
1864 snd_hda_apply_pincfgs(codec, dell_m6_pin_configs);
1865 spec->num_smuxes = 0;
1866 spec->eapd_switch = 0;
1867}
1868
1869static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec,
1870 const struct hda_fixup *fix, int action)
1871{
1872 struct sigmatel_spec *spec = codec->spec;
1873
1874 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1875 return;
1876
1877 stac92hd73xx_fixup_dell(codec);
1878 snd_hda_add_verbs(codec, dell_eq_core_init);
1879 spec->volknob_init = 1;
1880}
1881
1882/* Analog Mics */
1883static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec,
1884 const struct hda_fixup *fix, int action)
1885{
1886 struct sigmatel_spec *spec = codec->spec;
1887
1888 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1889 return;
1890
1891 stac92hd73xx_fixup_dell(codec);
1892 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1893 spec->num_dmics = 0;
1894}
1895
1896/* Digital Mics */
1897static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec,
1898 const struct hda_fixup *fix, int action)
1899{
1900 struct sigmatel_spec *spec = codec->spec;
1901
1902 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1903 return;
1904
1905 stac92hd73xx_fixup_dell(codec);
1906 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1907 spec->num_dmics = 1;
1908}
1909
1910/* Both */
1911static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec,
1912 const struct hda_fixup *fix, int action)
1913{
1914 struct sigmatel_spec *spec = codec->spec;
1915
1916 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1917 return;
1918
1919 stac92hd73xx_fixup_dell(codec);
1920 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
1921 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
1922 spec->num_dmics = 1;
1923}
1924
1925static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec,
1926 const struct hda_fixup *fix, int action)
1927{
1928 struct sigmatel_spec *spec = codec->spec;
1929
1930 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1931 return;
1932
1933 snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs);
1934 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
1935 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
1936 spec->eapd_switch = 0;
1937}
1938
1939static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec,
1940 const struct hda_fixup *fix, int action)
1941{
1942 struct sigmatel_spec *spec = codec->spec;
1943
1944 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1945 return;
1946 spec->hp_detect = 0;
1947}
1948
1949static const struct hda_fixup stac92hd73xx_fixups[] = {
1950 [STAC_92HD73XX_REF] = {
1951 .type = HDA_FIXUP_FUNC,
1952 .v.func = stac92hd73xx_fixup_ref,
1953 },
1954 [STAC_DELL_M6_AMIC] = {
1955 .type = HDA_FIXUP_FUNC,
1956 .v.func = stac92hd73xx_fixup_dell_m6_amic,
1957 },
1958 [STAC_DELL_M6_DMIC] = {
1959 .type = HDA_FIXUP_FUNC,
1960 .v.func = stac92hd73xx_fixup_dell_m6_dmic,
1961 },
1962 [STAC_DELL_M6_BOTH] = {
1963 .type = HDA_FIXUP_FUNC,
1964 .v.func = stac92hd73xx_fixup_dell_m6_both,
1965 },
1966 [STAC_DELL_EQ] = {
1967 .type = HDA_FIXUP_FUNC,
1968 .v.func = stac92hd73xx_fixup_dell_eq,
1969 },
1970 [STAC_ALIENWARE_M17X] = {
1971 .type = HDA_FIXUP_FUNC,
1972 .v.func = stac92hd73xx_fixup_alienware_m17x,
1973 },
1974 [STAC_92HD73XX_INTEL] = {
1975 .type = HDA_FIXUP_PINS,
1976 .v.pins = intel_dg45id_pin_configs,
1977 },
1978 [STAC_92HD73XX_NO_JD] = {
1979 .type = HDA_FIXUP_FUNC,
1980 .v.func = stac92hd73xx_fixup_no_jd,
1981 }
e1f0d669
MR
1982};
1983
55e30141
TI
1984static const struct hda_model_fixup stac92hd73xx_models[] = {
1985 { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" },
1986 { .id = STAC_92HD73XX_REF, .name = "ref" },
1987 { .id = STAC_92HD73XX_INTEL, .name = "intel" },
1988 { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" },
1989 { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" },
1990 { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
1991 { .id = STAC_DELL_EQ, .name = "dell-eq" },
1992 { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
1993 {}
e1f0d669
MR
1994};
1995
55e30141 1996static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
e1f0d669
MR
1997 /* SigmaTel reference board */
1998 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
a7662640 1999 "DFI LanParty", STAC_92HD73XX_REF),
577aa2c1
MR
2000 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2001 "DFI LanParty", STAC_92HD73XX_REF),
ae709440
WF
2002 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
2003 "Intel DG45ID", STAC_92HD73XX_INTEL),
2004 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
2005 "Intel DG45FC", STAC_92HD73XX_INTEL),
a7662640 2006 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
661cd8fb 2007 "Dell Studio 1535", STAC_DELL_M6_DMIC),
a7662640 2008 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
661cd8fb 2009 "unknown Dell", STAC_DELL_M6_DMIC),
a7662640 2010 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
661cd8fb 2011 "unknown Dell", STAC_DELL_M6_BOTH),
a7662640 2012 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
661cd8fb 2013 "unknown Dell", STAC_DELL_M6_BOTH),
a7662640 2014 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
661cd8fb 2015 "unknown Dell", STAC_DELL_M6_AMIC),
a7662640 2016 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
661cd8fb 2017 "unknown Dell", STAC_DELL_M6_AMIC),
a7662640 2018 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
661cd8fb
TI
2019 "unknown Dell", STAC_DELL_M6_DMIC),
2020 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
2021 "unknown Dell", STAC_DELL_M6_DMIC),
b0fc5e04 2022 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
661cd8fb 2023 "Dell Studio 1537", STAC_DELL_M6_DMIC),
fa620e97
JS
2024 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
2025 "Dell Studio 17", STAC_DELL_M6_DMIC),
626f5cef
TI
2026 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
2027 "Dell Studio 1555", STAC_DELL_M6_DMIC),
8ef5837a
DB
2028 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
2029 "Dell Studio 1557", STAC_DELL_M6_DMIC),
aac78daf 2030 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
ffe535ed 2031 "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
5c1bccf6 2032 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
e033ebfb 2033 "Dell Studio 1558", STAC_DELL_M6_DMIC),
55e30141 2034 /* codec SSID matching */
842ae638
TI
2035 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
2036 "Alienware M17x", STAC_ALIENWARE_M17X),
0defe09c
DC
2037 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
2038 "Alienware M17x", STAC_ALIENWARE_M17X),
dbd1b547 2039 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
b9ecc4ee 2040 "Alienware M17x R3", STAC_DELL_EQ),
842ae638
TI
2041 {} /* terminator */
2042};
2043
372f8c75
TI
2044static const struct hda_pintbl ref92hd83xxx_pin_configs[] = {
2045 { 0x0a, 0x02214030 },
2046 { 0x0b, 0x02211010 },
2047 { 0x0c, 0x02a19020 },
2048 { 0x0d, 0x02170130 },
2049 { 0x0e, 0x01014050 },
2050 { 0x0f, 0x01819040 },
2051 { 0x10, 0x01014020 },
2052 { 0x11, 0x90a3014e },
2053 { 0x1f, 0x01451160 },
2054 { 0x20, 0x98560170 },
2055 {}
d0513fc6
MR
2056};
2057
372f8c75
TI
2058static const struct hda_pintbl dell_s14_pin_configs[] = {
2059 { 0x0a, 0x0221403f },
2060 { 0x0b, 0x0221101f },
2061 { 0x0c, 0x02a19020 },
2062 { 0x0d, 0x90170110 },
2063 { 0x0e, 0x40f000f0 },
2064 { 0x0f, 0x40f000f0 },
2065 { 0x10, 0x40f000f0 },
2066 { 0x11, 0x90a60160 },
2067 { 0x1f, 0x40f000f0 },
2068 { 0x20, 0x40f000f0 },
2069 {}
8bb0ac55
MR
2070};
2071
372f8c75
TI
2072static const struct hda_pintbl dell_vostro_3500_pin_configs[] = {
2073 { 0x0a, 0x02a11020 },
2074 { 0x0b, 0x0221101f },
2075 { 0x0c, 0x400000f0 },
2076 { 0x0d, 0x90170110 },
2077 { 0x0e, 0x400000f1 },
2078 { 0x0f, 0x400000f2 },
2079 { 0x10, 0x400000f3 },
2080 { 0x11, 0x90a60160 },
2081 { 0x1f, 0x400000f4 },
2082 { 0x20, 0x400000f5 },
2083 {}
f7f9bdfa
JW
2084};
2085
372f8c75
TI
2086static const struct hda_pintbl hp_dv7_4000_pin_configs[] = {
2087 { 0x0a, 0x03a12050 },
2088 { 0x0b, 0x0321201f },
2089 { 0x0c, 0x40f000f0 },
2090 { 0x0d, 0x90170110 },
2091 { 0x0e, 0x40f000f0 },
2092 { 0x0f, 0x40f000f0 },
2093 { 0x10, 0x90170110 },
2094 { 0x11, 0xd5a30140 },
2095 { 0x1f, 0x40f000f0 },
2096 { 0x20, 0x40f000f0 },
2097 {}
48315590
SE
2098};
2099
372f8c75
TI
2100static const struct hda_pintbl hp_zephyr_pin_configs[] = {
2101 { 0x0a, 0x01813050 },
2102 { 0x0b, 0x0421201f },
2103 { 0x0c, 0x04a1205e },
2104 { 0x0d, 0x96130310 },
2105 { 0x0e, 0x96130310 },
2106 { 0x0f, 0x0101401f },
2107 { 0x10, 0x1111611f },
2108 { 0x11, 0xd5a30130 },
2109 {}
5556e147
VK
2110};
2111
372f8c75
TI
2112static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = {
2113 { 0x0a, 0x40f000f0 },
2114 { 0x0b, 0x0221101f },
2115 { 0x0c, 0x02a11020 },
2116 { 0x0d, 0x92170110 },
2117 { 0x0e, 0x40f000f0 },
2118 { 0x0f, 0x92170110 },
2119 { 0x10, 0x40f000f0 },
2120 { 0x11, 0xd5a30130 },
2121 { 0x1f, 0x40f000f0 },
2122 { 0x20, 0x40f000f0 },
2123 {}
0c27c180
VK
2124};
2125
372f8c75
TI
2126static void stac92hd83xxx_fixup_hp(struct hda_codec *codec,
2127 const struct hda_fixup *fix, int action)
2128{
2129 struct sigmatel_spec *spec = codec->spec;
2130
2131 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2132 return;
2133
2134 if (hp_bnb2011_with_dock(codec)) {
2135 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
2136 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
2137 }
2138
2139 if (find_mute_led_cfg(codec, spec->default_polarity))
2140 snd_printd("mute LED gpio %d polarity %d\n",
2141 spec->gpio_led,
2142 spec->gpio_led_polarity);
2143}
2144
2145static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec,
2146 const struct hda_fixup *fix, int action)
2147{
2148 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2149 return;
2150
2151 snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs);
2152 snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init);
2153}
2154
2155static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec,
2156 const struct hda_fixup *fix, int action)
2157{
2158 struct sigmatel_spec *spec = codec->spec;
2159
2160 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2161 spec->default_polarity = 0;
2162}
2163
2164static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec,
2165 const struct hda_fixup *fix, int action)
2166{
2167 struct sigmatel_spec *spec = codec->spec;
2168
2169 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2170 spec->default_polarity = 1;
2171}
2172
2173static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
2174 const struct hda_fixup *fix, int action)
2175{
2176 struct sigmatel_spec *spec = codec->spec;
2177
2178 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2179 spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
2180}
2181
2182static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec,
2183 const struct hda_fixup *fix, int action)
2184{
2185 struct sigmatel_spec *spec = codec->spec;
2186
2187 if (action == HDA_FIXUP_ACT_PRE_PROBE)
2188 spec->headset_jack = 1;
2189}
2190
2191static const struct hda_fixup stac92hd83xxx_fixups[] = {
2192 [STAC_92HD83XXX_REF] = {
2193 .type = HDA_FIXUP_PINS,
2194 .v.pins = ref92hd83xxx_pin_configs,
2195 },
2196 [STAC_92HD83XXX_PWR_REF] = {
2197 .type = HDA_FIXUP_PINS,
2198 .v.pins = ref92hd83xxx_pin_configs,
2199 },
2200 [STAC_DELL_S14] = {
2201 .type = HDA_FIXUP_PINS,
2202 .v.pins = dell_s14_pin_configs,
2203 },
2204 [STAC_DELL_VOSTRO_3500] = {
2205 .type = HDA_FIXUP_PINS,
2206 .v.pins = dell_vostro_3500_pin_configs,
2207 },
2208 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = {
2209 .type = HDA_FIXUP_PINS,
2210 .v.pins = hp_cNB11_intquad_pin_configs,
2211 .chained = true,
2212 .chain_id = STAC_92HD83XXX_HP,
2213 },
2214 [STAC_92HD83XXX_HP] = {
2215 .type = HDA_FIXUP_FUNC,
2216 .v.func = stac92hd83xxx_fixup_hp,
2217 },
2218 [STAC_HP_DV7_4000] = {
2219 .type = HDA_FIXUP_PINS,
2220 .v.pins = hp_dv7_4000_pin_configs,
2221 .chained = true,
2222 .chain_id = STAC_92HD83XXX_HP,
2223 },
2224 [STAC_HP_ZEPHYR] = {
2225 .type = HDA_FIXUP_FUNC,
2226 .v.func = stac92hd83xxx_fixup_hp_zephyr,
2227 .chained = true,
2228 .chain_id = STAC_92HD83XXX_HP,
2229 },
2230 [STAC_92HD83XXX_HP_LED] = {
2231 .type = HDA_FIXUP_FUNC,
2232 .v.func = stac92hd83xxx_fixup_hp_led,
2233 .chained = true,
2234 .chain_id = STAC_92HD83XXX_HP,
2235 },
2236 [STAC_92HD83XXX_HP_INV_LED] = {
2237 .type = HDA_FIXUP_FUNC,
2238 .v.func = stac92hd83xxx_fixup_hp_inv_led,
2239 .chained = true,
2240 .chain_id = STAC_92HD83XXX_HP,
2241 },
2242 [STAC_92HD83XXX_HP_MIC_LED] = {
2243 .type = HDA_FIXUP_FUNC,
2244 .v.func = stac92hd83xxx_fixup_hp_mic_led,
2245 .chained = true,
2246 .chain_id = STAC_92HD83XXX_HP,
2247 },
2248 [STAC_92HD83XXX_HEADSET_JACK] = {
2249 .type = HDA_FIXUP_FUNC,
2250 .v.func = stac92hd83xxx_fixup_headset_jack,
2251 },
d0513fc6
MR
2252};
2253
372f8c75
TI
2254static const struct hda_model_fixup stac92hd83xxx_models[] = {
2255 { .id = STAC_92HD83XXX_REF, .name = "ref" },
2256 { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" },
2257 { .id = STAC_DELL_S14, .name = "dell-s14" },
2258 { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" },
2259 { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" },
2260 { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" },
2261 { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" },
2262 { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" },
2263 { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" },
2264 { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" },
2265 { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
2266 {}
d0513fc6
MR
2267};
2268
372f8c75 2269static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
d0513fc6
MR
2270 /* SigmaTel reference board */
2271 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
f9d088b2 2272 "DFI LanParty", STAC_92HD83XXX_REF),
577aa2c1
MR
2273 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2274 "DFI LanParty", STAC_92HD83XXX_REF),
8bb0ac55
MR
2275 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
2276 "unknown Dell", STAC_DELL_S14),
8d032a8f
DH
2277 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
2278 "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
2279 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
2280 "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
2281 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
2282 "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
2283 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
2284 "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
2285 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
2286 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2287 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
2288 "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
2289 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
2290 "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
2291 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
2292 "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
2293 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
2294 "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
f7f9bdfa
JW
2295 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
2296 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
0c27c180
VK
2297 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
2298 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2299 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
2300 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2301 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
2302 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2303 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
8ae5865e 2304 "HP Pavilion dv7", STAC_HP_DV7_4000),
0c27c180
VK
2305 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
2306 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2307 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
2308 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
62cbde18
TI
2309 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
2310 "HP Folio", STAC_92HD83XXX_HP_MIC_LED),
0c27c180
VK
2311 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2312 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2313 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
2314 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2315 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
2316 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2317 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
2318 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2319 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
2320 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2321 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
2322 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2323 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
2324 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2325 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
2326 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2327 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
2328 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2329 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
2330 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2331 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
2332 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2333 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
2334 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2335 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
2336 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2337 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
2338 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
5556e147
VK
2339 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
2340 "HP", STAC_HP_ZEPHYR),
a3e19973
TI
2341 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
2342 "HP Mini", STAC_92HD83XXX_HP_LED),
5afc13af
GMDV
2343 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
2344 "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
8c698fe2
TI
2345 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a,
2346 "HP Mini", STAC_92HD83XXX_HP_LED),
372f8c75 2347 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP),
574f3c4f 2348 {} /* terminator */
d0513fc6
MR
2349};
2350
0f6fcb73
TI
2351static const struct hda_pintbl ref92hd71bxx_pin_configs[] = {
2352 { 0x0a, 0x02214030 },
2353 { 0x0b, 0x02a19040 },
2354 { 0x0c, 0x01a19020 },
2355 { 0x0d, 0x01014010 },
2356 { 0x0e, 0x0181302e },
2357 { 0x0f, 0x01014010 },
2358 { 0x14, 0x01019020 },
2359 { 0x18, 0x90a000f0 },
2360 { 0x19, 0x90a000f0 },
2361 { 0x1e, 0x01452050 },
2362 { 0x1f, 0x01452050 },
2363 {}
e035b841
MR
2364};
2365
0f6fcb73
TI
2366static const struct hda_pintbl dell_m4_1_pin_configs[] = {
2367 { 0x0a, 0x0421101f },
2368 { 0x0b, 0x04a11221 },
2369 { 0x0c, 0x40f000f0 },
2370 { 0x0d, 0x90170110 },
2371 { 0x0e, 0x23a1902e },
2372 { 0x0f, 0x23014250 },
2373 { 0x14, 0x40f000f0 },
2374 { 0x18, 0x90a000f0 },
2375 { 0x19, 0x40f000f0 },
2376 { 0x1e, 0x4f0000f0 },
2377 { 0x1f, 0x4f0000f0 },
2378 {}
a7662640
MR
2379};
2380
0f6fcb73
TI
2381static const struct hda_pintbl dell_m4_2_pin_configs[] = {
2382 { 0x0a, 0x0421101f },
2383 { 0x0b, 0x04a11221 },
2384 { 0x0c, 0x90a70330 },
2385 { 0x0d, 0x90170110 },
2386 { 0x0e, 0x23a1902e },
2387 { 0x0f, 0x23014250 },
2388 { 0x14, 0x40f000f0 },
2389 { 0x18, 0x40f000f0 },
2390 { 0x19, 0x40f000f0 },
2391 { 0x1e, 0x044413b0 },
2392 { 0x1f, 0x044413b0 },
2393 {}
a7662640
MR
2394};
2395
0f6fcb73
TI
2396static const struct hda_pintbl dell_m4_3_pin_configs[] = {
2397 { 0x0a, 0x0421101f },
2398 { 0x0b, 0x04a11221 },
2399 { 0x0c, 0x90a70330 },
2400 { 0x0d, 0x90170110 },
2401 { 0x0e, 0x40f000f0 },
2402 { 0x0f, 0x40f000f0 },
2403 { 0x14, 0x40f000f0 },
2404 { 0x18, 0x90a000f0 },
2405 { 0x19, 0x40f000f0 },
2406 { 0x1e, 0x044413b0 },
2407 { 0x1f, 0x044413b0 },
2408 {}
3a7abfd2
MR
2409};
2410
0f6fcb73
TI
2411static void stac92hd71bxx_fixup_ref(struct hda_codec *codec,
2412 const struct hda_fixup *fix, int action)
2413{
2414 struct sigmatel_spec *spec = codec->spec;
2415
2416 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2417 return;
2418
2419 snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs);
2420 spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0;
2421}
2422
2423static void stac92hd71bxx_fixup_no_dmic(struct hda_codec *codec,
2424 const struct hda_fixup *fix, int action)
2425{
2426 struct sigmatel_spec *spec = codec->spec;
2427
2428 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2429 return;
2430 spec->num_dmics = 0;
2431 spec->num_smuxes = 0;
2432 spec->num_dmuxes = 0;
2433}
2434
2435static void stac92hd71bxx_fixup_no_smux(struct hda_codec *codec,
2436 const struct hda_fixup *fix, int action)
2437{
2438 struct sigmatel_spec *spec = codec->spec;
2439
2440 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2441 return;
2442 spec->num_dmics = 1;
2443 spec->num_smuxes = 0;
2444 spec->num_dmuxes = 1;
2445}
2446
2447static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
2448 const struct hda_fixup *fix, int action)
2449{
2450 struct sigmatel_spec *spec = codec->spec;
2451
2452 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2453 return;
2454
2455 /* Enable VREF power saving on GPIO1 detect */
2456 stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x02);
2457 snd_hda_codec_write_cache(codec, codec->afg, 0,
2458 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
2459 snd_hda_jack_detect_enable(codec, codec->afg, 0);
2460 spec->gpio_mask |= 0x02;
2461
2462 /* enable internal microphone */
2463 snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
2464 stac92xx_auto_set_pinctl(codec, 0x0e,
2465 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
2466
2467 stac92hd71bxx_fixup_no_dmic(codec, fix, action);
2468}
2469
2470static void stac92hd71bxx_fixup_hp_dv4_1222nr(struct hda_codec *codec,
2471 const struct hda_fixup *fix, int action)
2472{
2473 struct sigmatel_spec *spec = codec->spec;
2474
2475 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2476 return;
2477 spec->num_dmics = 1;
2478 /* I don't know if it needs 1 or 2 smuxes - will wait for
2479 * bug reports to fix if needed
2480 */
2481 spec->num_smuxes = 1;
2482 spec->num_dmuxes = 1;
2483}
2484
2485static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec,
2486 const struct hda_fixup *fix, int action)
2487{
2488 struct sigmatel_spec *spec = codec->spec;
2489
2490 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2491 return;
2492 spec->gpio_led = 0x01;
2493}
2494
2495static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec,
2496 const struct hda_fixup *fix, int action)
2497{
2498 struct sigmatel_spec *spec = codec->spec;
2499 unsigned int cap;
2500
2501 switch (action) {
2502 case HDA_FIXUP_ACT_PRE_PROBE:
2503 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
2504 stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
2505 /* HP dv6 gives the headphone pin as a line-out. Thus we
2506 * need to set hp_detect flag here to force to enable HP
2507 * detection.
2508 */
2509 spec->hp_detect = 1;
2510 break;
2511
2512 case HDA_FIXUP_ACT_PROBE:
2513 /* enable bass on HP dv7 */
2514 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
2515 cap &= AC_GPIO_IO_COUNT;
2516 if (cap >= 6)
2517 stac_add_hp_bass_switch(codec);
2518 break;
2519 }
2520}
2521
2522static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
2523 const struct hda_fixup *fix, int action)
2524{
2525 struct sigmatel_spec *spec = codec->spec;
2526
2527 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2528 return;
2529 spec->gpio_led = 0x08;
2530 spec->num_dmics = 1;
2531 spec->num_smuxes = 1;
2532 spec->num_dmuxes = 1;
2533}
2534
2535
2536static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
2537 const struct hda_fixup *fix, int action)
2538{
2539 struct sigmatel_spec *spec = codec->spec;
2540
2541 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2542 return;
2543
2544 if (hp_blike_system(codec->subsystem_id)) {
2545 unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
2546 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
2547 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
2548 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
2549 /* It was changed in the BIOS to just satisfy MS DTM.
2550 * Lets turn it back into slaved HP
2551 */
2552 pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
2553 | (AC_JACK_HP_OUT <<
2554 AC_DEFCFG_DEVICE_SHIFT);
2555 pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
2556 | AC_DEFCFG_SEQUENCE)))
2557 | 0x1f;
2558 snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
2559 }
2560 }
2561
2562 if (find_mute_led_cfg(codec, 1))
2563 snd_printd("mute LED gpio %d polarity %d\n",
2564 spec->gpio_led,
2565 spec->gpio_led_polarity);
2566
2567}
2568
2569static const struct hda_fixup stac92hd71bxx_fixups[] = {
2570 [STAC_92HD71BXX_REF] = {
2571 .type = HDA_FIXUP_FUNC,
2572 .v.func = stac92hd71bxx_fixup_ref,
2573 },
2574 [STAC_DELL_M4_1] = {
2575 .type = HDA_FIXUP_PINS,
2576 .v.pins = dell_m4_1_pin_configs,
2577 .chained = true,
2578 .chain_id = STAC_92HD71BXX_NO_SMUX,
2579 },
2580 [STAC_DELL_M4_2] = {
2581 .type = HDA_FIXUP_PINS,
2582 .v.pins = dell_m4_2_pin_configs,
2583 .chained = true,
2584 .chain_id = STAC_92HD71BXX_NO_DMIC,
2585 },
2586 [STAC_DELL_M4_3] = {
2587 .type = HDA_FIXUP_PINS,
2588 .v.pins = dell_m4_3_pin_configs,
2589 .chained = true,
2590 .chain_id = STAC_92HD71BXX_NO_SMUX,
2591 },
2592 [STAC_HP_M4] = {
2593 .type = HDA_FIXUP_FUNC,
2594 .v.func = stac92hd71bxx_fixup_hp_m4,
2595 .chained = true,
2596 .chain_id = STAC_92HD71BXX_HP,
2597 },
2598 [STAC_HP_DV4] = {
2599 .type = HDA_FIXUP_FUNC,
2600 .v.func = stac92hd71bxx_fixup_hp_dv4,
2601 .chained = true,
2602 .chain_id = STAC_HP_DV5,
2603 },
2604 [STAC_HP_DV5] = {
2605 .type = HDA_FIXUP_FUNC,
2606 .v.func = stac92hd71bxx_fixup_hp_dv5,
2607 .chained = true,
2608 .chain_id = STAC_92HD71BXX_HP,
2609 },
2610 [STAC_HP_HDX] = {
2611 .type = HDA_FIXUP_FUNC,
2612 .v.func = stac92hd71bxx_fixup_hp_hdx,
2613 .chained = true,
2614 .chain_id = STAC_92HD71BXX_HP,
2615 },
2616 [STAC_HP_DV4_1222NR] = {
2617 .type = HDA_FIXUP_FUNC,
2618 .v.func = stac92hd71bxx_fixup_hp_dv4_1222nr,
2619 .chained = true,
2620 .chain_id = STAC_HP_DV4,
2621 },
2622 [STAC_92HD71BXX_NO_DMIC] = {
2623 .type = HDA_FIXUP_FUNC,
2624 .v.func = stac92hd71bxx_fixup_no_dmic,
2625 },
2626 [STAC_92HD71BXX_NO_SMUX] = {
2627 .type = HDA_FIXUP_FUNC,
2628 .v.func = stac92hd71bxx_fixup_no_smux,
2629 },
2630 [STAC_92HD71BXX_HP] = {
2631 .type = HDA_FIXUP_FUNC,
2632 .v.func = stac92hd71bxx_fixup_hp,
2633 },
e035b841
MR
2634};
2635
0f6fcb73
TI
2636static const struct hda_model_fixup stac92hd71bxx_models[] = {
2637 { .id = STAC_92HD71BXX_REF, .name = "ref" },
2638 { .id = STAC_DELL_M4_1, .name = "dell-m4-1" },
2639 { .id = STAC_DELL_M4_2, .name = "dell-m4-2" },
2640 { .id = STAC_DELL_M4_3, .name = "dell-m4-3" },
2641 { .id = STAC_HP_M4, .name = "hp-m4" },
2642 { .id = STAC_HP_DV4, .name = "hp-dv4" },
2643 { .id = STAC_HP_DV5, .name = "hp-dv5" },
2644 { .id = STAC_HP_HDX, .name = "hp-hdx" },
2645 { .id = STAC_HP_DV4_1222NR, .name = "hp-dv4-1222nr" },
2646 {}
e035b841
MR
2647};
2648
0f6fcb73 2649static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = {
e035b841
MR
2650 /* SigmaTel reference board */
2651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2652 "DFI LanParty", STAC_92HD71BXX_REF),
577aa2c1
MR
2653 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
2654 "DFI LanParty", STAC_92HD71BXX_REF),
514bf54c
JG
2655 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
2656 "HP dv4-1222nr", STAC_HP_DV4_1222NR),
5bdaaada
VK
2657 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
2658 "HP", STAC_HP_DV5),
58d8395b
TI
2659 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
2660 "HP", STAC_HP_DV5),
2ae466f8 2661 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
2a6ce6e5 2662 "HP dv4-7", STAC_HP_DV4),
2ae466f8
TI
2663 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
2664 "HP dv4-7", STAC_HP_DV5),
6fce61ae
TI
2665 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
2666 "HP HDX", STAC_HP_HDX), /* HDX18 */
9a9e2359 2667 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
2ae466f8 2668 "HP mini 1000", STAC_HP_M4),
ae6241fb 2669 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
6fce61ae 2670 "HP HDX", STAC_HP_HDX), /* HDX16 */
6e34c033
TI
2671 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
2672 "HP dv6", STAC_HP_DV5),
e3d2530a
KG
2673 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
2674 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
9b2167d5
LY
2675 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
2676 "HP DV6", STAC_HP_DV5),
1972d025
TI
2677 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
2678 "HP", STAC_HP_DV5),
0f6fcb73 2679 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP),
a7662640
MR
2680 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
2681 "unknown Dell", STAC_DELL_M4_1),
2682 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
2683 "unknown Dell", STAC_DELL_M4_1),
2684 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
2685 "unknown Dell", STAC_DELL_M4_1),
2686 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
2687 "unknown Dell", STAC_DELL_M4_1),
2688 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
2689 "unknown Dell", STAC_DELL_M4_1),
2690 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
2691 "unknown Dell", STAC_DELL_M4_1),
2692 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
2693 "unknown Dell", STAC_DELL_M4_1),
2694 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
2695 "unknown Dell", STAC_DELL_M4_2),
2696 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
2697 "unknown Dell", STAC_DELL_M4_2),
2698 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
2699 "unknown Dell", STAC_DELL_M4_2),
2700 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
2701 "unknown Dell", STAC_DELL_M4_2),
3a7abfd2
MR
2702 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
2703 "unknown Dell", STAC_DELL_M4_3),
e035b841
MR
2704 {} /* terminator */
2705};
2706
0a427846
TI
2707static const struct hda_pintbl ref922x_pin_configs[] = {
2708 { 0x0a, 0x01014010 },
2709 { 0x0b, 0x01016011 },
2710 { 0x0c, 0x01012012 },
2711 { 0x0d, 0x0221401f },
2712 { 0x0e, 0x01813122 },
2713 { 0x0f, 0x01011014 },
2714 { 0x10, 0x01441030 },
2715 { 0x11, 0x01c41030 },
2716 { 0x15, 0x40000100 },
2717 { 0x1b, 0x40000100 },
2718 {}
2f2f4251
M
2719};
2720
dfe495d0
TI
2721/*
2722 STAC 922X pin configs for
2723 102801A7
2724 102801AB
2725 102801A9
2726 102801D1
2727 102801D2
2728*/
0a427846
TI
2729static const struct hda_pintbl dell_922x_d81_pin_configs[] = {
2730 { 0x0a, 0x02214030 },
2731 { 0x0b, 0x01a19021 },
2732 { 0x0c, 0x01111012 },
2733 { 0x0d, 0x01114010 },
2734 { 0x0e, 0x02a19020 },
2735 { 0x0f, 0x01117011 },
2736 { 0x10, 0x400001f0 },
2737 { 0x11, 0x400001f1 },
2738 { 0x15, 0x01813122 },
2739 { 0x1b, 0x400001f2 },
2740 {}
dfe495d0
TI
2741};
2742
2743/*
2744 STAC 922X pin configs for
2745 102801AC
2746 102801D0
2747*/
0a427846
TI
2748static const struct hda_pintbl dell_922x_d82_pin_configs[] = {
2749 { 0x0a, 0x02214030 },
2750 { 0x0b, 0x01a19021 },
2751 { 0x0c, 0x01111012 },
2752 { 0x0d, 0x01114010 },
2753 { 0x0e, 0x02a19020 },
2754 { 0x0f, 0x01117011 },
2755 { 0x10, 0x01451140 },
2756 { 0x11, 0x400001f0 },
2757 { 0x15, 0x01813122 },
2758 { 0x1b, 0x400001f1 },
2759 {}
dfe495d0
TI
2760};
2761
2762/*
2763 STAC 922X pin configs for
2764 102801BF
2765*/
0a427846
TI
2766static const struct hda_pintbl dell_922x_m81_pin_configs[] = {
2767 { 0x0a, 0x0321101f },
2768 { 0x0b, 0x01112024 },
2769 { 0x0c, 0x01111222 },
2770 { 0x0d, 0x91174220 },
2771 { 0x0e, 0x03a11050 },
2772 { 0x0f, 0x01116221 },
2773 { 0x10, 0x90a70330 },
2774 { 0x11, 0x01452340 },
2775 { 0x15, 0x40C003f1 },
2776 { 0x1b, 0x405003f0 },
2777 {}
dfe495d0
TI
2778};
2779
2780/*
2781 STAC 9221 A1 pin configs for
2782 102801D7 (Dell XPS M1210)
2783*/
0a427846
TI
2784static const struct hda_pintbl dell_922x_m82_pin_configs[] = {
2785 { 0x0a, 0x02211211 },
2786 { 0x0b, 0x408103ff },
2787 { 0x0c, 0x02a1123e },
2788 { 0x0d, 0x90100310 },
2789 { 0x0e, 0x408003f1 },
2790 { 0x0f, 0x0221121f },
2791 { 0x10, 0x03451340 },
2792 { 0x11, 0x40c003f2 },
2793 { 0x15, 0x508003f3 },
2794 { 0x1b, 0x405003f4 },
2795 {}
dfe495d0
TI
2796};
2797
0a427846
TI
2798static const struct hda_pintbl d945gtp3_pin_configs[] = {
2799 { 0x0a, 0x0221401f },
2800 { 0x0b, 0x01a19022 },
2801 { 0x0c, 0x01813021 },
2802 { 0x0d, 0x01014010 },
2803 { 0x0e, 0x40000100 },
2804 { 0x0f, 0x40000100 },
2805 { 0x10, 0x40000100 },
2806 { 0x11, 0x40000100 },
2807 { 0x15, 0x02a19120 },
2808 { 0x1b, 0x40000100 },
2809 {}
2810};
2811
2812static const struct hda_pintbl d945gtp5_pin_configs[] = {
2813 { 0x0a, 0x0221401f },
2814 { 0x0b, 0x01011012 },
2815 { 0x0c, 0x01813024 },
2816 { 0x0d, 0x01014010 },
2817 { 0x0e, 0x01a19021 },
2818 { 0x0f, 0x01016011 },
2819 { 0x10, 0x01452130 },
2820 { 0x11, 0x40000100 },
2821 { 0x15, 0x02a19320 },
2822 { 0x1b, 0x40000100 },
2823 {}
403d1944
MP
2824};
2825
0a427846
TI
2826static const struct hda_pintbl intel_mac_v1_pin_configs[] = {
2827 { 0x0a, 0x0121e21f },
2828 { 0x0b, 0x400000ff },
2829 { 0x0c, 0x9017e110 },
2830 { 0x0d, 0x400000fd },
2831 { 0x0e, 0x400000fe },
2832 { 0x0f, 0x0181e020 },
2833 { 0x10, 0x1145e030 },
2834 { 0x11, 0x11c5e240 },
2835 { 0x15, 0x400000fc },
2836 { 0x1b, 0x400000fb },
2837 {}
403d1944
MP
2838};
2839
0a427846
TI
2840static const struct hda_pintbl intel_mac_v2_pin_configs[] = {
2841 { 0x0a, 0x0121e21f },
2842 { 0x0b, 0x90a7012e },
2843 { 0x0c, 0x9017e110 },
2844 { 0x0d, 0x400000fd },
2845 { 0x0e, 0x400000fe },
2846 { 0x0f, 0x0181e020 },
2847 { 0x10, 0x1145e230 },
2848 { 0x11, 0x500000fa },
2849 { 0x15, 0x400000fc },
2850 { 0x1b, 0x400000fb },
2851 {}
5d5d3bc3
IZ
2852};
2853
0a427846
TI
2854static const struct hda_pintbl intel_mac_v3_pin_configs[] = {
2855 { 0x0a, 0x0121e21f },
2856 { 0x0b, 0x90a7012e },
2857 { 0x0c, 0x9017e110 },
2858 { 0x0d, 0x400000fd },
2859 { 0x0e, 0x400000fe },
2860 { 0x0f, 0x0181e020 },
2861 { 0x10, 0x1145e230 },
2862 { 0x11, 0x11c5e240 },
2863 { 0x15, 0x400000fc },
2864 { 0x1b, 0x400000fb },
2865 {}
6f0778d8
NB
2866};
2867
0a427846
TI
2868static const struct hda_pintbl intel_mac_v4_pin_configs[] = {
2869 { 0x0a, 0x0321e21f },
2870 { 0x0b, 0x03a1e02e },
2871 { 0x0c, 0x9017e110 },
2872 { 0x0d, 0x9017e11f },
2873 { 0x0e, 0x400000fe },
2874 { 0x0f, 0x0381e020 },
2875 { 0x10, 0x1345e230 },
2876 { 0x11, 0x13c5e240 },
2877 { 0x15, 0x400000fc },
2878 { 0x1b, 0x400000fb },
2879 {}
3fc24d85
TI
2880};
2881
0a427846
TI
2882static const struct hda_pintbl intel_mac_v5_pin_configs[] = {
2883 { 0x0a, 0x0321e21f },
2884 { 0x0b, 0x03a1e02e },
2885 { 0x0c, 0x9017e110 },
2886 { 0x0d, 0x9017e11f },
2887 { 0x0e, 0x400000fe },
2888 { 0x0f, 0x0381e020 },
2889 { 0x10, 0x1345e230 },
2890 { 0x11, 0x13c5e240 },
2891 { 0x15, 0x400000fc },
2892 { 0x1b, 0x400000fb },
2893 {}
f16928fb
SF
2894};
2895
0a427846
TI
2896static const struct hda_pintbl ecs202_pin_configs[] = {
2897 { 0x0a, 0x0221401f },
2898 { 0x0b, 0x02a19020 },
2899 { 0x0c, 0x01a19020 },
2900 { 0x0d, 0x01114010 },
2901 { 0x0e, 0x408000f0 },
2902 { 0x0f, 0x01813022 },
2903 { 0x10, 0x074510a0 },
2904 { 0x11, 0x40c400f1 },
2905 { 0x15, 0x9037012e },
2906 { 0x1b, 0x40e000f2 },
2907 {}
0dae0f83
TI
2908};
2909
0a427846
TI
2910/* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */
2911static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = {
2912 SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1),
2913 SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2),
2914 SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2),
2915 SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3),
2916 SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3),
2917 SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3),
2918 SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3),
2919 SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3),
2920 SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3),
2921 SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4),
2922 SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5),
2923 SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5),
2924 {}
8c650087 2925};
76c08828 2926
0a427846
TI
2927static const struct hda_fixup stac922x_fixups[];
2928
2929/* remap the fixup from codec SSID and apply it */
2930static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
2931 const struct hda_fixup *fix,
2932 int action)
2933{
2934 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2935 return;
2936 snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
2937 stac922x_fixups);
2938 if (codec->fixup_id != STAC_INTEL_MAC_AUTO)
2939 snd_hda_apply_fixup(codec, action);
2940}
2941
2942static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec,
2943 const struct hda_fixup *fix,
2944 int action)
2945{
2946 struct sigmatel_spec *spec = codec->spec;
2947
2948 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2949 spec->gpio_mask = spec->gpio_dir = 0x03;
2950 spec->gpio_data = 0x03;
2951 }
2952}
2953
2954static const struct hda_fixup stac922x_fixups[] = {
2955 [STAC_D945_REF] = {
2956 .type = HDA_FIXUP_PINS,
2957 .v.pins = ref922x_pin_configs,
2958 },
2959 [STAC_D945GTP3] = {
2960 .type = HDA_FIXUP_PINS,
2961 .v.pins = d945gtp3_pin_configs,
2962 },
2963 [STAC_D945GTP5] = {
2964 .type = HDA_FIXUP_PINS,
2965 .v.pins = d945gtp5_pin_configs,
2966 },
2967 [STAC_INTEL_MAC_AUTO] = {
2968 .type = HDA_FIXUP_FUNC,
2969 .v.func = stac922x_fixup_intel_mac_auto,
2970 },
2971 [STAC_INTEL_MAC_V1] = {
2972 .type = HDA_FIXUP_PINS,
2973 .v.pins = intel_mac_v1_pin_configs,
2974 .chained = true,
2975 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2976 },
2977 [STAC_INTEL_MAC_V2] = {
2978 .type = HDA_FIXUP_PINS,
2979 .v.pins = intel_mac_v2_pin_configs,
2980 .chained = true,
2981 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2982 },
2983 [STAC_INTEL_MAC_V3] = {
2984 .type = HDA_FIXUP_PINS,
2985 .v.pins = intel_mac_v3_pin_configs,
2986 .chained = true,
2987 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2988 },
2989 [STAC_INTEL_MAC_V4] = {
2990 .type = HDA_FIXUP_PINS,
2991 .v.pins = intel_mac_v4_pin_configs,
2992 .chained = true,
2993 .chain_id = STAC_922X_INTEL_MAC_GPIO,
2994 },
2995 [STAC_INTEL_MAC_V5] = {
2996 .type = HDA_FIXUP_PINS,
2997 .v.pins = intel_mac_v5_pin_configs,
2998 .chained = true,
2999 .chain_id = STAC_922X_INTEL_MAC_GPIO,
3000 },
3001 [STAC_922X_INTEL_MAC_GPIO] = {
3002 .type = HDA_FIXUP_FUNC,
3003 .v.func = stac922x_fixup_intel_mac_gpio,
3004 },
3005 [STAC_ECS_202] = {
3006 .type = HDA_FIXUP_PINS,
3007 .v.pins = ecs202_pin_configs,
3008 },
3009 [STAC_922X_DELL_D81] = {
3010 .type = HDA_FIXUP_PINS,
3011 .v.pins = dell_922x_d81_pin_configs,
3012 },
3013 [STAC_922X_DELL_D82] = {
3014 .type = HDA_FIXUP_PINS,
3015 .v.pins = dell_922x_d82_pin_configs,
3016 },
3017 [STAC_922X_DELL_M81] = {
3018 .type = HDA_FIXUP_PINS,
3019 .v.pins = dell_922x_m81_pin_configs,
3020 },
3021 [STAC_922X_DELL_M82] = {
3022 .type = HDA_FIXUP_PINS,
3023 .v.pins = dell_922x_m82_pin_configs,
3024 },
3025};
3026
3027static const struct hda_model_fixup stac922x_models[] = {
3028 { .id = STAC_D945_REF, .name = "ref" },
3029 { .id = STAC_D945GTP5, .name = "5stack" },
3030 { .id = STAC_D945GTP3, .name = "3stack" },
3031 { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" },
3032 { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" },
3033 { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" },
3034 { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" },
3035 { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" },
3036 { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" },
3037 { .id = STAC_ECS_202, .name = "ecs202" },
3038 { .id = STAC_922X_DELL_D81, .name = "dell-d81" },
3039 { .id = STAC_922X_DELL_D82, .name = "dell-d82" },
3040 { .id = STAC_922X_DELL_M81, .name = "dell-m81" },
3041 { .id = STAC_922X_DELL_M82, .name = "dell-m82" },
dfe495d0 3042 /* for backward compatibility */
0a427846
TI
3043 { .id = STAC_INTEL_MAC_V3, .name = "macmini" },
3044 { .id = STAC_INTEL_MAC_V5, .name = "macbook" },
3045 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" },
3046 { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" },
3047 { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" },
3048 { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" },
3049 {}
3050};
3051
3052static const struct snd_pci_quirk stac922x_fixup_tbl[] = {
f5fcc13c
TI
3053 /* SigmaTel reference board */
3054 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3055 "DFI LanParty", STAC_D945_REF),
577aa2c1
MR
3056 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3057 "DFI LanParty", STAC_D945_REF),
f5fcc13c
TI
3058 /* Intel 945G based systems */
3059 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
3060 "Intel D945G", STAC_D945GTP3),
3061 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
3062 "Intel D945G", STAC_D945GTP3),
3063 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
3064 "Intel D945G", STAC_D945GTP3),
3065 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
3066 "Intel D945G", STAC_D945GTP3),
3067 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
3068 "Intel D945G", STAC_D945GTP3),
3069 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
3070 "Intel D945G", STAC_D945GTP3),
3071 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
3072 "Intel D945G", STAC_D945GTP3),
3073 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
3074 "Intel D945G", STAC_D945GTP3),
3075 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
3076 "Intel D945G", STAC_D945GTP3),
3077 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
3078 "Intel D945G", STAC_D945GTP3),
3079 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
3080 "Intel D945G", STAC_D945GTP3),
3081 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
3082 "Intel D945G", STAC_D945GTP3),
3083 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
3084 "Intel D945G", STAC_D945GTP3),
3085 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
3086 "Intel D945G", STAC_D945GTP3),
3087 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
3088 "Intel D945G", STAC_D945GTP3),
3089 /* Intel D945G 5-stack systems */
3090 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
3091 "Intel D945G", STAC_D945GTP5),
3092 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
3093 "Intel D945G", STAC_D945GTP5),
3094 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
3095 "Intel D945G", STAC_D945GTP5),
3096 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
3097 "Intel D945G", STAC_D945GTP5),
3098 /* Intel 945P based systems */
3099 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
3100 "Intel D945P", STAC_D945GTP3),
3101 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
3102 "Intel D945P", STAC_D945GTP3),
3103 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
3104 "Intel D945P", STAC_D945GTP3),
3105 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
3106 "Intel D945P", STAC_D945GTP3),
3107 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
3108 "Intel D945P", STAC_D945GTP3),
3109 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
3110 "Intel D945P", STAC_D945GTP5),
8056d47e
TI
3111 /* other intel */
3112 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
3113 "Intel D945", STAC_D945_REF),
f5fcc13c 3114 /* other systems */
0a427846 3115
536319af 3116 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
0a427846
TI
3117 SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO),
3118
dfe495d0
TI
3119 /* Dell systems */
3120 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
3121 "unknown Dell", STAC_922X_DELL_D81),
3122 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
3123 "unknown Dell", STAC_922X_DELL_D81),
3124 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
3125 "unknown Dell", STAC_922X_DELL_D81),
3126 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
3127 "unknown Dell", STAC_922X_DELL_D82),
3128 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
3129 "unknown Dell", STAC_922X_DELL_M81),
3130 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
3131 "unknown Dell", STAC_922X_DELL_D82),
3132 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
3133 "unknown Dell", STAC_922X_DELL_D81),
3134 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
3135 "unknown Dell", STAC_922X_DELL_D81),
3136 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
3137 "Dell XPS M1210", STAC_922X_DELL_M82),
8c650087 3138 /* ECS/PC Chips boards */
dea0a509 3139 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
8663ae55 3140 "ECS/PC chips", STAC_ECS_202),
403d1944
MP
3141 {} /* terminator */
3142};
3143
29ac8363
TI
3144static const struct hda_pintbl ref927x_pin_configs[] = {
3145 { 0x0a, 0x02214020 },
3146 { 0x0b, 0x02a19080 },
3147 { 0x0c, 0x0181304e },
3148 { 0x0d, 0x01014010 },
3149 { 0x0e, 0x01a19040 },
3150 { 0x0f, 0x01011012 },
3151 { 0x10, 0x01016011 },
3152 { 0x11, 0x0101201f },
3153 { 0x12, 0x183301f0 },
3154 { 0x13, 0x18a001f0 },
3155 { 0x14, 0x18a001f0 },
3156 { 0x21, 0x01442070 },
3157 { 0x22, 0x01c42190 },
3158 { 0x23, 0x40000100 },
3159 {}
3cc08dc6
MP
3160};
3161
29ac8363
TI
3162static const struct hda_pintbl d965_3st_pin_configs[] = {
3163 { 0x0a, 0x0221401f },
3164 { 0x0b, 0x02a19120 },
3165 { 0x0c, 0x40000100 },
3166 { 0x0d, 0x01014011 },
3167 { 0x0e, 0x01a19021 },
3168 { 0x0f, 0x01813024 },
3169 { 0x10, 0x40000100 },
3170 { 0x11, 0x40000100 },
3171 { 0x12, 0x40000100 },
3172 { 0x13, 0x40000100 },
3173 { 0x14, 0x40000100 },
3174 { 0x21, 0x40000100 },
3175 { 0x22, 0x40000100 },
3176 { 0x23, 0x40000100 },
3177 {}
81d3dbde
TD
3178};
3179
29ac8363
TI
3180static const struct hda_pintbl d965_5st_pin_configs[] = {
3181 { 0x0a, 0x02214020 },
3182 { 0x0b, 0x02a19080 },
3183 { 0x0c, 0x0181304e },
3184 { 0x0d, 0x01014010 },
3185 { 0x0e, 0x01a19040 },
3186 { 0x0f, 0x01011012 },
3187 { 0x10, 0x01016011 },
3188 { 0x11, 0x40000100 },
3189 { 0x12, 0x40000100 },
3190 { 0x13, 0x40000100 },
3191 { 0x14, 0x40000100 },
3192 { 0x21, 0x01442070 },
3193 { 0x22, 0x40000100 },
3194 { 0x23, 0x40000100 },
3195 {}
93ed1503
TD
3196};
3197
29ac8363
TI
3198static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = {
3199 { 0x0a, 0x40000100 },
3200 { 0x0b, 0x40000100 },
3201 { 0x0c, 0x0181304e },
3202 { 0x0d, 0x01014010 },
3203 { 0x0e, 0x01a19040 },
3204 { 0x0f, 0x01011012 },
3205 { 0x10, 0x01016011 },
3206 { 0x11, 0x40000100 },
3207 { 0x12, 0x40000100 },
3208 { 0x13, 0x40000100 },
3209 { 0x14, 0x40000100 },
3210 { 0x21, 0x01442070 },
3211 { 0x22, 0x40000100 },
3212 { 0x23, 0x40000100 },
3213 {}
679d92ed
TI
3214};
3215
29ac8363
TI
3216static const struct hda_pintbl dell_3st_pin_configs[] = {
3217 { 0x0a, 0x02211230 },
3218 { 0x0b, 0x02a11220 },
3219 { 0x0c, 0x01a19040 },
3220 { 0x0d, 0x01114210 },
3221 { 0x0e, 0x01111212 },
3222 { 0x0f, 0x01116211 },
3223 { 0x10, 0x01813050 },
3224 { 0x11, 0x01112214 },
3225 { 0x12, 0x403003fa },
3226 { 0x13, 0x90a60040 },
3227 { 0x14, 0x90a60040 },
3228 { 0x21, 0x404003fb },
3229 { 0x22, 0x40c003fc },
3230 { 0x23, 0x40000100 },
3231 {}
4ff076e5
TD
3232};
3233
29ac8363
TI
3234static void stac927x_fixup_ref_no_jd(struct hda_codec *codec,
3235 const struct hda_fixup *fix, int action)
3236{
3237 struct sigmatel_spec *spec = codec->spec;
3238
3239 /* no jack detecion for ref-no-jd model */
3240 if (action == HDA_FIXUP_ACT_PROBE)
3241 spec->hp_detect = 0;
3242}
3243
3244static void stac927x_fixup_ref(struct hda_codec *codec,
3245 const struct hda_fixup *fix, int action)
3246{
3247 struct sigmatel_spec *spec = codec->spec;
3248
3249 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3250 snd_hda_apply_pincfgs(codec, ref927x_pin_configs);
3251 spec->eapd_mask = spec->gpio_mask = 0;
3252 spec->gpio_dir = spec->gpio_data = 0;
3253 }
3254}
3255
3256static void stac927x_fixup_dell_dmic(struct hda_codec *codec,
3257 const struct hda_fixup *fix, int action)
3258{
3259 struct sigmatel_spec *spec = codec->spec;
3260
3261 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3262 return;
3263
3264 if (codec->subsystem_id != 0x1028022f) {
3265 /* GPIO2 High = Enable EAPD */
3266 spec->eapd_mask = spec->gpio_mask = 0x04;
3267 spec->gpio_dir = spec->gpio_data = 0x04;
3268 }
3269 spec->dmic_nids = stac927x_dmic_nids;
3270 spec->num_dmics = STAC927X_NUM_DMICS;
3271
3272 snd_hda_add_verbs(codec, dell_3st_core_init);
3273 spec->volknob_init = 1;
3274 spec->dmux_nids = stac927x_dmux_nids;
3275 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
3276}
3277
3278static void stac927x_fixup_volknob(struct hda_codec *codec,
3279 const struct hda_fixup *fix, int action)
3280{
3281 struct sigmatel_spec *spec = codec->spec;
3282
3283 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3284 snd_hda_add_verbs(codec, stac927x_volknob_core_init);
3285 spec->volknob_init = 1;
3286 }
3287}
3288
3289static const struct hda_fixup stac927x_fixups[] = {
3290 [STAC_D965_REF_NO_JD] = {
3291 .type = HDA_FIXUP_FUNC,
3292 .v.func = stac927x_fixup_ref_no_jd,
3293 .chained = true,
3294 .chain_id = STAC_D965_REF,
3295 },
3296 [STAC_D965_REF] = {
3297 .type = HDA_FIXUP_FUNC,
3298 .v.func = stac927x_fixup_ref,
3299 },
3300 [STAC_D965_3ST] = {
3301 .type = HDA_FIXUP_PINS,
3302 .v.pins = d965_3st_pin_configs,
3303 .chained = true,
3304 .chain_id = STAC_D965_VERBS,
3305 },
3306 [STAC_D965_5ST] = {
3307 .type = HDA_FIXUP_PINS,
3308 .v.pins = d965_5st_pin_configs,
3309 .chained = true,
3310 .chain_id = STAC_D965_VERBS,
3311 },
3312 [STAC_D965_VERBS] = {
3313 .type = HDA_FIXUP_VERBS,
3314 .v.verbs = d965_core_init,
3315 },
3316 [STAC_D965_5ST_NO_FP] = {
3317 .type = HDA_FIXUP_PINS,
3318 .v.pins = d965_5st_no_fp_pin_configs,
3319 },
3320 [STAC_DELL_3ST] = {
3321 .type = HDA_FIXUP_PINS,
3322 .v.pins = dell_3st_pin_configs,
3323 .chained = true,
3324 .chain_id = STAC_927X_DELL_DMIC,
3325 },
3326 [STAC_DELL_BIOS] = {
3327 .type = HDA_FIXUP_PINS,
3328 .v.pins = (const struct hda_pintbl[]) {
3329 /* configure the analog microphone on some laptops */
3330 { 0x0c, 0x90a79130 },
3331 /* correct the front output jack as a hp out */
3332 { 0x0f, 0x0227011f },
3333 /* correct the front input jack as a mic */
3334 { 0x0e, 0x02a79130 },
3335 {}
3336 },
3337 .chained = true,
3338 .chain_id = STAC_927X_DELL_DMIC,
3339 },
3340 [STAC_DELL_BIOS_SPDIF] = {
3341 .type = HDA_FIXUP_PINS,
3342 .v.pins = (const struct hda_pintbl[]) {
3343 /* correct the device field to SPDIF out */
3344 { 0x21, 0x01442070 },
3345 {}
3346 },
3347 .chained = true,
3348 .chain_id = STAC_DELL_BIOS,
3349 },
3350 [STAC_927X_DELL_DMIC] = {
3351 .type = HDA_FIXUP_FUNC,
3352 .v.func = stac927x_fixup_dell_dmic,
3353 },
3354 [STAC_927X_VOLKNOB] = {
3355 .type = HDA_FIXUP_FUNC,
3356 .v.func = stac927x_fixup_volknob,
3357 },
3cc08dc6
MP
3358};
3359
29ac8363
TI
3360static const struct hda_model_fixup stac927x_models[] = {
3361 { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" },
3362 { .id = STAC_D965_REF, .name = "ref" },
3363 { .id = STAC_D965_3ST, .name = "3stack" },
3364 { .id = STAC_D965_5ST, .name = "5stack" },
3365 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3366 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3367 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3368 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3369 {}
f5fcc13c
TI
3370};
3371
29ac8363 3372static const struct snd_pci_quirk stac927x_fixup_tbl[] = {
f5fcc13c
TI
3373 /* SigmaTel reference board */
3374 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3375 "DFI LanParty", STAC_D965_REF),
577aa2c1
MR
3376 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3377 "DFI LanParty", STAC_D965_REF),
81d3dbde 3378 /* Intel 946 based systems */
f5fcc13c
TI
3379 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
3380 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
93ed1503 3381 /* 965 based 3 stack systems */
dea0a509
TI
3382 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
3383 "Intel D965", STAC_D965_3ST),
3384 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
3385 "Intel D965", STAC_D965_3ST),
4ff076e5 3386 /* Dell 3 stack systems */
dfe495d0 3387 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
4ff076e5
TD
3388 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
3389 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
8e9068b1 3390 /* Dell 3 stack systems with verb table in BIOS */
2f32d909 3391 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
66668b6f 3392 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
2f32d909 3393 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
29ac8363 3394 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF),
84d3dc20 3395 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
8e9068b1
MR
3396 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
3397 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
3398 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
29ac8363 3399 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF),
93ed1503 3400 /* 965 based 5 stack systems */
dea0a509
TI
3401 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
3402 "Intel D965", STAC_D965_5ST),
3403 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
3404 "Intel D965", STAC_D965_5ST),
54930531
TI
3405 /* volume-knob fixes */
3406 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
3cc08dc6
MP
3407 {} /* terminator */
3408};
3409
fe6322ca
TI
3410static const struct hda_pintbl ref9205_pin_configs[] = {
3411 { 0x0a, 0x40000100 },
3412 { 0x0b, 0x40000100 },
3413 { 0x0c, 0x01016011 },
3414 { 0x0d, 0x01014010 },
3415 { 0x0e, 0x01813122 },
3416 { 0x0f, 0x01a19021 },
3417 { 0x14, 0x01019020 },
3418 { 0x16, 0x40000100 },
3419 { 0x17, 0x90a000f0 },
3420 { 0x18, 0x90a000f0 },
3421 { 0x21, 0x01441030 },
3422 { 0x22, 0x01c41030 },
3423 {}
f3302a59
MP
3424};
3425
dfe495d0
TI
3426/*
3427 STAC 9205 pin configs for
3428 102801F1
3429 102801F2
3430 102801FC
3431 102801FD
3432 10280204
3433 1028021F
3fa2ef74 3434 10280228 (Dell Vostro 1500)
95e70e87 3435 10280229 (Dell Vostro 1700)
dfe495d0 3436*/
fe6322ca
TI
3437static const struct hda_pintbl dell_9205_m42_pin_configs[] = {
3438 { 0x0a, 0x0321101F },
3439 { 0x0b, 0x03A11020 },
3440 { 0x0c, 0x400003FA },
3441 { 0x0d, 0x90170310 },
3442 { 0x0e, 0x400003FB },
3443 { 0x0f, 0x400003FC },
3444 { 0x14, 0x400003FD },
3445 { 0x16, 0x40F000F9 },
3446 { 0x17, 0x90A60330 },
3447 { 0x18, 0x400003FF },
3448 { 0x21, 0x0144131F },
3449 { 0x22, 0x40C003FE },
3450 {}
dfe495d0
TI
3451};
3452
3453/*
3454 STAC 9205 pin configs for
3455 102801F9
3456 102801FA
3457 102801FE
3458 102801FF (Dell Precision M4300)
3459 10280206
3460 10280200
3461 10280201
3462*/
fe6322ca
TI
3463static const struct hda_pintbl dell_9205_m43_pin_configs[] = {
3464 { 0x0a, 0x0321101f },
3465 { 0x0b, 0x03a11020 },
3466 { 0x0c, 0x90a70330 },
3467 { 0x0d, 0x90170310 },
3468 { 0x0e, 0x400000fe },
3469 { 0x0f, 0x400000ff },
3470 { 0x14, 0x400000fd },
3471 { 0x16, 0x40f000f9 },
3472 { 0x17, 0x400000fa },
3473 { 0x18, 0x400000fc },
3474 { 0x21, 0x0144131f },
3475 { 0x22, 0x40c003f8 },
3476 /* Enable SPDIF in/out */
3477 { 0x1f, 0x01441030 },
3478 { 0x20, 0x1c410030 },
3479 {}
ae0a8ed8
TD
3480};
3481
fe6322ca
TI
3482static const struct hda_pintbl dell_9205_m44_pin_configs[] = {
3483 { 0x0a, 0x0421101f },
3484 { 0x0b, 0x04a11020 },
3485 { 0x0c, 0x400003fa },
3486 { 0x0d, 0x90170310 },
3487 { 0x0e, 0x400003fb },
3488 { 0x0f, 0x400003fc },
3489 { 0x14, 0x400003fd },
3490 { 0x16, 0x400003f9 },
3491 { 0x17, 0x90a60330 },
3492 { 0x18, 0x400003ff },
3493 { 0x21, 0x01441340 },
3494 { 0x22, 0x40c003fe },
3495 {}
ae0a8ed8
TD
3496};
3497
fe6322ca
TI
3498static void stac9205_fixup_ref(struct hda_codec *codec,
3499 const struct hda_fixup *fix, int action)
3500{
3501 struct sigmatel_spec *spec = codec->spec;
3502
3503 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3504 snd_hda_apply_pincfgs(codec, ref9205_pin_configs);
3505 /* SPDIF-In enabled */
3506 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0;
3507 }
3508}
3509
fe6322ca
TI
3510static void stac9205_fixup_dell_m43(struct hda_codec *codec,
3511 const struct hda_fixup *fix, int action)
3512{
3513 struct sigmatel_spec *spec = codec->spec;
3514 int err;
3515
3516 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3517 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
3518
3519 /* Enable unsol response for GPIO4/Dock HP connection */
3520 err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01);
3521 if (err < 0)
3522 return;
3523 snd_hda_codec_write_cache(codec, codec->afg, 0,
3524 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
3525 snd_hda_jack_detect_enable(codec, codec->afg, 0);
3526
3527 spec->gpio_dir = 0x0b;
3528 spec->eapd_mask = 0x01;
3529 spec->gpio_mask = 0x1b;
3530 spec->gpio_mute = 0x10;
3531 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
3532 * GPIO3 Low = DRM
3533 */
3534 spec->gpio_data = 0x01;
3535 }
3536}
3537
3538static void stac9205_fixup_eapd(struct hda_codec *codec,
3539 const struct hda_fixup *fix, int action)
3540{
3541 struct sigmatel_spec *spec = codec->spec;
3542
3543 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3544 spec->eapd_switch = 0;
3545}
3546
3547static const struct hda_fixup stac9205_fixups[] = {
3548 [STAC_9205_REF] = {
3549 .type = HDA_FIXUP_FUNC,
3550 .v.func = stac9205_fixup_ref,
3551 },
3552 [STAC_9205_DELL_M42] = {
3553 .type = HDA_FIXUP_PINS,
3554 .v.pins = dell_9205_m42_pin_configs,
3555 },
3556 [STAC_9205_DELL_M43] = {
3557 .type = HDA_FIXUP_FUNC,
3558 .v.func = stac9205_fixup_dell_m43,
3559 },
3560 [STAC_9205_DELL_M44] = {
3561 .type = HDA_FIXUP_PINS,
3562 .v.pins = dell_9205_m44_pin_configs,
3563 },
3564 [STAC_9205_EAPD] = {
3565 .type = HDA_FIXUP_FUNC,
3566 .v.func = stac9205_fixup_eapd,
3567 },
3568 {}
f3302a59
MP
3569};
3570
fe6322ca
TI
3571static const struct hda_model_fixup stac9205_models[] = {
3572 { .id = STAC_9205_REF, .name = "ref" },
3573 { .id = STAC_9205_DELL_M42, .name = "dell-m42" },
3574 { .id = STAC_9205_DELL_M43, .name = "dell-m43" },
3575 { .id = STAC_9205_DELL_M44, .name = "dell-m44" },
3576 { .id = STAC_9205_EAPD, .name = "eapd" },
3577 {}
f5fcc13c
TI
3578};
3579
fe6322ca 3580static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
f5fcc13c
TI
3581 /* SigmaTel reference board */
3582 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
3583 "DFI LanParty", STAC_9205_REF),
02358fcf
HRK
3584 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
3585 "SigmaTel", STAC_9205_REF),
577aa2c1
MR
3586 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
3587 "DFI LanParty", STAC_9205_REF),
d9a4268e 3588 /* Dell */
dfe495d0
TI
3589 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
3590 "unknown Dell", STAC_9205_DELL_M42),
3591 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
3592 "unknown Dell", STAC_9205_DELL_M42),
ae0a8ed8 3593 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
b44ef2f1 3594 "Dell Precision", STAC_9205_DELL_M43),
ae0a8ed8
TD
3595 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
3596 "Dell Precision", STAC_9205_DELL_M43),
3597 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
3598 "Dell Precision", STAC_9205_DELL_M43),
dfe495d0
TI
3599 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
3600 "unknown Dell", STAC_9205_DELL_M42),
3601 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
3602 "unknown Dell", STAC_9205_DELL_M42),
ae0a8ed8
TD
3603 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
3604 "Dell Precision", STAC_9205_DELL_M43),
3605 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
dfe495d0 3606 "Dell Precision M4300", STAC_9205_DELL_M43),
dfe495d0
TI
3607 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
3608 "unknown Dell", STAC_9205_DELL_M42),
4549915c
TI
3609 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
3610 "Dell Precision", STAC_9205_DELL_M43),
3611 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
3612 "Dell Precision", STAC_9205_DELL_M43),
3613 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
3614 "Dell Precision", STAC_9205_DELL_M43),
ae0a8ed8
TD
3615 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
3616 "Dell Inspiron", STAC_9205_DELL_M44),
3fa2ef74
MR
3617 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
3618 "Dell Vostro 1500", STAC_9205_DELL_M42),
95e70e87
AA
3619 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
3620 "Dell Vostro 1700", STAC_9205_DELL_M42),
d9a4268e 3621 /* Gateway */
42b95f0c 3622 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
d9a4268e 3623 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
f3302a59
MP
3624 {} /* terminator */
3625};
3626
dabbed6f 3627/*
c7d4b2fa 3628 * Analog playback callbacks
dabbed6f 3629 */
c7d4b2fa
M
3630static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
3631 struct hda_codec *codec,
c8b6bf9b 3632 struct snd_pcm_substream *substream)
2f2f4251 3633{
dabbed6f 3634 struct sigmatel_spec *spec = codec->spec;
8daaaa97
MR
3635 if (spec->stream_delay)
3636 msleep(spec->stream_delay);
9a08160b
TI
3637 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3638 hinfo);
2f2f4251
M
3639}
3640
2f2f4251
M
3641static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3642 struct hda_codec *codec,
3643 unsigned int stream_tag,
3644 unsigned int format,
c8b6bf9b 3645 struct snd_pcm_substream *substream)
2f2f4251
M
3646{
3647 struct sigmatel_spec *spec = codec->spec;
403d1944 3648 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
2f2f4251
M
3649}
3650
3651static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3652 struct hda_codec *codec,
c8b6bf9b 3653 struct snd_pcm_substream *substream)
2f2f4251
M
3654{
3655 struct sigmatel_spec *spec = codec->spec;
3656 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3657}
3658
dabbed6f
M
3659/*
3660 * Digital playback callbacks
3661 */
3662static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3663 struct hda_codec *codec,
c8b6bf9b 3664 struct snd_pcm_substream *substream)
dabbed6f
M
3665{
3666 struct sigmatel_spec *spec = codec->spec;
3667 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3668}
3669
3670static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3671 struct hda_codec *codec,
c8b6bf9b 3672 struct snd_pcm_substream *substream)
dabbed6f
M
3673{
3674 struct sigmatel_spec *spec = codec->spec;
3675 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3676}
3677
6b97eb45
TI
3678static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3679 struct hda_codec *codec,
3680 unsigned int stream_tag,
3681 unsigned int format,
3682 struct snd_pcm_substream *substream)
3683{
3684 struct sigmatel_spec *spec = codec->spec;
3685 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3686 stream_tag, format, substream);
3687}
3688
9411e21c
TI
3689static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3690 struct hda_codec *codec,
3691 struct snd_pcm_substream *substream)
3692{
3693 struct sigmatel_spec *spec = codec->spec;
3694 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3695}
3696
dabbed6f 3697
2f2f4251
M
3698/*
3699 * Analog capture callbacks
3700 */
3701static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3702 struct hda_codec *codec,
3703 unsigned int stream_tag,
3704 unsigned int format,
c8b6bf9b 3705 struct snd_pcm_substream *substream)
2f2f4251
M
3706{
3707 struct sigmatel_spec *spec = codec->spec;
8daaaa97 3708 hda_nid_t nid = spec->adc_nids[substream->number];
2f2f4251 3709
8daaaa97
MR
3710 if (spec->powerdown_adcs) {
3711 msleep(40);
8c2f767b 3712 snd_hda_codec_write(codec, nid, 0,
8daaaa97
MR
3713 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3714 }
3715 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
2f2f4251
M
3716 return 0;
3717}
3718
3719static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3720 struct hda_codec *codec,
c8b6bf9b 3721 struct snd_pcm_substream *substream)
2f2f4251
M
3722{
3723 struct sigmatel_spec *spec = codec->spec;
8daaaa97 3724 hda_nid_t nid = spec->adc_nids[substream->number];
2f2f4251 3725
8daaaa97
MR
3726 snd_hda_codec_cleanup_stream(codec, nid);
3727 if (spec->powerdown_adcs)
8c2f767b 3728 snd_hda_codec_write(codec, nid, 0,
8daaaa97 3729 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2f2f4251
M
3730 return 0;
3731}
3732
2b63536f 3733static const struct hda_pcm_stream stac92xx_pcm_digital_playback = {
dabbed6f
M
3734 .substreams = 1,
3735 .channels_min = 2,
3736 .channels_max = 2,
3737 /* NID is set in stac92xx_build_pcms */
3738 .ops = {
3739 .open = stac92xx_dig_playback_pcm_open,
6b97eb45 3740 .close = stac92xx_dig_playback_pcm_close,
9411e21c
TI
3741 .prepare = stac92xx_dig_playback_pcm_prepare,
3742 .cleanup = stac92xx_dig_playback_pcm_cleanup
dabbed6f
M
3743 },
3744};
3745
2b63536f 3746static const struct hda_pcm_stream stac92xx_pcm_digital_capture = {
dabbed6f
M
3747 .substreams = 1,
3748 .channels_min = 2,
3749 .channels_max = 2,
3750 /* NID is set in stac92xx_build_pcms */
3751};
3752
2b63536f 3753static const struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2f2f4251
M
3754 .substreams = 1,
3755 .channels_min = 2,
c7d4b2fa 3756 .channels_max = 8,
2f2f4251
M
3757 .nid = 0x02, /* NID to query formats and rates */
3758 .ops = {
3759 .open = stac92xx_playback_pcm_open,
3760 .prepare = stac92xx_playback_pcm_prepare,
3761 .cleanup = stac92xx_playback_pcm_cleanup
3762 },
3763};
3764
2b63536f 3765static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
3cc08dc6
MP
3766 .substreams = 1,
3767 .channels_min = 2,
3768 .channels_max = 2,
3769 .nid = 0x06, /* NID to query formats and rates */
3770 .ops = {
3771 .open = stac92xx_playback_pcm_open,
3772 .prepare = stac92xx_playback_pcm_prepare,
3773 .cleanup = stac92xx_playback_pcm_cleanup
3774 },
3775};
3776
2b63536f 3777static const struct hda_pcm_stream stac92xx_pcm_analog_capture = {
2f2f4251
M
3778 .channels_min = 2,
3779 .channels_max = 2,
9e05b7a3 3780 /* NID + .substreams is set in stac92xx_build_pcms */
2f2f4251
M
3781 .ops = {
3782 .prepare = stac92xx_capture_pcm_prepare,
3783 .cleanup = stac92xx_capture_pcm_cleanup
3784 },
3785};
3786
3787static int stac92xx_build_pcms(struct hda_codec *codec)
3788{
3789 struct sigmatel_spec *spec = codec->spec;
3790 struct hda_pcm *info = spec->pcm_rec;
3791
3792 codec->num_pcms = 1;
3793 codec->pcm_info = info;
3794
c7d4b2fa 3795 info->name = "STAC92xx Analog";
2f2f4251 3796 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
00a602db
TI
3797 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3798 spec->multiout.dac_nids[0];
ee81abb6
TI
3799 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
3800 spec->autocfg.line_outs == 2)
3801 info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
3802 snd_pcm_2_1_chmaps;
3803
2f2f4251 3804 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
3cc08dc6 3805 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
9e05b7a3 3806 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
3cc08dc6
MP
3807
3808 if (spec->alt_switch) {
3809 codec->num_pcms++;
3810 info++;
3811 info->name = "STAC92xx Analog Alt";
3812 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
3813 }
2f2f4251 3814
dabbed6f
M
3815 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3816 codec->num_pcms++;
3817 info++;
3818 info->name = "STAC92xx Digital";
0852d7a6 3819 info->pcm_type = spec->autocfg.dig_out_type[0];
dabbed6f
M
3820 if (spec->multiout.dig_out_nid) {
3821 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
3822 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3823 }
3824 if (spec->dig_in_nid) {
3825 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
3826 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3827 }
3828 }
3829
2f2f4251
M
3830 return 0;
3831}
3832
403d1944
MP
3833static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
3834
3835{
cdd03ced 3836 snd_hda_set_pin_ctl_cache(codec, nid, pin_type);
403d1944
MP
3837}
3838
7c2ba97b
MR
3839#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
3840
3841static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
3842 struct snd_ctl_elem_value *ucontrol)
3843{
3844 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3845 struct sigmatel_spec *spec = codec->spec;
3846
d7a89436 3847 ucontrol->value.integer.value[0] = !!spec->hp_switch;
7c2ba97b
MR
3848 return 0;
3849}
3850
62558ce1 3851static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
c6e4c666 3852
7c2ba97b
MR
3853static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
3854 struct snd_ctl_elem_value *ucontrol)
3855{
3856 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3857 struct sigmatel_spec *spec = codec->spec;
d7a89436
TI
3858 int nid = kcontrol->private_value;
3859
3860 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
7c2ba97b 3861
25985edc 3862 /* check to be sure that the ports are up to date with
7c2ba97b
MR
3863 * switch changes
3864 */
62558ce1 3865 stac_issue_unsol_event(codec, nid);
7c2ba97b
MR
3866
3867 return 1;
3868}
3869
7c922de7
NL
3870static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
3871 struct snd_ctl_elem_info *uinfo)
3872{
3873 int i;
2b63536f 3874 static const char * const texts[] = {
7c922de7
NL
3875 "Mic In", "Line In", "Line Out"
3876 };
3877
3878 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3879 struct sigmatel_spec *spec = codec->spec;
3880 hda_nid_t nid = kcontrol->private_value;
3881
3882 if (nid == spec->mic_switch || nid == spec->line_switch)
3883 i = 3;
3884 else
3885 i = 2;
3886
3887 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3888 uinfo->value.enumerated.items = i;
3889 uinfo->count = 1;
3890 if (uinfo->value.enumerated.item >= i)
3891 uinfo->value.enumerated.item = i-1;
3892 strcpy(uinfo->value.enumerated.name,
3893 texts[uinfo->value.enumerated.item]);
3894
3895 return 0;
3896}
3897
3898static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
3899 struct snd_ctl_elem_value *ucontrol)
3900{
3901 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3902 hda_nid_t nid = kcontrol->private_value;
3903 unsigned int vref = stac92xx_vref_get(codec, nid);
3904
4740860b 3905 if (vref == snd_hda_get_default_vref(codec, nid))
7c922de7
NL
3906 ucontrol->value.enumerated.item[0] = 0;
3907 else if (vref == AC_PINCTL_VREF_GRD)
3908 ucontrol->value.enumerated.item[0] = 1;
3909 else if (vref == AC_PINCTL_VREF_HIZ)
3910 ucontrol->value.enumerated.item[0] = 2;
3911
3912 return 0;
3913}
3914
3915static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
3916 struct snd_ctl_elem_value *ucontrol)
3917{
3918 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3919 unsigned int new_vref = 0;
b8621516 3920 int error;
7c922de7
NL
3921 hda_nid_t nid = kcontrol->private_value;
3922
3923 if (ucontrol->value.enumerated.item[0] == 0)
4740860b 3924 new_vref = snd_hda_get_default_vref(codec, nid);
7c922de7
NL
3925 else if (ucontrol->value.enumerated.item[0] == 1)
3926 new_vref = AC_PINCTL_VREF_GRD;
3927 else if (ucontrol->value.enumerated.item[0] == 2)
3928 new_vref = AC_PINCTL_VREF_HIZ;
3929 else
3930 return 0;
3931
3932 if (new_vref != stac92xx_vref_get(codec, nid)) {
3933 error = stac92xx_vref_set(codec, nid, new_vref);
3934 return error;
3935 }
3936
3937 return 0;
3938}
3939
3940static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
3941 struct snd_ctl_elem_info *uinfo)
3942{
2b63536f 3943 char *texts[2];
7c922de7
NL
3944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3945 struct sigmatel_spec *spec = codec->spec;
3946
3947 if (kcontrol->private_value == spec->line_switch)
3948 texts[0] = "Line In";
3949 else
3950 texts[0] = "Mic In";
3951 texts[1] = "Line Out";
3952 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3953 uinfo->value.enumerated.items = 2;
3954 uinfo->count = 1;
3955
3956 if (uinfo->value.enumerated.item >= 2)
3957 uinfo->value.enumerated.item = 1;
3958 strcpy(uinfo->value.enumerated.name,
3959 texts[uinfo->value.enumerated.item]);
3960
3961 return 0;
3962}
403d1944
MP
3963
3964static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3965{
3966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3967 struct sigmatel_spec *spec = codec->spec;
7c922de7
NL
3968 hda_nid_t nid = kcontrol->private_value;
3969 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
403d1944 3970
7c922de7 3971 ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx];
403d1944
MP
3972 return 0;
3973}
3974
3975static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3976{
3977 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3978 struct sigmatel_spec *spec = codec->spec;
7c922de7
NL
3979 hda_nid_t nid = kcontrol->private_value;
3980 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
3981 unsigned short val = !!ucontrol->value.enumerated.item[0];
403d1944
MP
3982
3983 spec->io_switch[io_idx] = val;
3984
3985 if (val)
3986 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
c960a03b
TI
3987 else {
3988 unsigned int pinctl = AC_PINCTL_IN_EN;
3989 if (io_idx) /* set VREF for mic */
4740860b 3990 pinctl |= snd_hda_get_default_vref(codec, nid);
c960a03b
TI
3991 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3992 }
40c1d308
JZ
3993
3994 /* check the auto-mute again: we need to mute/unmute the speaker
3995 * appropriately according to the pin direction
3996 */
3997 if (spec->hp_detect)
62558ce1 3998 stac_issue_unsol_event(codec, nid);
40c1d308 3999
403d1944
MP
4000 return 1;
4001}
4002
0fb87bb4
ML
4003#define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
4004
4005static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
4006 struct snd_ctl_elem_value *ucontrol)
4007{
4008 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4009 struct sigmatel_spec *spec = codec->spec;
4010
4011 ucontrol->value.integer.value[0] = spec->clfe_swap;
4012 return 0;
4013}
4014
4015static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
4016 struct snd_ctl_elem_value *ucontrol)
4017{
4018 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4019 struct sigmatel_spec *spec = codec->spec;
4020 hda_nid_t nid = kcontrol->private_value & 0xff;
68ea7b2f 4021 unsigned int val = !!ucontrol->value.integer.value[0];
0fb87bb4 4022
68ea7b2f 4023 if (spec->clfe_swap == val)
0fb87bb4
ML
4024 return 0;
4025
68ea7b2f 4026 spec->clfe_swap = val;
0fb87bb4
ML
4027
4028 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
4029 spec->clfe_swap ? 0x4 : 0x0);
4030
4031 return 1;
4032}
4033
7c2ba97b
MR
4034#define STAC_CODEC_HP_SWITCH(xname) \
4035 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4036 .name = xname, \
4037 .index = 0, \
4038 .info = stac92xx_hp_switch_info, \
4039 .get = stac92xx_hp_switch_get, \
4040 .put = stac92xx_hp_switch_put, \
4041 }
4042
403d1944
MP
4043#define STAC_CODEC_IO_SWITCH(xname, xpval) \
4044 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4045 .name = xname, \
4046 .index = 0, \
4047 .info = stac92xx_io_switch_info, \
4048 .get = stac92xx_io_switch_get, \
4049 .put = stac92xx_io_switch_put, \
4050 .private_value = xpval, \
4051 }
4052
0fb87bb4
ML
4053#define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
4054 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4055 .name = xname, \
4056 .index = 0, \
4057 .info = stac92xx_clfe_switch_info, \
4058 .get = stac92xx_clfe_switch_get, \
4059 .put = stac92xx_clfe_switch_put, \
4060 .private_value = xpval, \
4061 }
403d1944 4062
c7d4b2fa
M
4063enum {
4064 STAC_CTL_WIDGET_VOL,
4065 STAC_CTL_WIDGET_MUTE,
123c07ae 4066 STAC_CTL_WIDGET_MUTE_BEEP,
09a99959 4067 STAC_CTL_WIDGET_MONO_MUX,
7c2ba97b 4068 STAC_CTL_WIDGET_HP_SWITCH,
403d1944 4069 STAC_CTL_WIDGET_IO_SWITCH,
2fc99890
NL
4070 STAC_CTL_WIDGET_CLFE_SWITCH,
4071 STAC_CTL_WIDGET_DC_BIAS
c7d4b2fa
M
4072};
4073
2b63536f 4074static const struct snd_kcontrol_new stac92xx_control_templates[] = {
c7d4b2fa
M
4075 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4076 HDA_CODEC_MUTE(NULL, 0, 0, 0),
123c07ae 4077 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
09a99959 4078 STAC_MONO_MUX,
7c2ba97b 4079 STAC_CODEC_HP_SWITCH(NULL),
403d1944 4080 STAC_CODEC_IO_SWITCH(NULL, 0),
0fb87bb4 4081 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2fc99890 4082 DC_BIAS(NULL, 0, 0),
c7d4b2fa
M
4083};
4084
4085/* add dynamic controls */
e3c75964
TI
4086static struct snd_kcontrol_new *
4087stac_control_new(struct sigmatel_spec *spec,
2b63536f 4088 const struct snd_kcontrol_new *ktemp,
4d02d1b6 4089 const char *name,
5e26dfd0 4090 unsigned int subdev)
c7d4b2fa 4091{
c8b6bf9b 4092 struct snd_kcontrol_new *knew;
c7d4b2fa 4093
603c4019
TI
4094 knew = snd_array_new(&spec->kctls);
4095 if (!knew)
e3c75964 4096 return NULL;
4d4e9bb3 4097 *knew = *ktemp;
82fe0c58 4098 knew->name = kstrdup(name, GFP_KERNEL);
e3c75964
TI
4099 if (!knew->name) {
4100 /* roolback */
4101 memset(knew, 0, sizeof(*knew));
4102 spec->kctls.alloced--;
4103 return NULL;
4104 }
5e26dfd0 4105 knew->subdevice = subdev;
e3c75964
TI
4106 return knew;
4107}
4108
62cbde18
TI
4109static struct snd_kcontrol_new *
4110add_control_temp(struct sigmatel_spec *spec,
4111 const struct snd_kcontrol_new *ktemp,
4112 int idx, const char *name,
4113 unsigned long val)
e3c75964 4114{
4d02d1b6 4115 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
5e26dfd0 4116 HDA_SUBDEV_AMP_FLAG);
e3c75964 4117 if (!knew)
62cbde18 4118 return NULL;
e3c75964 4119 knew->index = idx;
c7d4b2fa 4120 knew->private_value = val;
62cbde18
TI
4121 return knew;
4122}
4123
4124static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
4125 const struct snd_kcontrol_new *ktemp,
4126 int idx, const char *name,
4127 unsigned long val)
4128{
4129 return add_control_temp(spec, ktemp, idx, name, val) ? 0 : -ENOMEM;
c7d4b2fa
M
4130}
4131
4d4e9bb3
TI
4132static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
4133 int type, int idx, const char *name,
4134 unsigned long val)
4135{
4136 return stac92xx_add_control_temp(spec,
4137 &stac92xx_control_templates[type],
4138 idx, name, val);
4139}
4140
4682eee0
MR
4141
4142/* add dynamic controls */
4d4e9bb3
TI
4143static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
4144 const char *name, unsigned long val)
4682eee0
MR
4145{
4146 return stac92xx_add_control_idx(spec, type, 0, name, val);
4147}
4148
2b63536f 4149static const struct snd_kcontrol_new stac_input_src_temp = {
e3c75964
TI
4150 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4151 .name = "Input Source",
4152 .info = stac92xx_mux_enum_info,
4153 .get = stac92xx_mux_enum_get,
4154 .put = stac92xx_mux_enum_put,
4155};
4156
7c922de7
NL
4157static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
4158 hda_nid_t nid, int idx)
4159{
4160 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
4161 int control = 0;
4162 struct sigmatel_spec *spec = codec->spec;
4163 char name[22];
4164
99ae28be 4165 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
8d032a8f
DH
4166 if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf)
4167 != INPUT_PIN_ATTR_DOCK)
4168 return 0;
4740860b 4169 if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
7c922de7
NL
4170 && nid == spec->line_switch)
4171 control = STAC_CTL_WIDGET_IO_SWITCH;
4172 else if (snd_hda_query_pin_caps(codec, nid)
4173 & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT))
4174 control = STAC_CTL_WIDGET_DC_BIAS;
4175 else if (nid == spec->mic_switch)
4176 control = STAC_CTL_WIDGET_IO_SWITCH;
4177 }
4178
4179 if (control) {
201e06ff
TI
4180 snd_hda_get_pin_label(codec, nid, &spec->autocfg,
4181 name, sizeof(name), NULL);
7c922de7
NL
4182 return stac92xx_add_control(codec->spec, control,
4183 strcat(name, " Jack Mode"), nid);
4184 }
4185
4186 return 0;
4187}
4188
e3c75964
TI
4189static int stac92xx_add_input_source(struct sigmatel_spec *spec)
4190{
4191 struct snd_kcontrol_new *knew;
4192 struct hda_input_mux *imux = &spec->private_imux;
4193
3d21d3f7
TI
4194 if (spec->auto_mic)
4195 return 0; /* no need for input source */
e3c75964
TI
4196 if (!spec->num_adcs || imux->num_items <= 1)
4197 return 0; /* no need for input source control */
4198 knew = stac_control_new(spec, &stac_input_src_temp,
4d02d1b6 4199 stac_input_src_temp.name, 0);
e3c75964
TI
4200 if (!knew)
4201 return -ENOMEM;
4202 knew->count = spec->num_adcs;
4203 return 0;
4204}
4205
c21ca4a8
TI
4206/* check whether the line-input can be used as line-out */
4207static hda_nid_t check_line_out_switch(struct hda_codec *codec)
403d1944
MP
4208{
4209 struct sigmatel_spec *spec = codec->spec;
c21ca4a8
TI
4210 struct auto_pin_cfg *cfg = &spec->autocfg;
4211 hda_nid_t nid;
4212 unsigned int pincap;
eea7dc93 4213 int i;
8e9068b1 4214
c21ca4a8
TI
4215 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
4216 return 0;
eea7dc93 4217 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 4218 if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) {
eea7dc93
TI
4219 nid = cfg->inputs[i].pin;
4220 pincap = snd_hda_query_pin_caps(codec, nid);
4221 if (pincap & AC_PINCAP_OUT)
4222 return nid;
4223 }
4224 }
c21ca4a8
TI
4225 return 0;
4226}
403d1944 4227
eea7dc93
TI
4228static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
4229
c21ca4a8 4230/* check whether the mic-input can be used as line-out */
eea7dc93 4231static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
c21ca4a8
TI
4232{
4233 struct sigmatel_spec *spec = codec->spec;
4234 struct auto_pin_cfg *cfg = &spec->autocfg;
4235 unsigned int def_conf, pincap;
86e2959a 4236 int i;
c21ca4a8 4237
eea7dc93 4238 *dac = 0;
c21ca4a8
TI
4239 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
4240 return 0;
eea7dc93
TI
4241 for (i = 0; i < cfg->num_inputs; i++) {
4242 hda_nid_t nid = cfg->inputs[i].pin;
86e2959a 4243 if (cfg->inputs[i].type != AUTO_PIN_MIC)
eea7dc93 4244 continue;
330ee995 4245 def_conf = snd_hda_codec_get_pincfg(codec, nid);
c21ca4a8
TI
4246 /* some laptops have an internal analog microphone
4247 * which can't be used as a output */
99ae28be 4248 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
1327a32b 4249 pincap = snd_hda_query_pin_caps(codec, nid);
eea7dc93
TI
4250 if (pincap & AC_PINCAP_OUT) {
4251 *dac = get_unassigned_dac(codec, nid);
4252 if (*dac)
4253 return nid;
4254 }
403d1944 4255 }
403d1944 4256 }
403d1944
MP
4257 return 0;
4258}
4259
7b043899
SL
4260static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
4261{
4262 int i;
4263
4264 for (i = 0; i < spec->multiout.num_dacs; i++) {
4265 if (spec->multiout.dac_nids[i] == nid)
4266 return 1;
4267 }
4268
4269 return 0;
4270}
4271
c21ca4a8
TI
4272static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
4273{
4274 int i;
4275 if (is_in_dac_nids(spec, nid))
4276 return 1;
4277 for (i = 0; i < spec->autocfg.hp_outs; i++)
4278 if (spec->hp_dacs[i] == nid)
4279 return 1;
4280 for (i = 0; i < spec->autocfg.speaker_outs; i++)
4281 if (spec->speaker_dacs[i] == nid)
4282 return 1;
4283 return 0;
4284}
4285
4286static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
4287{
4288 struct sigmatel_spec *spec = codec->spec;
48718eab 4289 struct auto_pin_cfg *cfg = &spec->autocfg;
c21ca4a8 4290 int j, conn_len;
48718eab 4291 hda_nid_t conn[HDA_MAX_CONNECTIONS], fallback_dac;
c21ca4a8
TI
4292 unsigned int wcaps, wtype;
4293
4294 conn_len = snd_hda_get_connections(codec, nid, conn,
4295 HDA_MAX_CONNECTIONS);
36706005
CC
4296 /* 92HD88: trace back up the link of nids to find the DAC */
4297 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
4298 != AC_WID_AUD_OUT)) {
4299 nid = conn[0];
4300 conn_len = snd_hda_get_connections(codec, nid, conn,
4301 HDA_MAX_CONNECTIONS);
4302 }
c21ca4a8 4303 for (j = 0; j < conn_len; j++) {
14bafe32 4304 wcaps = get_wcaps(codec, conn[j]);
a22d543a 4305 wtype = get_wcaps_type(wcaps);
c21ca4a8
TI
4306 /* we check only analog outputs */
4307 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
4308 continue;
4309 /* if this route has a free DAC, assign it */
4310 if (!check_all_dac_nids(spec, conn[j])) {
4311 if (conn_len > 1) {
4312 /* select this DAC in the pin's input mux */
4313 snd_hda_codec_write_cache(codec, nid, 0,
4314 AC_VERB_SET_CONNECT_SEL, j);
4315 }
4316 return conn[j];
4317 }
4318 }
48718eab
DH
4319
4320 /* if all DACs are already assigned, connect to the primary DAC,
4321 unless we're assigning a secondary headphone */
4322 fallback_dac = spec->multiout.dac_nids[0];
4323 if (spec->multiout.hp_nid) {
4324 for (j = 0; j < cfg->hp_outs; j++)
4325 if (cfg->hp_pins[j] == nid) {
4326 fallback_dac = spec->multiout.hp_nid;
4327 break;
4328 }
4329 }
4330
ee58a7ca
TI
4331 if (conn_len > 1) {
4332 for (j = 0; j < conn_len; j++) {
48718eab 4333 if (conn[j] == fallback_dac) {
ee58a7ca
TI
4334 snd_hda_codec_write_cache(codec, nid, 0,
4335 AC_VERB_SET_CONNECT_SEL, j);
4336 break;
4337 }
4338 }
4339 }
c21ca4a8
TI
4340 return 0;
4341}
4342
4343static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
4344static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
4345
3cc08dc6 4346/*
7b043899
SL
4347 * Fill in the dac_nids table from the parsed pin configuration
4348 * This function only works when every pin in line_out_pins[]
4349 * contains atleast one DAC in its connection list. Some 92xx
4350 * codecs are not connected directly to a DAC, such as the 9200
4351 * and 9202/925x. For those, dac_nids[] must be hard-coded.
3cc08dc6 4352 */
c21ca4a8 4353static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
c7d4b2fa
M
4354{
4355 struct sigmatel_spec *spec = codec->spec;
c21ca4a8
TI
4356 struct auto_pin_cfg *cfg = &spec->autocfg;
4357 int i;
4358 hda_nid_t nid, dac;
7b043899 4359
c7d4b2fa
M
4360 for (i = 0; i < cfg->line_outs; i++) {
4361 nid = cfg->line_out_pins[i];
c21ca4a8
TI
4362 dac = get_unassigned_dac(codec, nid);
4363 if (!dac) {
df802952
TI
4364 if (spec->multiout.num_dacs > 0) {
4365 /* we have already working output pins,
4366 * so let's drop the broken ones again
4367 */
4368 cfg->line_outs = spec->multiout.num_dacs;
4369 break;
4370 }
7b043899
SL
4371 /* error out, no available DAC found */
4372 snd_printk(KERN_ERR
4373 "%s: No available DAC for pin 0x%x\n",
4374 __func__, nid);
4375 return -ENODEV;
4376 }
c21ca4a8
TI
4377 add_spec_dacs(spec, dac);
4378 }
7b043899 4379
139e071b
TI
4380 for (i = 0; i < cfg->hp_outs; i++) {
4381 nid = cfg->hp_pins[i];
4382 dac = get_unassigned_dac(codec, nid);
4383 if (dac) {
4384 if (!spec->multiout.hp_nid)
4385 spec->multiout.hp_nid = dac;
4386 else
4387 add_spec_extra_dacs(spec, dac);
4388 }
4389 spec->hp_dacs[i] = dac;
4390 }
4391
4392 for (i = 0; i < cfg->speaker_outs; i++) {
4393 nid = cfg->speaker_pins[i];
4394 dac = get_unassigned_dac(codec, nid);
4395 if (dac)
4396 add_spec_extra_dacs(spec, dac);
4397 spec->speaker_dacs[i] = dac;
4398 }
4399
c21ca4a8
TI
4400 /* add line-in as output */
4401 nid = check_line_out_switch(codec);
4402 if (nid) {
4403 dac = get_unassigned_dac(codec, nid);
4404 if (dac) {
4405 snd_printdd("STAC: Add line-in 0x%x as output %d\n",
4406 nid, cfg->line_outs);
4407 cfg->line_out_pins[cfg->line_outs] = nid;
4408 cfg->line_outs++;
4409 spec->line_switch = nid;
4410 add_spec_dacs(spec, dac);
4411 }
4412 }
4413 /* add mic as output */
eea7dc93
TI
4414 nid = check_mic_out_switch(codec, &dac);
4415 if (nid && dac) {
4416 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
4417 nid, cfg->line_outs);
4418 cfg->line_out_pins[cfg->line_outs] = nid;
4419 cfg->line_outs++;
4420 spec->mic_switch = nid;
4421 add_spec_dacs(spec, dac);
c21ca4a8 4422 }
c7d4b2fa 4423
c21ca4a8 4424 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
7b043899
SL
4425 spec->multiout.num_dacs,
4426 spec->multiout.dac_nids[0],
4427 spec->multiout.dac_nids[1],
4428 spec->multiout.dac_nids[2],
4429 spec->multiout.dac_nids[3],
4430 spec->multiout.dac_nids[4]);
c21ca4a8 4431
c7d4b2fa
M
4432 return 0;
4433}
4434
eb06ed8f 4435/* create volume control/switch for the given prefx type */
668b9652
TI
4436static int create_controls_idx(struct hda_codec *codec, const char *pfx,
4437 int idx, hda_nid_t nid, int chs)
eb06ed8f 4438{
7c7767eb 4439 struct sigmatel_spec *spec = codec->spec;
eb06ed8f
TI
4440 char name[32];
4441 int err;
4442
7c7767eb
TI
4443 if (!spec->check_volume_offset) {
4444 unsigned int caps, step, nums, db_scale;
4445 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
4446 step = (caps & AC_AMPCAP_STEP_SIZE) >>
4447 AC_AMPCAP_STEP_SIZE_SHIFT;
4448 step = (step + 1) * 25; /* in .01dB unit */
4449 nums = (caps & AC_AMPCAP_NUM_STEPS) >>
4450 AC_AMPCAP_NUM_STEPS_SHIFT;
4451 db_scale = nums * step;
4452 /* if dB scale is over -64dB, and finer enough,
4453 * let's reduce it to half
4454 */
4455 if (db_scale > 6400 && nums >= 0x1f)
4456 spec->volume_offset = nums / 2;
4457 spec->check_volume_offset = 1;
4458 }
4459
eb06ed8f 4460 sprintf(name, "%s Playback Volume", pfx);
668b9652 4461 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name,
7c7767eb
TI
4462 HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT,
4463 spec->volume_offset));
eb06ed8f
TI
4464 if (err < 0)
4465 return err;
4466 sprintf(name, "%s Playback Switch", pfx);
668b9652 4467 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name,
eb06ed8f
TI
4468 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
4469 if (err < 0)
4470 return err;
4471 return 0;
4472}
4473
668b9652
TI
4474#define create_controls(codec, pfx, nid, chs) \
4475 create_controls_idx(codec, pfx, 0, nid, chs)
4476
ae0afd81
MR
4477static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
4478{
c21ca4a8 4479 if (spec->multiout.num_dacs > 4) {
ae0afd81
MR
4480 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
4481 return 1;
4482 } else {
dda14410
TI
4483 snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids);
4484 spec->dac_nids[spec->multiout.num_dacs] = nid;
ae0afd81
MR
4485 spec->multiout.num_dacs++;
4486 }
4487 return 0;
4488}
4489
c21ca4a8 4490static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
ae0afd81 4491{
c21ca4a8
TI
4492 int i;
4493 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
4494 if (!spec->multiout.extra_out_nid[i]) {
4495 spec->multiout.extra_out_nid[i] = nid;
4496 return 0;
4497 }
4498 }
4499 printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
4500 return 1;
ae0afd81
MR
4501}
4502
dc04d1b4
TI
4503/* Create output controls
4504 * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT)
4505 */
4506static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
4507 const hda_nid_t *pins,
4508 const hda_nid_t *dac_nids,
4509 int type)
c7d4b2fa 4510{
76624534 4511 struct sigmatel_spec *spec = codec->spec;
ea734963 4512 static const char * const chname[4] = {
19039bd0
TI
4513 "Front", "Surround", NULL /*CLFE*/, "Side"
4514 };
dc04d1b4 4515 hda_nid_t nid;
91589232
TI
4516 int i, err;
4517 unsigned int wid_caps;
0fb87bb4 4518
dc04d1b4 4519 for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
ffd0e56c 4520 if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
e35d9d6a 4521 if (is_jack_detectable(codec, pins[i]))
ffd0e56c
TI
4522 spec->hp_detect = 1;
4523 }
dc04d1b4
TI
4524 nid = dac_nids[i];
4525 if (!nid)
4526 continue;
4527 if (type != AUTO_PIN_HP_OUT && i == 2) {
c7d4b2fa 4528 /* Center/LFE */
7c7767eb 4529 err = create_controls(codec, "Center", nid, 1);
eb06ed8f 4530 if (err < 0)
c7d4b2fa 4531 return err;
7c7767eb 4532 err = create_controls(codec, "LFE", nid, 2);
eb06ed8f 4533 if (err < 0)
c7d4b2fa 4534 return err;
0fb87bb4
ML
4535
4536 wid_caps = get_wcaps(codec, nid);
4537
4538 if (wid_caps & AC_WCAP_LR_SWAP) {
4539 err = stac92xx_add_control(spec,
4540 STAC_CTL_WIDGET_CLFE_SWITCH,
4541 "Swap Center/LFE Playback Switch", nid);
4542
4543 if (err < 0)
4544 return err;
4545 }
4546
c7d4b2fa 4547 } else {
dc04d1b4 4548 const char *name;
668b9652 4549 int idx;
dc04d1b4
TI
4550 switch (type) {
4551 case AUTO_PIN_HP_OUT:
668b9652
TI
4552 name = "Headphone";
4553 idx = i;
dc04d1b4
TI
4554 break;
4555 case AUTO_PIN_SPEAKER_OUT:
f37bc7a8
TI
4556 if (num_outs <= 2) {
4557 name = i ? "Bass Speaker" : "Speaker";
4558 idx = 0;
298efee7
DH
4559 break;
4560 }
4561 /* Fall through in case of multi speaker outs */
dc04d1b4
TI
4562 default:
4563 name = chname[i];
668b9652 4564 idx = 0;
dc04d1b4 4565 break;
76624534 4566 }
668b9652 4567 err = create_controls_idx(codec, name, idx, nid, 3);
eb06ed8f 4568 if (err < 0)
c7d4b2fa
M
4569 return err;
4570 }
4571 }
dc04d1b4
TI
4572 return 0;
4573}
4574
62cbde18
TI
4575static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4576 unsigned int dir_mask, unsigned int data);
4577
4578/* hook for controlling mic-mute LED GPIO */
4579static int stac92xx_capture_sw_put_led(struct snd_kcontrol *kcontrol,
4580 struct snd_ctl_elem_value *ucontrol)
4581{
4582 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4583 struct sigmatel_spec *spec = codec->spec;
4584 int err;
4585 bool mute;
4586
4587 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4588 if (err <= 0)
4589 return err;
4590 mute = !(ucontrol->value.integer.value[0] &&
4591 ucontrol->value.integer.value[1]);
4592 if (spec->mic_mute_led_on != mute) {
4593 spec->mic_mute_led_on = mute;
4594 if (mute)
4595 spec->gpio_data |= spec->mic_mute_led_gpio;
4596 else
4597 spec->gpio_data &= ~spec->mic_mute_led_gpio;
4598 stac_gpio_set(codec, spec->gpio_mask,
4599 spec->gpio_dir, spec->gpio_data);
4600 }
4601 return err;
4602}
4603
6479c631
TI
4604static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
4605 unsigned long sw, int idx)
4606{
62cbde18
TI
4607 struct sigmatel_spec *spec = codec->spec;
4608 struct snd_kcontrol_new *knew;
6479c631 4609 int err;
62cbde18 4610
6479c631 4611 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
bf677bd8 4612 "Capture Volume", vol);
6479c631
TI
4613 if (err < 0)
4614 return err;
62cbde18
TI
4615
4616 knew = add_control_temp(spec,
4617 &stac92xx_control_templates[STAC_CTL_WIDGET_MUTE],
4618 idx, "Capture Switch", sw);
4619 if (!knew)
4620 return -ENOMEM;
4621 /* add a LED hook for some HP laptops */
4622 if (spec->mic_mute_led_gpio)
4623 knew->put = stac92xx_capture_sw_put_led;
4624
6479c631
TI
4625 return 0;
4626}
4627
dc04d1b4
TI
4628/* add playback controls from the parsed DAC table */
4629static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
4630 const struct auto_pin_cfg *cfg)
4631{
4632 struct sigmatel_spec *spec = codec->spec;
7c922de7 4633 hda_nid_t nid;
dc04d1b4 4634 int err;
7c922de7 4635 int idx;
dc04d1b4
TI
4636
4637 err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins,
4638 spec->multiout.dac_nids,
4639 cfg->line_out_type);
4640 if (err < 0)
4641 return err;
c7d4b2fa 4642
a9cb5c90 4643 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
7c2ba97b
MR
4644 err = stac92xx_add_control(spec,
4645 STAC_CTL_WIDGET_HP_SWITCH,
d7a89436
TI
4646 "Headphone as Line Out Switch",
4647 cfg->hp_pins[cfg->hp_outs - 1]);
7c2ba97b
MR
4648 if (err < 0)
4649 return err;
4650 }
4651
eea7dc93 4652 for (idx = 0; idx < cfg->num_inputs; idx++) {
86e2959a 4653 if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN)
eea7dc93
TI
4654 break;
4655 nid = cfg->inputs[idx].pin;
4656 err = stac92xx_add_jack_mode_control(codec, nid, idx);
4657 if (err < 0)
4658 return err;
b5895dc8 4659 }
403d1944 4660
c7d4b2fa
M
4661 return 0;
4662}
4663
eb06ed8f
TI
4664/* add playback controls for Speaker and HP outputs */
4665static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
4666 struct auto_pin_cfg *cfg)
4667{
4668 struct sigmatel_spec *spec = codec->spec;
dc04d1b4
TI
4669 int err;
4670
4671 err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins,
4672 spec->hp_dacs, AUTO_PIN_HP_OUT);
4673 if (err < 0)
4674 return err;
4675
4676 err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins,
4677 spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT);
4678 if (err < 0)
4679 return err;
eb06ed8f 4680
c7d4b2fa
M
4681 return 0;
4682}
4683
b22b4821 4684/* labels for mono mux outputs */
ea734963 4685static const char * const stac92xx_mono_labels[4] = {
d0513fc6 4686 "DAC0", "DAC1", "Mixer", "DAC2"
b22b4821
MR
4687};
4688
4689/* create mono mux for mono out on capable codecs */
4690static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
4691{
4692 struct sigmatel_spec *spec = codec->spec;
4693 struct hda_input_mux *mono_mux = &spec->private_mono_mux;
4694 int i, num_cons;
4695 hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)];
4696
4697 num_cons = snd_hda_get_connections(codec,
4698 spec->mono_nid,
4699 con_lst,
4700 HDA_MAX_NUM_INPUTS);
16a433d8 4701 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
b22b4821
MR
4702 return -EINVAL;
4703
10a20af7
TI
4704 for (i = 0; i < num_cons; i++)
4705 snd_hda_add_imux_item(mono_mux, stac92xx_mono_labels[i], i,
4706 NULL);
09a99959
MR
4707
4708 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
4709 "Mono Mux", spec->mono_nid);
b22b4821
MR
4710}
4711
1cd2224c
MR
4712/* create PC beep volume controls */
4713static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
4714 hda_nid_t nid)
4715{
4716 struct sigmatel_spec *spec = codec->spec;
4717 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
123c07ae
JK
4718 int err, type = STAC_CTL_WIDGET_MUTE_BEEP;
4719
4720 if (spec->anabeep_nid == nid)
4721 type = STAC_CTL_WIDGET_MUTE;
1cd2224c
MR
4722
4723 /* check for mute support for the the amp */
4724 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
123c07ae 4725 err = stac92xx_add_control(spec, type,
d355c82a 4726 "Beep Playback Switch",
1cd2224c
MR
4727 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
4728 if (err < 0)
4729 return err;
4730 }
4731
4732 /* check to see if there is volume support for the amp */
4733 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
4734 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
d355c82a 4735 "Beep Playback Volume",
1cd2224c
MR
4736 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
4737 if (err < 0)
4738 return err;
4739 }
4740 return 0;
4741}
4742
4d4e9bb3
TI
4743#ifdef CONFIG_SND_HDA_INPUT_BEEP
4744#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
4745
4746static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
4747 struct snd_ctl_elem_value *ucontrol)
4748{
4749 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4750 ucontrol->value.integer.value[0] = codec->beep->enabled;
4751 return 0;
4752}
4753
4754static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
4755 struct snd_ctl_elem_value *ucontrol)
4756{
4757 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
123c07ae 4758 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
4d4e9bb3
TI
4759}
4760
2b63536f 4761static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
4d4e9bb3
TI
4762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4763 .info = stac92xx_dig_beep_switch_info,
4764 .get = stac92xx_dig_beep_switch_get,
4765 .put = stac92xx_dig_beep_switch_put,
4766};
4767
4768static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
4769{
4770 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
d355c82a 4771 0, "Beep Playback Switch", 0);
4d4e9bb3
TI
4772}
4773#endif
4774
4682eee0
MR
4775static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
4776{
4777 struct sigmatel_spec *spec = codec->spec;
667067d8 4778 int i, j, err = 0;
4682eee0
MR
4779
4780 for (i = 0; i < spec->num_muxes; i++) {
667067d8
TI
4781 hda_nid_t nid;
4782 unsigned int wcaps;
4783 unsigned long val;
4784
4682eee0
MR
4785 nid = spec->mux_nids[i];
4786 wcaps = get_wcaps(codec, nid);
667067d8
TI
4787 if (!(wcaps & AC_WCAP_OUT_AMP))
4788 continue;
4682eee0 4789
667067d8
TI
4790 /* check whether already the same control was created as
4791 * normal Capture Volume.
4792 */
4793 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4794 for (j = 0; j < spec->num_caps; j++) {
4795 if (spec->capvols[j] == val)
4796 break;
4682eee0 4797 }
667067d8
TI
4798 if (j < spec->num_caps)
4799 continue;
4800
4801 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i,
4802 "Mux Capture Volume", val);
4803 if (err < 0)
4804 return err;
4682eee0
MR
4805 }
4806 return 0;
4807};
4808
ea734963 4809static const char * const stac92xx_spdif_labels[3] = {
65973632 4810 "Digital Playback", "Analog Mux 1", "Analog Mux 2",
d9737751
MR
4811};
4812
4813static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
4814{
4815 struct sigmatel_spec *spec = codec->spec;
4816 struct hda_input_mux *spdif_mux = &spec->private_smux;
ea734963 4817 const char * const *labels = spec->spdif_labels;
d9737751 4818 int i, num_cons;
65973632 4819 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
d9737751
MR
4820
4821 num_cons = snd_hda_get_connections(codec,
4822 spec->smux_nids[0],
4823 con_lst,
4824 HDA_MAX_NUM_INPUTS);
16a433d8 4825 if (num_cons <= 0)
d9737751
MR
4826 return -EINVAL;
4827
65973632
MR
4828 if (!labels)
4829 labels = stac92xx_spdif_labels;
4830
10a20af7
TI
4831 for (i = 0; i < num_cons; i++)
4832 snd_hda_add_imux_item(spdif_mux, labels[i], i, NULL);
d9737751
MR
4833
4834 return 0;
4835}
4836
8b65727b 4837/* labels for dmic mux inputs */
ea734963 4838static const char * const stac92xx_dmic_labels[5] = {
8b65727b
MP
4839 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
4840 "Digital Mic 3", "Digital Mic 4"
4841};
4842
699d8995
VK
4843static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
4844 int idx)
4845{
4846 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
4847 int nums;
4848 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
4849 if (idx >= 0 && idx < nums)
4850 return conn[idx];
4851 return 0;
4852}
4853
8d087c76
TI
4854/* look for NID recursively */
4855#define get_connection_index(codec, mux, nid) \
4856 snd_hda_get_conn_index(codec, mux, nid, 1)
3d21d3f7 4857
667067d8 4858/* create a volume assigned to the given pin (only if supported) */
96f845de 4859/* return 1 if the volume control is created */
667067d8 4860static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
eea7dc93 4861 const char *label, int idx, int direction)
667067d8
TI
4862{
4863 unsigned int caps, nums;
4864 char name[32];
96f845de 4865 int err;
667067d8 4866
96f845de
TI
4867 if (direction == HDA_OUTPUT)
4868 caps = AC_WCAP_OUT_AMP;
4869 else
4870 caps = AC_WCAP_IN_AMP;
4871 if (!(get_wcaps(codec, nid) & caps))
667067d8 4872 return 0;
96f845de 4873 caps = query_amp_caps(codec, nid, direction);
667067d8
TI
4874 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
4875 if (!nums)
4876 return 0;
4877 snprintf(name, sizeof(name), "%s Capture Volume", label);
eea7dc93
TI
4878 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name,
4879 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
96f845de
TI
4880 if (err < 0)
4881 return err;
4882 return 1;
667067d8
TI
4883}
4884
8b65727b
MP
4885/* create playback/capture controls for input pins on dmic capable codecs */
4886static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
4887 const struct auto_pin_cfg *cfg)
4888{
4889 struct sigmatel_spec *spec = codec->spec;
5207e10e 4890 struct hda_input_mux *imux = &spec->private_imux;
8b65727b 4891 struct hda_input_mux *dimux = &spec->private_dimux;
263d0328 4892 int err, i;
5207e10e 4893 unsigned int def_conf;
8b65727b 4894
10a20af7 4895 snd_hda_add_imux_item(dimux, stac92xx_dmic_labels[0], 0, NULL);
5207e10e 4896
8b65727b 4897 for (i = 0; i < spec->num_dmics; i++) {
0678accd 4898 hda_nid_t nid;
10a20af7 4899 int index, type_idx;
201e06ff 4900 char label[32];
8b65727b 4901
667067d8
TI
4902 nid = spec->dmic_nids[i];
4903 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
4904 continue;
4905 def_conf = snd_hda_codec_get_pincfg(codec, nid);
8b65727b
MP
4906 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
4907 continue;
4908
3d21d3f7
TI
4909 index = get_connection_index(codec, spec->dmux_nids[0], nid);
4910 if (index < 0)
4911 continue;
4912
201e06ff
TI
4913 snd_hda_get_pin_label(codec, nid, &spec->autocfg,
4914 label, sizeof(label), NULL);
10a20af7 4915 snd_hda_add_imux_item(dimux, label, index, &type_idx);
2d7ec12b
TI
4916 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
4917 snd_hda_add_imux_item(imux, label, index, &type_idx);
5207e10e 4918
10a20af7
TI
4919 err = create_elem_capture_vol(codec, nid, label, type_idx,
4920 HDA_INPUT);
667067d8
TI
4921 if (err < 0)
4922 return err;
96f845de
TI
4923 if (!err) {
4924 err = create_elem_capture_vol(codec, nid, label,
10a20af7 4925 type_idx, HDA_OUTPUT);
96f845de
TI
4926 if (err < 0)
4927 return err;
699d8995
VK
4928 if (!err) {
4929 nid = get_connected_node(codec,
4930 spec->dmux_nids[0], index);
4931 if (nid)
4932 err = create_elem_capture_vol(codec,
4933 nid, label,
4934 type_idx, HDA_INPUT);
4935 if (err < 0)
4936 return err;
4937 }
96f845de 4938 }
8b65727b
MP
4939 }
4940
4941 return 0;
4942}
4943
3d21d3f7 4944static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
9907790a 4945 hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock)
3d21d3f7
TI
4946{
4947 unsigned int cfg;
1f83ac5a 4948 unsigned int type;
3d21d3f7
TI
4949
4950 if (!nid)
4951 return 0;
4952 cfg = snd_hda_codec_get_pincfg(codec, nid);
1f83ac5a 4953 type = get_defcfg_device(cfg);
99ae28be
TI
4954 switch (snd_hda_get_input_pin_attr(cfg)) {
4955 case INPUT_PIN_ATTR_INT:
3d21d3f7
TI
4956 if (*fixed)
4957 return 1; /* already occupied */
1f83ac5a
TI
4958 if (type != AC_JACK_MIC_IN)
4959 return 1; /* invalid type */
3d21d3f7
TI
4960 *fixed = nid;
4961 break;
99ae28be
TI
4962 case INPUT_PIN_ATTR_UNUSED:
4963 break;
4964 case INPUT_PIN_ATTR_DOCK:
4965 if (*dock)
4966 return 1; /* already occupied */
1f83ac5a
TI
4967 if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN)
4968 return 1; /* invalid type */
99ae28be
TI
4969 *dock = nid;
4970 break;
4971 default:
3d21d3f7
TI
4972 if (*ext)
4973 return 1; /* already occupied */
1f83ac5a
TI
4974 if (type != AC_JACK_MIC_IN)
4975 return 1; /* invalid type */
3d21d3f7
TI
4976 *ext = nid;
4977 break;
4978 }
4979 return 0;
4980}
4981
4982static int set_mic_route(struct hda_codec *codec,
4983 struct sigmatel_mic_route *mic,
4984 hda_nid_t pin)
4985{
4986 struct sigmatel_spec *spec = codec->spec;
4987 struct auto_pin_cfg *cfg = &spec->autocfg;
4988 int i;
4989
4990 mic->pin = pin;
9907790a
CC
4991 if (pin == 0)
4992 return 0;
eea7dc93
TI
4993 for (i = 0; i < cfg->num_inputs; i++) {
4994 if (pin == cfg->inputs[i].pin)
3d21d3f7 4995 break;
eea7dc93 4996 }
86e2959a 4997 if (i < cfg->num_inputs && cfg->inputs[i].type == AUTO_PIN_MIC) {
3d21d3f7 4998 /* analog pin */
3d21d3f7
TI
4999 i = get_connection_index(codec, spec->mux_nids[0], pin);
5000 if (i < 0)
5001 return -1;
5002 mic->mux_idx = i;
02d33322
TI
5003 mic->dmux_idx = -1;
5004 if (spec->dmux_nids)
5005 mic->dmux_idx = get_connection_index(codec,
5006 spec->dmux_nids[0],
5007 spec->mux_nids[0]);
da2a2aaa 5008 } else if (spec->dmux_nids) {
3d21d3f7 5009 /* digital pin */
3d21d3f7
TI
5010 i = get_connection_index(codec, spec->dmux_nids[0], pin);
5011 if (i < 0)
5012 return -1;
5013 mic->dmux_idx = i;
02d33322
TI
5014 mic->mux_idx = -1;
5015 if (spec->mux_nids)
5016 mic->mux_idx = get_connection_index(codec,
5017 spec->mux_nids[0],
5018 spec->dmux_nids[0]);
3d21d3f7
TI
5019 }
5020 return 0;
5021}
5022
5023/* return non-zero if the device is for automatic mic switch */
5024static int stac_check_auto_mic(struct hda_codec *codec)
5025{
5026 struct sigmatel_spec *spec = codec->spec;
5027 struct auto_pin_cfg *cfg = &spec->autocfg;
9907790a 5028 hda_nid_t fixed, ext, dock;
3d21d3f7
TI
5029 int i;
5030
9907790a 5031 fixed = ext = dock = 0;
eea7dc93 5032 for (i = 0; i < cfg->num_inputs; i++)
9907790a
CC
5033 if (check_mic_pin(codec, cfg->inputs[i].pin,
5034 &fixed, &ext, &dock))
3d21d3f7
TI
5035 return 0;
5036 for (i = 0; i < spec->num_dmics; i++)
9907790a
CC
5037 if (check_mic_pin(codec, spec->dmic_nids[i],
5038 &fixed, &ext, &dock))
3d21d3f7 5039 return 0;
80c67852 5040 if (!fixed || (!ext && !dock))
9907790a 5041 return 0; /* no input to switch */
e35d9d6a 5042 if (!is_jack_detectable(codec, ext))
3d21d3f7
TI
5043 return 0; /* no unsol support */
5044 if (set_mic_route(codec, &spec->ext_mic, ext) ||
9907790a
CC
5045 set_mic_route(codec, &spec->int_mic, fixed) ||
5046 set_mic_route(codec, &spec->dock_mic, dock))
3d21d3f7
TI
5047 return 0; /* something is wrong */
5048 return 1;
5049}
5050
c7d4b2fa
M
5051/* create playback/capture controls for input pins */
5052static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
5053{
5054 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa 5055 struct hda_input_mux *imux = &spec->private_imux;
667067d8 5056 int i, j;
263d0328 5057 const char *label;
c7d4b2fa 5058
eea7dc93
TI
5059 for (i = 0; i < cfg->num_inputs; i++) {
5060 hda_nid_t nid = cfg->inputs[i].pin;
10a20af7 5061 int index, err, type_idx;
314634bc 5062
314634bc
TI
5063 index = -1;
5064 for (j = 0; j < spec->num_muxes; j++) {
667067d8
TI
5065 index = get_connection_index(codec, spec->mux_nids[j],
5066 nid);
5067 if (index >= 0)
5068 break;
c7d4b2fa 5069 }
667067d8
TI
5070 if (index < 0)
5071 continue;
5072
10a20af7
TI
5073 label = hda_get_autocfg_input_label(codec, cfg, i);
5074 snd_hda_add_imux_item(imux, label, index, &type_idx);
263d0328 5075
667067d8 5076 err = create_elem_capture_vol(codec, nid,
263d0328 5077 label, type_idx,
96f845de 5078 HDA_INPUT);
667067d8
TI
5079 if (err < 0)
5080 return err;
c7d4b2fa 5081 }
5207e10e 5082 spec->num_analog_muxes = imux->num_items;
c7d4b2fa 5083
7b043899 5084 if (imux->num_items) {
62fe78e9
SR
5085 /*
5086 * Set the current input for the muxes.
5087 * The STAC9221 has two input muxes with identical source
5088 * NID lists. Hopefully this won't get confused.
5089 */
5090 for (i = 0; i < spec->num_muxes; i++) {
82beb8fd
TI
5091 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
5092 AC_VERB_SET_CONNECT_SEL,
5093 imux->items[0].index);
62fe78e9
SR
5094 }
5095 }
5096
c7d4b2fa
M
5097 return 0;
5098}
5099
c7d4b2fa
M
5100static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
5101{
5102 struct sigmatel_spec *spec = codec->spec;
5103 int i;
5104
5105 for (i = 0; i < spec->autocfg.line_outs; i++) {
5106 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5107 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
5108 }
5109}
5110
5111static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
5112{
5113 struct sigmatel_spec *spec = codec->spec;
eb06ed8f 5114 int i;
c7d4b2fa 5115
eb06ed8f
TI
5116 for (i = 0; i < spec->autocfg.hp_outs; i++) {
5117 hda_nid_t pin;
5118 pin = spec->autocfg.hp_pins[i];
5119 if (pin) /* connect to front */
5120 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
5121 }
5122 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
5123 hda_nid_t pin;
5124 pin = spec->autocfg.speaker_pins[i];
5125 if (pin) /* connect to front */
5126 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
5127 }
c7d4b2fa
M
5128}
5129
8af3aeb4
TI
5130static int is_dual_headphones(struct hda_codec *codec)
5131{
5132 struct sigmatel_spec *spec = codec->spec;
5133 int i, valid_hps;
5134
5135 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT ||
5136 spec->autocfg.hp_outs <= 1)
5137 return 0;
5138 valid_hps = 0;
5139 for (i = 0; i < spec->autocfg.hp_outs; i++) {
5140 hda_nid_t nid = spec->autocfg.hp_pins[i];
5141 unsigned int cfg = snd_hda_codec_get_pincfg(codec, nid);
5142 if (get_defcfg_location(cfg) & AC_JACK_LOC_SEPARATE)
5143 continue;
5144 valid_hps++;
5145 }
5146 return (valid_hps > 1);
5147}
5148
5149
9009b0e4 5150static int stac92xx_parse_auto_config(struct hda_codec *codec)
c7d4b2fa
M
5151{
5152 struct sigmatel_spec *spec = codec->spec;
9009b0e4 5153 hda_nid_t dig_out = 0, dig_in = 0;
dc04d1b4 5154 int hp_swap = 0;
6479c631 5155 int i, err;
c7d4b2fa 5156
8b65727b
MP
5157 if ((err = snd_hda_parse_pin_def_config(codec,
5158 &spec->autocfg,
5159 spec->dmic_nids)) < 0)
c7d4b2fa 5160 return err;
82bc955f 5161 if (! spec->autocfg.line_outs)
869264c4 5162 return 0; /* can't find valid pin config */
19039bd0 5163
bcecd9bd
JZ
5164 /* If we have no real line-out pin and multiple hp-outs, HPs should
5165 * be set up as multi-channel outputs.
5166 */
8af3aeb4 5167 if (is_dual_headphones(codec)) {
bcecd9bd
JZ
5168 /* Copy hp_outs to line_outs, backup line_outs in
5169 * speaker_outs so that the following routines can handle
5170 * HP pins as primary outputs.
5171 */
c21ca4a8 5172 snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
bcecd9bd
JZ
5173 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
5174 sizeof(spec->autocfg.line_out_pins));
5175 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
5176 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
5177 sizeof(spec->autocfg.hp_pins));
5178 spec->autocfg.line_outs = spec->autocfg.hp_outs;
c21ca4a8
TI
5179 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
5180 spec->autocfg.hp_outs = 0;
dc04d1b4 5181 hp_swap = 1;
bcecd9bd 5182 }
09a99959 5183 if (spec->autocfg.mono_out_pin) {
d0513fc6
MR
5184 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
5185 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
09a99959
MR
5186 u32 caps = query_amp_caps(codec,
5187 spec->autocfg.mono_out_pin, dir);
5188 hda_nid_t conn_list[1];
5189
5190 /* get the mixer node and then the mono mux if it exists */
5191 if (snd_hda_get_connections(codec,
5192 spec->autocfg.mono_out_pin, conn_list, 1) &&
5193 snd_hda_get_connections(codec, conn_list[0],
16a433d8 5194 conn_list, 1) > 0) {
09a99959
MR
5195
5196 int wcaps = get_wcaps(codec, conn_list[0]);
a22d543a 5197 int wid_type = get_wcaps_type(wcaps);
09a99959
MR
5198 /* LR swap check, some stac925x have a mux that
5199 * changes the DACs output path instead of the
5200 * mono-mux path.
5201 */
5202 if (wid_type == AC_WID_AUD_SEL &&
5203 !(wcaps & AC_WCAP_LR_SWAP))
5204 spec->mono_nid = conn_list[0];
5205 }
d0513fc6
MR
5206 if (dir) {
5207 hda_nid_t nid = spec->autocfg.mono_out_pin;
5208
5209 /* most mono outs have a least a mute/unmute switch */
5210 dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
5211 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
5212 "Mono Playback Switch",
5213 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
09a99959
MR
5214 if (err < 0)
5215 return err;
d0513fc6
MR
5216 /* check for volume support for the amp */
5217 if ((caps & AC_AMPCAP_NUM_STEPS)
5218 >> AC_AMPCAP_NUM_STEPS_SHIFT) {
5219 err = stac92xx_add_control(spec,
5220 STAC_CTL_WIDGET_VOL,
5221 "Mono Playback Volume",
5222 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
5223 if (err < 0)
5224 return err;
5225 }
09a99959
MR
5226 }
5227
5228 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
5229 AC_PINCTL_OUT_EN);
5230 }
bcecd9bd 5231
c21ca4a8
TI
5232 if (!spec->multiout.num_dacs) {
5233 err = stac92xx_auto_fill_dac_nids(codec);
5234 if (err < 0)
19039bd0 5235 return err;
c9280d68
TI
5236 err = stac92xx_auto_create_multi_out_ctls(codec,
5237 &spec->autocfg);
5238 if (err < 0)
5239 return err;
c21ca4a8 5240 }
c7d4b2fa 5241
1cd2224c
MR
5242 /* setup analog beep controls */
5243 if (spec->anabeep_nid > 0) {
5244 err = stac92xx_auto_create_beep_ctls(codec,
5245 spec->anabeep_nid);
5246 if (err < 0)
5247 return err;
5248 }
5249
5250 /* setup digital beep controls and input device */
5251#ifdef CONFIG_SND_HDA_INPUT_BEEP
5252 if (spec->digbeep_nid > 0) {
5253 hda_nid_t nid = spec->digbeep_nid;
4d4e9bb3 5254 unsigned int caps;
1cd2224c
MR
5255
5256 err = stac92xx_auto_create_beep_ctls(codec, nid);
5257 if (err < 0)
5258 return err;
5259 err = snd_hda_attach_beep_device(codec, nid);
5260 if (err < 0)
5261 return err;
d8d881dd
TI
5262 if (codec->beep) {
5263 /* IDT/STAC codecs have linear beep tone parameter */
1b0e372d 5264 codec->beep->linear_tone = spec->linear_tone_beep;
d8d881dd
TI
5265 /* if no beep switch is available, make its own one */
5266 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
5267 if (!(caps & AC_AMPCAP_MUTE)) {
5268 err = stac92xx_beep_switch_ctl(codec);
5269 if (err < 0)
5270 return err;
5271 }
4d4e9bb3 5272 }
1cd2224c
MR
5273 }
5274#endif
5275
0fb87bb4 5276 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
0fb87bb4
ML
5277 if (err < 0)
5278 return err;
5279
dc04d1b4
TI
5280 /* All output parsing done, now restore the swapped hp pins */
5281 if (hp_swap) {
5282 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
5283 sizeof(spec->autocfg.hp_pins));
5284 spec->autocfg.hp_outs = spec->autocfg.line_outs;
5285 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
5286 spec->autocfg.line_outs = 0;
5287 }
0fb87bb4 5288
3d21d3f7
TI
5289 if (stac_check_auto_mic(codec)) {
5290 spec->auto_mic = 1;
5291 /* only one capture for auto-mic */
5292 spec->num_adcs = 1;
5293 spec->num_caps = 1;
5294 spec->num_muxes = 1;
5295 }
5296
6479c631
TI
5297 for (i = 0; i < spec->num_caps; i++) {
5298 err = stac92xx_add_capvol_ctls(codec, spec->capvols[i],
5299 spec->capsws[i], i);
5300 if (err < 0)
5301 return err;
5302 }
5303
dc04d1b4 5304 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
0fb87bb4 5305 if (err < 0)
c7d4b2fa
M
5306 return err;
5307
b22b4821
MR
5308 if (spec->mono_nid > 0) {
5309 err = stac92xx_auto_create_mono_output_ctls(codec);
5310 if (err < 0)
5311 return err;
5312 }
2a9c7816 5313 if (spec->num_dmics > 0 && !spec->dinput_mux)
8b65727b
MP
5314 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
5315 &spec->autocfg)) < 0)
5316 return err;
4682eee0
MR
5317 if (spec->num_muxes > 0) {
5318 err = stac92xx_auto_create_mux_input_ctls(codec);
5319 if (err < 0)
5320 return err;
5321 }
d9737751
MR
5322 if (spec->num_smuxes > 0) {
5323 err = stac92xx_auto_create_spdif_mux_ctls(codec);
5324 if (err < 0)
5325 return err;
5326 }
8b65727b 5327
e3c75964
TI
5328 err = stac92xx_add_input_source(spec);
5329 if (err < 0)
5330 return err;
5331
c7d4b2fa 5332 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
403d1944 5333 if (spec->multiout.max_channels > 2)
c7d4b2fa 5334 spec->surr_switch = 1;
c7d4b2fa 5335
9009b0e4
CC
5336 /* find digital out and in converters */
5337 for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) {
5338 unsigned int wid_caps = get_wcaps(codec, i);
5339 if (wid_caps & AC_WCAP_DIGITAL) {
5340 switch (get_wcaps_type(wid_caps)) {
5341 case AC_WID_AUD_OUT:
5342 if (!dig_out)
5343 dig_out = i;
5344 break;
5345 case AC_WID_AUD_IN:
5346 if (!dig_in)
5347 dig_in = i;
5348 break;
5349 }
5350 }
5351 }
0852d7a6 5352 if (spec->autocfg.dig_outs)
3cc08dc6 5353 spec->multiout.dig_out_nid = dig_out;
d0513fc6 5354 if (dig_in && spec->autocfg.dig_in_pin)
3cc08dc6 5355 spec->dig_in_nid = dig_in;
c7d4b2fa 5356
603c4019
TI
5357 if (spec->kctls.list)
5358 spec->mixers[spec->num_mixers++] = spec->kctls.list;
c7d4b2fa
M
5359
5360 spec->input_mux = &spec->private_imux;
f8ccbf65
MR
5361 if (!spec->dinput_mux)
5362 spec->dinput_mux = &spec->private_dimux;
d9737751 5363 spec->sinput_mux = &spec->private_smux;
b22b4821 5364 spec->mono_mux = &spec->private_mono_mux;
c7d4b2fa
M
5365 return 1;
5366}
5367
82bc955f
TI
5368/* add playback controls for HP output */
5369static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
5370 struct auto_pin_cfg *cfg)
5371{
5372 struct sigmatel_spec *spec = codec->spec;
eb06ed8f 5373 hda_nid_t pin = cfg->hp_pins[0];
82bc955f
TI
5374
5375 if (! pin)
5376 return 0;
5377
e35d9d6a 5378 if (is_jack_detectable(codec, pin))
82bc955f 5379 spec->hp_detect = 1;
82bc955f
TI
5380
5381 return 0;
5382}
5383
160ea0dc
RF
5384/* add playback controls for LFE output */
5385static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
5386 struct auto_pin_cfg *cfg)
5387{
5388 struct sigmatel_spec *spec = codec->spec;
5389 int err;
5390 hda_nid_t lfe_pin = 0x0;
5391 int i;
5392
5393 /*
5394 * search speaker outs and line outs for a mono speaker pin
5395 * with an amp. If one is found, add LFE controls
5396 * for it.
5397 */
5398 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
5399 hda_nid_t pin = spec->autocfg.speaker_pins[i];
64ed0dfd 5400 unsigned int wcaps = get_wcaps(codec, pin);
160ea0dc
RF
5401 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
5402 if (wcaps == AC_WCAP_OUT_AMP)
5403 /* found a mono speaker with an amp, must be lfe */
5404 lfe_pin = pin;
5405 }
5406
5407 /* if speaker_outs is 0, then speakers may be in line_outs */
5408 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
5409 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
5410 hda_nid_t pin = spec->autocfg.line_out_pins[i];
64ed0dfd 5411 unsigned int defcfg;
330ee995 5412 defcfg = snd_hda_codec_get_pincfg(codec, pin);
8b551785 5413 if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
64ed0dfd 5414 unsigned int wcaps = get_wcaps(codec, pin);
160ea0dc
RF
5415 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
5416 if (wcaps == AC_WCAP_OUT_AMP)
5417 /* found a mono speaker with an amp,
5418 must be lfe */
5419 lfe_pin = pin;
5420 }
5421 }
5422 }
5423
5424 if (lfe_pin) {
7c7767eb 5425 err = create_controls(codec, "LFE", lfe_pin, 1);
160ea0dc
RF
5426 if (err < 0)
5427 return err;
5428 }
5429
5430 return 0;
5431}
5432
c7d4b2fa
M
5433static int stac9200_parse_auto_config(struct hda_codec *codec)
5434{
5435 struct sigmatel_spec *spec = codec->spec;
5436 int err;
5437
df694daa 5438 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
c7d4b2fa
M
5439 return err;
5440
5441 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
5442 return err;
5443
82bc955f
TI
5444 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
5445 return err;
5446
160ea0dc
RF
5447 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
5448 return err;
5449
355a0ec4
TI
5450 if (spec->num_muxes > 0) {
5451 err = stac92xx_auto_create_mux_input_ctls(codec);
5452 if (err < 0)
5453 return err;
5454 }
5455
e3c75964
TI
5456 err = stac92xx_add_input_source(spec);
5457 if (err < 0)
5458 return err;
5459
0852d7a6 5460 if (spec->autocfg.dig_outs)
c7d4b2fa 5461 spec->multiout.dig_out_nid = 0x05;
82bc955f 5462 if (spec->autocfg.dig_in_pin)
c7d4b2fa 5463 spec->dig_in_nid = 0x04;
c7d4b2fa 5464
603c4019
TI
5465 if (spec->kctls.list)
5466 spec->mixers[spec->num_mixers++] = spec->kctls.list;
c7d4b2fa
M
5467
5468 spec->input_mux = &spec->private_imux;
8b65727b 5469 spec->dinput_mux = &spec->private_dimux;
c7d4b2fa
M
5470
5471 return 1;
5472}
5473
62fe78e9
SR
5474/*
5475 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
5476 * funky external mute control using GPIO pins.
5477 */
5478
76e1ddfb 5479static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4fe5195c 5480 unsigned int dir_mask, unsigned int data)
62fe78e9
SR
5481{
5482 unsigned int gpiostate, gpiomask, gpiodir;
5483
45eebda7
VK
5484 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
5485
62fe78e9
SR
5486 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5487 AC_VERB_GET_GPIO_DATA, 0);
4fe5195c 5488 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
62fe78e9
SR
5489
5490 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5491 AC_VERB_GET_GPIO_MASK, 0);
76e1ddfb 5492 gpiomask |= mask;
62fe78e9
SR
5493
5494 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5495 AC_VERB_GET_GPIO_DIRECTION, 0);
4fe5195c 5496 gpiodir |= dir_mask;
62fe78e9 5497
76e1ddfb 5498 /* Configure GPIOx as CMOS */
62fe78e9
SR
5499 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
5500
5501 snd_hda_codec_write(codec, codec->afg, 0,
5502 AC_VERB_SET_GPIO_MASK, gpiomask);
76e1ddfb
TI
5503 snd_hda_codec_read(codec, codec->afg, 0,
5504 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
62fe78e9
SR
5505
5506 msleep(1);
5507
76e1ddfb
TI
5508 snd_hda_codec_read(codec, codec->afg, 0,
5509 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
62fe78e9
SR
5510}
5511
3a93897e 5512static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
c6e4c666 5513 unsigned char type, int data)
74aeaabc 5514{
3a93897e 5515 struct hda_jack_tbl *event;
74aeaabc 5516
3a93897e 5517 event = snd_hda_jack_tbl_new(codec, nid);
74aeaabc
MR
5518 if (!event)
5519 return -ENOMEM;
3a93897e
TI
5520 event->action = type;
5521 event->private_data = data;
c6e4c666 5522
3a93897e 5523 return 0;
c6e4c666
TI
5524}
5525
29adc4b9
DH
5526static void handle_unsol_event(struct hda_codec *codec,
5527 struct hda_jack_tbl *event);
5528
62558ce1
TI
5529/* check if given nid is a valid pin and no other events are assigned
5530 * to it. If OK, assign the event, set the unsol flag, and returns 1.
5531 * Otherwise, returns zero.
5532 */
5533static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
5534 unsigned int type)
c6e4c666 5535{
3a93897e 5536 struct hda_jack_tbl *event;
c6e4c666 5537
e35d9d6a 5538 if (!is_jack_detectable(codec, nid))
62558ce1 5539 return 0;
3a93897e
TI
5540 event = snd_hda_jack_tbl_new(codec, nid);
5541 if (!event)
5542 return -ENOMEM;
5543 if (event->action && event->action != type)
5544 return 0;
5545 event->action = type;
29adc4b9 5546 event->callback = handle_unsol_event;
3a93897e 5547 snd_hda_jack_detect_enable(codec, nid, 0);
62558ce1 5548 return 1;
314634bc
TI
5549}
5550
b4ead019 5551static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
a64135a2
MR
5552{
5553 int i;
5554 for (i = 0; i < cfg->hp_outs; i++)
5555 if (cfg->hp_pins[i] == nid)
5556 return 1; /* nid is a HP-Out */
b4ead019
TI
5557 for (i = 0; i < cfg->line_outs; i++)
5558 if (cfg->line_out_pins[i] == nid)
5559 return 1; /* nid is a line-Out */
a64135a2
MR
5560 return 0; /* nid is not a HP-Out */
5561};
5562
b76c850f
MR
5563static void stac92xx_power_down(struct hda_codec *codec)
5564{
5565 struct sigmatel_spec *spec = codec->spec;
5566
5567 /* power down inactive DACs */
2b63536f 5568 const hda_nid_t *dac;
b76c850f 5569 for (dac = spec->dac_list; *dac; dac++)
c21ca4a8 5570 if (!check_all_dac_nids(spec, *dac))
8c2f767b 5571 snd_hda_codec_write(codec, *dac, 0,
b76c850f
MR
5572 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5573}
5574
f73d3585
TI
5575static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
5576 int enable);
5577
bc759721
TI
5578static inline bool get_int_hint(struct hda_codec *codec, const char *key,
5579 int *valp)
014c41fc 5580{
bc759721 5581 return !snd_hda_get_int_hint(codec, key, valp);
014c41fc
TI
5582}
5583
6565e4fa
TI
5584/* override some hints from the hwdep entry */
5585static void stac_store_hints(struct hda_codec *codec)
5586{
5587 struct sigmatel_spec *spec = codec->spec;
6565e4fa
TI
5588 int val;
5589
5590 val = snd_hda_get_bool_hint(codec, "hp_detect");
5591 if (val >= 0)
5592 spec->hp_detect = val;
014c41fc 5593 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
6565e4fa
TI
5594 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
5595 spec->gpio_mask;
5596 }
014c41fc
TI
5597 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
5598 spec->gpio_mask &= spec->gpio_mask;
5599 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
5600 spec->gpio_dir &= spec->gpio_mask;
5601 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
5602 spec->eapd_mask &= spec->gpio_mask;
5603 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
5604 spec->gpio_mute &= spec->gpio_mask;
6565e4fa
TI
5605 val = snd_hda_get_bool_hint(codec, "eapd_switch");
5606 if (val >= 0)
5607 spec->eapd_switch = val;
5608}
5609
f2cbba76
TI
5610static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
5611 const hda_nid_t *pins)
5612{
5613 while (num_pins--)
5614 stac_issue_unsol_event(codec, *pins++);
5615}
5616
5617/* fake event to set up pins */
5618static void stac_fake_hp_events(struct hda_codec *codec)
5619{
5620 struct sigmatel_spec *spec = codec->spec;
5621
5622 if (spec->autocfg.hp_outs)
5623 stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
5624 spec->autocfg.hp_pins);
5625 if (spec->autocfg.line_outs &&
5626 spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
5627 stac_issue_unsol_events(codec, spec->autocfg.line_outs,
5628 spec->autocfg.line_out_pins);
5629}
5630
c7d4b2fa
M
5631static int stac92xx_init(struct hda_codec *codec)
5632{
5633 struct sigmatel_spec *spec = codec->spec;
82bc955f 5634 struct auto_pin_cfg *cfg = &spec->autocfg;
f73d3585 5635 unsigned int gpio;
e4973e1e 5636 int i;
c7d4b2fa 5637
5e68fb3c
DH
5638 if (spec->init)
5639 snd_hda_sequence_write(codec, spec->init);
c7d4b2fa 5640
d39a3ae8
TI
5641 snd_hda_apply_verbs(codec);
5642
8daaaa97
MR
5643 /* power down adcs initially */
5644 if (spec->powerdown_adcs)
5645 for (i = 0; i < spec->num_adcs; i++)
8c2f767b 5646 snd_hda_codec_write(codec,
8daaaa97
MR
5647 spec->adc_nids[i], 0,
5648 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
f73d3585 5649
6565e4fa
TI
5650 /* override some hints */
5651 stac_store_hints(codec);
5652
f73d3585
TI
5653 /* set up GPIO */
5654 gpio = spec->gpio_data;
5655 /* turn on EAPD statically when spec->eapd_switch isn't set.
5656 * otherwise, unsol event will turn it on/off dynamically
5657 */
5658 if (!spec->eapd_switch)
5659 gpio |= spec->eapd_mask;
5660 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio);
5661
82bc955f
TI
5662 /* set up pins */
5663 if (spec->hp_detect) {
505cb341 5664 /* Enable unsolicited responses on the HP widget */
74aeaabc 5665 for (i = 0; i < cfg->hp_outs; i++) {
74aeaabc 5666 hda_nid_t nid = cfg->hp_pins[i];
c6e4c666 5667 enable_pin_detect(codec, nid, STAC_HP_EVENT);
74aeaabc 5668 }
1c4bdf9b
TI
5669 if (cfg->line_out_type == AUTO_PIN_LINE_OUT &&
5670 cfg->speaker_outs > 0) {
fefd67f3 5671 /* enable pin-detect for line-outs as well */
15cfa2b3
TI
5672 for (i = 0; i < cfg->line_outs; i++) {
5673 hda_nid_t nid = cfg->line_out_pins[i];
fefd67f3
TI
5674 enable_pin_detect(codec, nid, STAC_LO_EVENT);
5675 }
5676 }
5677
0a07acaf
TI
5678 /* force to enable the first line-out; the others are set up
5679 * in unsol_event
5680 */
5681 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
74aeaabc 5682 AC_PINCTL_OUT_EN);
82bc955f 5683 /* fake event to set up pins */
f2cbba76 5684 stac_fake_hp_events(codec);
82bc955f
TI
5685 } else {
5686 stac92xx_auto_init_multi_out(codec);
5687 stac92xx_auto_init_hp_out(codec);
12dde4c6
TI
5688 for (i = 0; i < cfg->hp_outs; i++)
5689 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
82bc955f 5690 }
3d21d3f7 5691 if (spec->auto_mic) {
15b4f296 5692 /* initialize connection to analog input */
da2a2aaa
TI
5693 if (spec->dmux_nids)
5694 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
15b4f296 5695 AC_VERB_SET_CONNECT_SEL, 0);
3d21d3f7
TI
5696 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
5697 stac_issue_unsol_event(codec, spec->ext_mic.pin);
9907790a
CC
5698 if (enable_pin_detect(codec, spec->dock_mic.pin,
5699 STAC_MIC_EVENT))
5700 stac_issue_unsol_event(codec, spec->dock_mic.pin);
3d21d3f7 5701 }
eea7dc93
TI
5702 for (i = 0; i < cfg->num_inputs; i++) {
5703 hda_nid_t nid = cfg->inputs[i].pin;
5704 int type = cfg->inputs[i].type;
5705 unsigned int pinctl, conf;
86e2959a 5706 if (type == AUTO_PIN_MIC) {
eea7dc93 5707 /* for mic pins, force to initialize */
4740860b 5708 pinctl = snd_hda_get_default_vref(codec, nid);
eea7dc93
TI
5709 pinctl |= AC_PINCTL_IN_EN;
5710 stac92xx_auto_set_pinctl(codec, nid, pinctl);
5711 } else {
5712 pinctl = snd_hda_codec_read(codec, nid, 0,
5713 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5714 /* if PINCTL already set then skip */
5715 /* Also, if both INPUT and OUTPUT are set,
5716 * it must be a BIOS bug; need to override, too
5717 */
5718 if (!(pinctl & AC_PINCTL_IN_EN) ||
5719 (pinctl & AC_PINCTL_OUT_EN)) {
5720 pinctl &= ~AC_PINCTL_OUT_EN;
12dde4c6
TI
5721 pinctl |= AC_PINCTL_IN_EN;
5722 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4f1e6bc3 5723 }
c960a03b 5724 }
eea7dc93
TI
5725 conf = snd_hda_codec_get_pincfg(codec, nid);
5726 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
5727 if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT))
5728 stac_issue_unsol_event(codec, nid);
5729 }
82bc955f 5730 }
a64135a2
MR
5731 for (i = 0; i < spec->num_dmics; i++)
5732 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
5733 AC_PINCTL_IN_EN);
0852d7a6
TI
5734 if (cfg->dig_out_pins[0])
5735 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0],
f73d3585
TI
5736 AC_PINCTL_OUT_EN);
5737 if (cfg->dig_in_pin)
5738 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
5739 AC_PINCTL_IN_EN);
a64135a2 5740 for (i = 0; i < spec->num_pwrs; i++) {
f73d3585 5741 hda_nid_t nid = spec->pwr_nids[i];
6e1c39c6 5742 unsigned int pinctl, def_conf;
f73d3585 5743
bfc89dec
TI
5744 def_conf = snd_hda_codec_get_pincfg(codec, nid);
5745 def_conf = get_defcfg_connect(def_conf);
5746 if (def_conf == AC_JACK_PORT_NONE) {
5747 /* power off unused ports */
5748 stac_toggle_power_map(codec, nid, 0);
5749 continue;
5750 }
6e1c39c6
TI
5751 if (def_conf == AC_JACK_PORT_FIXED) {
5752 /* no need for jack detection for fixed pins */
5753 stac_toggle_power_map(codec, nid, 1);
5754 continue;
5755 }
eb632128 5756 /* power on when no jack detection is available */
542c9a0a
TI
5757 /* or when the VREF is used for controlling LED */
5758 if (!spec->hp_detect ||
bfc89dec
TI
5759 spec->vref_mute_led_nid == nid ||
5760 !is_jack_detectable(codec, nid)) {
eb632128
TI
5761 stac_toggle_power_map(codec, nid, 1);
5762 continue;
5763 }
5764
b4ead019 5765 if (is_nid_out_jack_pin(cfg, nid))
f73d3585
TI
5766 continue; /* already has an unsol event */
5767
5768 pinctl = snd_hda_codec_read(codec, nid, 0,
5769 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
a64135a2
MR
5770 /* outputs are only ports capable of power management
5771 * any attempts on powering down a input port cause the
5772 * referenced VREF to act quirky.
5773 */
eb632128
TI
5774 if (pinctl & AC_PINCTL_IN_EN) {
5775 stac_toggle_power_map(codec, nid, 1);
a64135a2 5776 continue;
eb632128 5777 }
afef2cfa 5778 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
62558ce1 5779 stac_issue_unsol_event(codec, nid);
afef2cfa
CC
5780 continue;
5781 }
5782 /* none of the above, turn the port OFF */
5783 stac_toggle_power_map(codec, nid, 0);
a64135a2 5784 }
c21bd025 5785
c21bd025 5786 /* sync mute LED */
1f43f6c1
TI
5787 if (spec->gpio_led) {
5788 if (spec->vmaster_mute.hook)
5789 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5790 else /* the very first init call doesn't have vmaster yet */
5791 stac92xx_update_led_status(codec, false);
5792 }
c882246d
TI
5793
5794 /* sync the power-map */
5795 if (spec->num_pwrs)
5796 snd_hda_codec_write(codec, codec->afg, 0,
5797 AC_VERB_IDT_SET_POWER_MAP,
5798 spec->power_map_bits);
b76c850f
MR
5799 if (spec->dac_list)
5800 stac92xx_power_down(codec);
c7d4b2fa
M
5801 return 0;
5802}
5803
603c4019
TI
5804static void stac92xx_free_kctls(struct hda_codec *codec)
5805{
5806 struct sigmatel_spec *spec = codec->spec;
5807
5808 if (spec->kctls.list) {
5809 struct snd_kcontrol_new *kctl = spec->kctls.list;
5810 int i;
5811 for (i = 0; i < spec->kctls.used; i++)
5812 kfree(kctl[i].name);
5813 }
5814 snd_array_free(&spec->kctls);
5815}
5816
45eebda7
VK
5817static void stac92xx_shutup_pins(struct hda_codec *codec)
5818{
5819 unsigned int i, def_conf;
5820
5821 if (codec->bus->shutdown)
5822 return;
5823 for (i = 0; i < codec->init_pins.used; i++) {
5824 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
5825 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
5826 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
cdd03ced 5827 snd_hda_set_pin_ctl(codec, pin->nid, 0);
45eebda7
VK
5828 }
5829}
5830
167eae5a
TI
5831static void stac92xx_shutup(struct hda_codec *codec)
5832{
5833 struct sigmatel_spec *spec = codec->spec;
167eae5a 5834
45eebda7 5835 stac92xx_shutup_pins(codec);
167eae5a
TI
5836
5837 if (spec->eapd_mask)
5838 stac_gpio_set(codec, spec->gpio_mask,
5839 spec->gpio_dir, spec->gpio_data &
5840 ~spec->eapd_mask);
5841}
5842
2f2f4251
M
5843static void stac92xx_free(struct hda_codec *codec)
5844{
c7d4b2fa 5845 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa
M
5846
5847 if (! spec)
5848 return;
5849
c7d4b2fa 5850 kfree(spec);
1cd2224c 5851 snd_hda_detach_beep_device(codec);
2f2f4251
M
5852}
5853
4e55096e
M
5854static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
5855 unsigned int flag)
5856{
8ce84198
TI
5857 unsigned int old_ctl, pin_ctl;
5858
5859 pin_ctl = snd_hda_codec_read(codec, nid,
4e55096e 5860 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
7b043899 5861
f9acba43
TI
5862 if (pin_ctl & AC_PINCTL_IN_EN) {
5863 /*
5864 * we need to check the current set-up direction of
5865 * shared input pins since they can be switched via
5866 * "xxx as Output" mixer switch
5867 */
5868 struct sigmatel_spec *spec = codec->spec;
c21ca4a8 5869 if (nid == spec->line_switch || nid == spec->mic_switch)
f9acba43
TI
5870 return;
5871 }
5872
8ce84198 5873 old_ctl = pin_ctl;
7b043899
SL
5874 /* if setting pin direction bits, clear the current
5875 direction bits first */
5876 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
5877 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
5878
8ce84198
TI
5879 pin_ctl |= flag;
5880 if (old_ctl != pin_ctl)
cdd03ced 5881 snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl);
4e55096e
M
5882}
5883
5884static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
5885 unsigned int flag)
5886{
5887 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
5888 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
8ce84198 5889 if (pin_ctl & flag)
cdd03ced 5890 snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl & ~flag);
4e55096e
M
5891}
5892
d56757ab 5893static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
314634bc
TI
5894{
5895 if (!nid)
5896 return 0;
a252c81a 5897 return snd_hda_jack_detect(codec, nid);
314634bc
TI
5898}
5899
fefd67f3
TI
5900static void stac92xx_line_out_detect(struct hda_codec *codec,
5901 int presence)
5902{
5903 struct sigmatel_spec *spec = codec->spec;
5904 struct auto_pin_cfg *cfg = &spec->autocfg;
5905 int i;
5906
042b92c1
DH
5907 if (cfg->speaker_outs == 0)
5908 return;
5909
fefd67f3
TI
5910 for (i = 0; i < cfg->line_outs; i++) {
5911 if (presence)
5912 break;
5913 presence = get_pin_presence(codec, cfg->line_out_pins[i]);
5914 if (presence) {
5915 unsigned int pinctl;
5916 pinctl = snd_hda_codec_read(codec,
5917 cfg->line_out_pins[i], 0,
5918 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5919 if (pinctl & AC_PINCTL_IN_EN)
5920 presence = 0; /* mic- or line-input */
5921 }
5922 }
5923
5924 if (presence) {
5925 /* disable speakers */
5926 for (i = 0; i < cfg->speaker_outs; i++)
5927 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
5928 AC_PINCTL_OUT_EN);
5929 if (spec->eapd_mask && spec->eapd_switch)
5930 stac_gpio_set(codec, spec->gpio_mask,
5931 spec->gpio_dir, spec->gpio_data &
5932 ~spec->eapd_mask);
5933 } else {
5934 /* enable speakers */
5935 for (i = 0; i < cfg->speaker_outs; i++)
5936 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
5937 AC_PINCTL_OUT_EN);
5938 if (spec->eapd_mask && spec->eapd_switch)
5939 stac_gpio_set(codec, spec->gpio_mask,
5940 spec->gpio_dir, spec->gpio_data |
5941 spec->eapd_mask);
5942 }
5943}
5944
d7a89436
TI
5945/* return non-zero if the hp-pin of the given array index isn't
5946 * a jack-detection target
5947 */
5948static int no_hp_sensing(struct sigmatel_spec *spec, int i)
5949{
5950 struct auto_pin_cfg *cfg = &spec->autocfg;
5951
5952 /* ignore sensing of shared line and mic jacks */
c21ca4a8 5953 if (cfg->hp_pins[i] == spec->line_switch)
d7a89436 5954 return 1;
c21ca4a8 5955 if (cfg->hp_pins[i] == spec->mic_switch)
d7a89436
TI
5956 return 1;
5957 /* ignore if the pin is set as line-out */
5958 if (cfg->hp_pins[i] == spec->hp_switch)
5959 return 1;
5960 return 0;
5961}
5962
c6e4c666 5963static void stac92xx_hp_detect(struct hda_codec *codec)
4e55096e
M
5964{
5965 struct sigmatel_spec *spec = codec->spec;
5966 struct auto_pin_cfg *cfg = &spec->autocfg;
5967 int i, presence;
5968
eb06ed8f 5969 presence = 0;
4fe5195c
MR
5970 if (spec->gpio_mute)
5971 presence = !(snd_hda_codec_read(codec, codec->afg, 0,
5972 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
5973
eb06ed8f 5974 for (i = 0; i < cfg->hp_outs; i++) {
314634bc
TI
5975 if (presence)
5976 break;
d7a89436
TI
5977 if (no_hp_sensing(spec, i))
5978 continue;
e6e3ea25
TI
5979 presence = get_pin_presence(codec, cfg->hp_pins[i]);
5980 if (presence) {
5981 unsigned int pinctl;
5982 pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
5983 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5984 if (pinctl & AC_PINCTL_IN_EN)
5985 presence = 0; /* mic- or line-input */
5986 }
eb06ed8f 5987 }
4e55096e
M
5988
5989 if (presence) {
d7a89436 5990 /* disable lineouts */
7c2ba97b 5991 if (spec->hp_switch)
d7a89436
TI
5992 stac92xx_reset_pinctl(codec, spec->hp_switch,
5993 AC_PINCTL_OUT_EN);
4e55096e
M
5994 for (i = 0; i < cfg->line_outs; i++)
5995 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
5996 AC_PINCTL_OUT_EN);
4e55096e 5997 } else {
d7a89436 5998 /* enable lineouts */
7c2ba97b 5999 if (spec->hp_switch)
d7a89436
TI
6000 stac92xx_set_pinctl(codec, spec->hp_switch,
6001 AC_PINCTL_OUT_EN);
4e55096e
M
6002 for (i = 0; i < cfg->line_outs; i++)
6003 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
6004 AC_PINCTL_OUT_EN);
4e55096e 6005 }
fefd67f3 6006 stac92xx_line_out_detect(codec, presence);
d7a89436
TI
6007 /* toggle hp outs */
6008 for (i = 0; i < cfg->hp_outs; i++) {
6009 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
6010 if (no_hp_sensing(spec, i))
6011 continue;
7bff172a 6012 if (1 /*presence*/)
d7a89436 6013 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
8317e0b0
TI
6014#if 0 /* FIXME */
6015/* Resetting the pinctl like below may lead to (a sort of) regressions
6016 * on some devices since they use the HP pin actually for line/speaker
6017 * outs although the default pin config shows a different pin (that is
6018 * wrong and useless).
6019 *
6020 * So, it's basically a problem of default pin configs, likely a BIOS issue.
6021 * But, disabling the code below just works around it, and I'm too tired of
6022 * bug reports with such devices...
6023 */
d7a89436
TI
6024 else
6025 stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
8317e0b0 6026#endif /* FIXME */
d7a89436 6027 }
4e55096e
M
6028}
6029
f73d3585
TI
6030static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
6031 int enable)
a64135a2
MR
6032{
6033 struct sigmatel_spec *spec = codec->spec;
f73d3585
TI
6034 unsigned int idx, val;
6035
6036 for (idx = 0; idx < spec->num_pwrs; idx++) {
6037 if (spec->pwr_nids[idx] == nid)
6038 break;
6039 }
6040 if (idx >= spec->num_pwrs)
6041 return;
d0513fc6 6042
afef2cfa 6043 idx = 1 << idx;
a64135a2 6044
c882246d 6045 val = spec->power_map_bits;
f73d3585 6046 if (enable)
a64135a2
MR
6047 val &= ~idx;
6048 else
6049 val |= idx;
6050
6051 /* power down unused output ports */
c882246d
TI
6052 if (val != spec->power_map_bits) {
6053 spec->power_map_bits = val;
6054 snd_hda_codec_write(codec, codec->afg, 0,
6055 AC_VERB_IDT_SET_POWER_MAP, val);
6056 }
74aeaabc
MR
6057}
6058
f73d3585
TI
6059static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
6060{
e6e3ea25 6061 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
f73d3585 6062}
a64135a2 6063
ab5a6ebe
VK
6064/* get the pin connection (fixed, none, etc) */
6065static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
6066{
6067 struct sigmatel_spec *spec = codec->spec;
6068 unsigned int cfg;
6069
6070 cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
6071 return get_defcfg_connect(cfg);
6072}
6073
6074static int stac92xx_connected_ports(struct hda_codec *codec,
2b63536f 6075 const hda_nid_t *nids, int num_nids)
ab5a6ebe
VK
6076{
6077 struct sigmatel_spec *spec = codec->spec;
6078 int idx, num;
6079 unsigned int def_conf;
6080
6081 for (num = 0; num < num_nids; num++) {
6082 for (idx = 0; idx < spec->num_pins; idx++)
6083 if (spec->pin_nids[idx] == nids[num])
6084 break;
6085 if (idx >= spec->num_pins)
6086 break;
6087 def_conf = stac_get_defcfg_connect(codec, idx);
6088 if (def_conf == AC_JACK_PORT_NONE)
6089 break;
6090 }
6091 return num;
6092}
6093
3d21d3f7
TI
6094static void stac92xx_mic_detect(struct hda_codec *codec)
6095{
6096 struct sigmatel_spec *spec = codec->spec;
6097 struct sigmatel_mic_route *mic;
6098
6099 if (get_pin_presence(codec, spec->ext_mic.pin))
6100 mic = &spec->ext_mic;
9907790a
CC
6101 else if (get_pin_presence(codec, spec->dock_mic.pin))
6102 mic = &spec->dock_mic;
3d21d3f7
TI
6103 else
6104 mic = &spec->int_mic;
02d33322 6105 if (mic->dmux_idx >= 0)
3d21d3f7
TI
6106 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
6107 AC_VERB_SET_CONNECT_SEL,
6108 mic->dmux_idx);
02d33322 6109 if (mic->mux_idx >= 0)
3d21d3f7
TI
6110 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
6111 AC_VERB_SET_CONNECT_SEL,
6112 mic->mux_idx);
6113}
6114
1835a0f9 6115static void handle_unsol_event(struct hda_codec *codec,
3a93897e 6116 struct hda_jack_tbl *event)
314634bc 6117{
a64135a2 6118 struct sigmatel_spec *spec = codec->spec;
1835a0f9 6119 int data;
c6e4c666 6120
3a93897e 6121 switch (event->action) {
314634bc 6122 case STAC_HP_EVENT:
fefd67f3 6123 case STAC_LO_EVENT:
16ffe32c 6124 stac92xx_hp_detect(codec);
fefd67f3 6125 break;
3d21d3f7
TI
6126 case STAC_MIC_EVENT:
6127 stac92xx_mic_detect(codec);
6128 break;
6129 }
6130
3a93897e 6131 switch (event->action) {
3d21d3f7 6132 case STAC_HP_EVENT:
fefd67f3 6133 case STAC_LO_EVENT:
3d21d3f7 6134 case STAC_MIC_EVENT:
74aeaabc 6135 case STAC_INSERT_EVENT:
a64135a2 6136 case STAC_PWR_EVENT:
c6e4c666
TI
6137 if (spec->num_pwrs > 0)
6138 stac92xx_pin_sense(codec, event->nid);
fd60cc89
MR
6139
6140 switch (codec->subsystem_id) {
6141 case 0x103c308f:
6142 if (event->nid == 0xb) {
6143 int pin = AC_PINCTL_IN_EN;
6144
6145 if (get_pin_presence(codec, 0xa)
6146 && get_pin_presence(codec, 0xb))
6147 pin |= AC_PINCTL_VREF_80;
6148 if (!get_pin_presence(codec, 0xb))
6149 pin |= AC_PINCTL_VREF_80;
6150
6151 /* toggle VREF state based on mic + hp pin
6152 * status
6153 */
6154 stac92xx_auto_set_pinctl(codec, 0x0a, pin);
6155 }
6156 }
72474be6 6157 break;
c6e4c666
TI
6158 case STAC_VREF_EVENT:
6159 data = snd_hda_codec_read(codec, codec->afg, 0,
6160 AC_VERB_GET_GPIO_DATA, 0);
72474be6
MR
6161 /* toggle VREF state based on GPIOx status */
6162 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
3a93897e 6163 !!(data & (1 << event->private_data)));
72474be6 6164 break;
314634bc
TI
6165 }
6166}
6167
1835a0f9
TI
6168static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
6169{
3a93897e 6170 struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid);
1835a0f9
TI
6171 if (!event)
6172 return;
6173 handle_unsol_event(codec, event);
6174}
6175
d38cce70
KG
6176static void set_hp_led_gpio(struct hda_codec *codec)
6177{
6178 struct sigmatel_spec *spec = codec->spec;
07f80449
TI
6179 unsigned int gpio;
6180
26ebe0a2
TI
6181 if (spec->gpio_led)
6182 return;
6183
07f80449
TI
6184 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
6185 gpio &= AC_GPIO_IO_COUNT;
6186 if (gpio > 3)
6187 spec->gpio_led = 0x08; /* GPIO 3 */
6188 else
6189 spec->gpio_led = 0x01; /* GPIO 0 */
d38cce70
KG
6190}
6191
c357aab0
VK
6192/*
6193 * This method searches for the mute LED GPIO configuration
6194 * provided as OEM string in SMBIOS. The format of that string
6195 * is HP_Mute_LED_P_G or HP_Mute_LED_P
6196 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
6197 * that corresponds to the NOT muted state of the master volume
6198 * and G is the index of the GPIO to use as the mute LED control (0..9)
6199 * If _G portion is missing it is assigned based on the codec ID
6200 *
6201 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
6202 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
d38cce70
KG
6203 *
6204 *
6205 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
6206 * SMBIOS - at least the ones I have seen do not have them - which include
6207 * my own system (HP Pavilion dv6-1110ax) and my cousin's
6208 * HP Pavilion dv9500t CTO.
6209 * Need more information on whether it is true across the entire series.
6210 * -- kunal
c357aab0 6211 */
6a557c94 6212static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
c357aab0
VK
6213{
6214 struct sigmatel_spec *spec = codec->spec;
6215 const struct dmi_device *dev = NULL;
6216
7560931f
TI
6217 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
6218 get_int_hint(codec, "gpio_led_polarity",
6219 &spec->gpio_led_polarity);
6220 return 1;
6221 }
0f6fcb73 6222
89bb3e74
TI
6223 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
6224 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
6225 &spec->gpio_led_polarity,
6226 &spec->gpio_led) == 2) {
6227 unsigned int max_gpio;
6228 max_gpio = snd_hda_param_read(codec, codec->afg,
6229 AC_PAR_GPIO_CAP);
6230 max_gpio &= AC_GPIO_IO_COUNT;
6231 if (spec->gpio_led < max_gpio)
6232 spec->gpio_led = 1 << spec->gpio_led;
6233 else
6234 spec->vref_mute_led_nid = spec->gpio_led;
6235 return 1;
c357aab0 6236 }
89bb3e74
TI
6237 if (sscanf(dev->name, "HP_Mute_LED_%d",
6238 &spec->gpio_led_polarity) == 1) {
d38cce70 6239 set_hp_led_gpio(codec);
d38cce70
KG
6240 return 1;
6241 }
89bb3e74
TI
6242 /* BIOS bug: unfilled OEM string */
6243 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
6244 set_hp_led_gpio(codec);
8c698fe2
TI
6245 if (default_polarity >= 0)
6246 spec->gpio_led_polarity = default_polarity;
6247 else
89bb3e74 6248 spec->gpio_led_polarity = 1;
89bb3e74
TI
6249 return 1;
6250 }
6251 }
6252
6253 /*
6254 * Fallback case - if we don't find the DMI strings,
6255 * we statically set the GPIO - if not a B-series system
6256 * and default polarity is provided
6257 */
6258 if (!hp_blike_system(codec->subsystem_id) &&
6259 (default_polarity == 0 || default_polarity == 1)) {
6260 set_hp_led_gpio(codec);
6261 spec->gpio_led_polarity = default_polarity;
6262 return 1;
c357aab0
VK
6263 }
6264 return 0;
6265}
6266
6267static int hp_blike_system(u32 subsystem_id)
78987bdc
RD
6268{
6269 switch (subsystem_id) {
c357aab0
VK
6270 case 0x103c1520:
6271 case 0x103c1521:
6272 case 0x103c1523:
6273 case 0x103c1524:
6274 case 0x103c1525:
78987bdc
RD
6275 case 0x103c1722:
6276 case 0x103c1723:
6277 case 0x103c1724:
6278 case 0x103c1725:
6279 case 0x103c1726:
6280 case 0x103c1727:
6281 case 0x103c1728:
6282 case 0x103c1729:
c357aab0
VK
6283 case 0x103c172a:
6284 case 0x103c172b:
6285 case 0x103c307e:
6286 case 0x103c307f:
6287 case 0x103c3080:
6288 case 0x103c3081:
6289 case 0x103c7007:
6290 case 0x103c7008:
78987bdc
RD
6291 return 1;
6292 }
6293 return 0;
6294}
6295
2d34e1b3
TI
6296#ifdef CONFIG_PROC_FS
6297static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
6298 struct hda_codec *codec, hda_nid_t nid)
6299{
6300 if (nid == codec->afg)
6301 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
c882246d
TI
6302 snd_hda_codec_read(codec, nid, 0,
6303 AC_VERB_IDT_GET_POWER_MAP, 0));
2d34e1b3
TI
6304}
6305
6306static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
6307 struct hda_codec *codec,
6308 unsigned int verb)
6309{
6310 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
6311 snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
6312}
6313
6314/* stac92hd71bxx, stac92hd73xx */
6315static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
6316 struct hda_codec *codec, hda_nid_t nid)
6317{
6318 stac92hd_proc_hook(buffer, codec, nid);
6319 if (nid == codec->afg)
6320 analog_loop_proc_hook(buffer, codec, 0xfa0);
6321}
6322
6323static void stac9205_proc_hook(struct snd_info_buffer *buffer,
6324 struct hda_codec *codec, hda_nid_t nid)
6325{
6326 if (nid == codec->afg)
6327 analog_loop_proc_hook(buffer, codec, 0xfe0);
6328}
6329
6330static void stac927x_proc_hook(struct snd_info_buffer *buffer,
6331 struct hda_codec *codec, hda_nid_t nid)
6332{
6333 if (nid == codec->afg)
6334 analog_loop_proc_hook(buffer, codec, 0xfeb);
6335}
6336#else
6337#define stac92hd_proc_hook NULL
6338#define stac92hd7x_proc_hook NULL
6339#define stac9205_proc_hook NULL
6340#define stac927x_proc_hook NULL
6341#endif
6342
2a43952a 6343#ifdef CONFIG_PM
ff6fdc37
M
6344static int stac92xx_resume(struct hda_codec *codec)
6345{
2c885878 6346 stac92xx_init(codec);
82beb8fd
TI
6347 snd_hda_codec_resume_amp(codec);
6348 snd_hda_codec_resume_cache(codec);
2c885878 6349 /* fake event to set up pins again to override cached values */
f2cbba76 6350 stac_fake_hp_events(codec);
ff6fdc37
M
6351 return 0;
6352}
c6798d2b 6353
68cb2b55 6354static int stac92xx_suspend(struct hda_codec *codec)
45eebda7
VK
6355{
6356 stac92xx_shutup(codec);
6357 return 0;
6358}
6359
45eebda7
VK
6360static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
6361 unsigned int power_state)
6362{
6363 unsigned int afg_power_state = power_state;
6364 struct sigmatel_spec *spec = codec->spec;
6365
6366 if (power_state == AC_PWRST_D3) {
f1a73746 6367 if (spec->vref_mute_led_nid) {
45eebda7
VK
6368 /* with vref-out pin used for mute led control
6369 * codec AFG is prevented from D3 state
6370 */
6371 afg_power_state = AC_PWRST_D1;
6372 }
6373 /* this delay seems necessary to avoid click noise at power-down */
6374 msleep(100);
6375 }
6376 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
6377 afg_power_state);
6378 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
6379}
350eba43
TI
6380#else
6381#define stac92xx_suspend NULL
6382#define stac92xx_resume NULL
350eba43 6383#define stac92xx_set_power_state NULL
2faa3bf1 6384#endif /* CONFIG_PM */
45eebda7 6385
2faa3bf1
TI
6386/* update mute-LED accoring to the master switch */
6387static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
ae6241fb
CP
6388{
6389 struct sigmatel_spec *spec = codec->spec;
2faa3bf1 6390 int muted = !enabled;
6fce61ae 6391
45eebda7 6392 if (!spec->gpio_led)
2faa3bf1
TI
6393 return;
6394
6395 /* LED state is inverted on these systems */
6396 if (spec->gpio_led_polarity)
6397 muted = !muted;
45eebda7 6398
f1a73746 6399 if (!spec->vref_mute_led_nid) {
45eebda7 6400 if (muted)
3e843196 6401 spec->gpio_data |= spec->gpio_led;
45eebda7 6402 else
3e843196 6403 spec->gpio_data &= ~spec->gpio_led;
45eebda7
VK
6404 stac_gpio_set(codec, spec->gpio_mask,
6405 spec->gpio_dir, spec->gpio_data);
6406 } else {
2faa3bf1 6407 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
f1a73746
TI
6408 stac_vrefout_set(codec, spec->vref_mute_led_nid,
6409 spec->vref_led);
c21bd025 6410 }
b4e81876 6411}
7df1ce1a 6412
2b63536f 6413static const struct hda_codec_ops stac92xx_patch_ops = {
2f2f4251
M
6414 .build_controls = stac92xx_build_controls,
6415 .build_pcms = stac92xx_build_pcms,
6416 .init = stac92xx_init,
6417 .free = stac92xx_free,
29adc4b9 6418 .unsol_event = snd_hda_jack_unsol_event,
2a43952a 6419#ifdef CONFIG_PM
c6798d2b 6420 .suspend = stac92xx_suspend,
ff6fdc37
M
6421 .resume = stac92xx_resume,
6422#endif
fb8d1a34 6423 .reboot_notify = stac92xx_shutup,
2f2f4251
M
6424};
6425
361dab3e
TI
6426static int alloc_stac_spec(struct hda_codec *codec, int num_pins,
6427 const hda_nid_t *pin_nids)
6428{
6429 struct sigmatel_spec *spec;
6430
6431 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6432 if (!spec)
6433 return -ENOMEM;
6434 codec->spec = spec;
6435 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
6436 spec->num_pins = num_pins;
6437 spec->pin_nids = pin_nids;
6438 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
6439 return 0;
6440}
6441
2f2f4251
M
6442static int patch_stac9200(struct hda_codec *codec)
6443{
6444 struct sigmatel_spec *spec;
c7d4b2fa 6445 int err;
2f2f4251 6446
361dab3e
TI
6447 err = alloc_stac_spec(codec, ARRAY_SIZE(stac9200_pin_nids),
6448 stac9200_pin_nids);
6449 if (err < 0)
6450 return err;
2f2f4251 6451
361dab3e 6452 spec = codec->spec;
1b0e372d 6453 spec->linear_tone_beep = 1;
d39a3ae8
TI
6454
6455 snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl,
6456 stac9200_fixups);
2f2f4251
M
6457
6458 spec->multiout.max_channels = 2;
6459 spec->multiout.num_dacs = 1;
6460 spec->multiout.dac_nids = stac9200_dac_nids;
6461 spec->adc_nids = stac9200_adc_nids;
6462 spec->mux_nids = stac9200_mux_nids;
dabbed6f 6463 spec->num_muxes = 1;
8b65727b 6464 spec->num_dmics = 0;
9e05b7a3 6465 spec->num_adcs = 1;
a64135a2 6466 spec->num_pwrs = 0;
d39a3ae8 6467 snd_hda_add_verbs(codec, stac9200_eapd_init);
c7d4b2fa 6468
2f2f4251 6469 spec->mixer = stac9200_mixer;
c7d4b2fa 6470
d39a3ae8 6471 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
117f257d 6472
c7d4b2fa
M
6473 err = stac9200_parse_auto_config(codec);
6474 if (err < 0) {
6475 stac92xx_free(codec);
6476 return err;
6477 }
2f2f4251
M
6478
6479 codec->patch_ops = stac92xx_patch_ops;
6480
d39a3ae8
TI
6481 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6482
2f2f4251
M
6483 return 0;
6484}
6485
8e21c34c
TD
6486static int patch_stac925x(struct hda_codec *codec)
6487{
6488 struct sigmatel_spec *spec;
6489 int err;
6490
361dab3e
TI
6491 err = alloc_stac_spec(codec, ARRAY_SIZE(stac925x_pin_nids),
6492 stac925x_pin_nids);
6493 if (err < 0)
6494 return err;
8e21c34c 6495
361dab3e 6496 spec = codec->spec;
1b0e372d 6497 spec->linear_tone_beep = 1;
9cb36c2a 6498
d2077d40
TI
6499 snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl,
6500 stac925x_fixups);
8e21c34c
TD
6501
6502 spec->multiout.max_channels = 2;
6503 spec->multiout.num_dacs = 1;
6504 spec->multiout.dac_nids = stac925x_dac_nids;
6505 spec->adc_nids = stac925x_adc_nids;
6506 spec->mux_nids = stac925x_mux_nids;
6507 spec->num_muxes = 1;
9e05b7a3 6508 spec->num_adcs = 1;
a64135a2 6509 spec->num_pwrs = 0;
2c11f955
TD
6510 switch (codec->vendor_id) {
6511 case 0x83847632: /* STAC9202 */
6512 case 0x83847633: /* STAC9202D */
6513 case 0x83847636: /* STAC9251 */
6514 case 0x83847637: /* STAC9251D */
f6e9852a 6515 spec->num_dmics = STAC925X_NUM_DMICS;
2c11f955 6516 spec->dmic_nids = stac925x_dmic_nids;
1697055e
TI
6517 spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
6518 spec->dmux_nids = stac925x_dmux_nids;
2c11f955
TD
6519 break;
6520 default:
6521 spec->num_dmics = 0;
6522 break;
6523 }
8e21c34c 6524
d2077d40 6525 snd_hda_add_verbs(codec, stac925x_core_init);
8e21c34c 6526 spec->mixer = stac925x_mixer;
6479c631
TI
6527 spec->num_caps = 1;
6528 spec->capvols = stac925x_capvols;
6529 spec->capsws = stac925x_capsws;
8e21c34c 6530
d2077d40
TI
6531 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6532
9009b0e4 6533 err = stac92xx_parse_auto_config(codec);
d2077d40 6534 if (!err)
9e507abd 6535 err = -EINVAL;
8e21c34c
TD
6536 if (err < 0) {
6537 stac92xx_free(codec);
6538 return err;
6539 }
6540
6541 codec->patch_ops = stac92xx_patch_ops;
6542
d2077d40
TI
6543 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6544
8e21c34c
TD
6545 return 0;
6546}
6547
e1f0d669
MR
6548static int patch_stac92hd73xx(struct hda_codec *codec)
6549{
6550 struct sigmatel_spec *spec;
6551 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
361dab3e 6552 int err;
c21ca4a8 6553 int num_dacs;
e1f0d669 6554
361dab3e
TI
6555 err = alloc_stac_spec(codec, ARRAY_SIZE(stac92hd73xx_pin_nids),
6556 stac92hd73xx_pin_nids);
6557 if (err < 0)
6558 return err;
e1f0d669 6559
361dab3e 6560 spec = codec->spec;
1b0e372d 6561 spec->linear_tone_beep = 0;
e99d32b3 6562 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
55e30141
TI
6563
6564 snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl,
6565 stac92hd73xx_fixups);
e1f0d669 6566
c21ca4a8 6567 num_dacs = snd_hda_get_connections(codec, 0x0a,
e1f0d669
MR
6568 conn, STAC92HD73_DAC_COUNT + 2) - 1;
6569
c21ca4a8 6570 if (num_dacs < 3 || num_dacs > 5) {
e1f0d669
MR
6571 printk(KERN_WARNING "hda_codec: Could not determine "
6572 "number of channels defaulting to DAC count\n");
c21ca4a8 6573 num_dacs = STAC92HD73_DAC_COUNT;
e1f0d669 6574 }
55e30141 6575
c21ca4a8 6576 switch (num_dacs) {
e1f0d669 6577 case 0x3: /* 6 Channel */
d78d7a90 6578 spec->aloopback_ctl = stac92hd73xx_6ch_loopback;
e1f0d669
MR
6579 break;
6580 case 0x4: /* 8 Channel */
d78d7a90 6581 spec->aloopback_ctl = stac92hd73xx_8ch_loopback;
e1f0d669
MR
6582 break;
6583 case 0x5: /* 10 Channel */
d78d7a90
TI
6584 spec->aloopback_ctl = stac92hd73xx_10ch_loopback;
6585 break;
c21ca4a8
TI
6586 }
6587 spec->multiout.dac_nids = spec->dac_nids;
e1f0d669 6588
e1f0d669
MR
6589 spec->aloopback_mask = 0x01;
6590 spec->aloopback_shift = 8;
6591
1cd2224c 6592 spec->digbeep_nid = 0x1c;
e1f0d669
MR
6593 spec->mux_nids = stac92hd73xx_mux_nids;
6594 spec->adc_nids = stac92hd73xx_adc_nids;
6595 spec->dmic_nids = stac92hd73xx_dmic_nids;
6596 spec->dmux_nids = stac92hd73xx_dmux_nids;
d9737751 6597 spec->smux_nids = stac92hd73xx_smux_nids;
e1f0d669
MR
6598
6599 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
6600 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
1697055e 6601 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
2a9c7816 6602
6479c631
TI
6603 spec->num_caps = STAC92HD73XX_NUM_CAPS;
6604 spec->capvols = stac92hd73xx_capvols;
6605 spec->capsws = stac92hd73xx_capsws;
6606
55e30141
TI
6607 /* GPIO0 High = Enable EAPD */
6608 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
6609 spec->gpio_data = 0x01;
6b3ab21e 6610
55e30141
TI
6611 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
6612 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
6613 spec->eapd_switch = 1;
a7662640 6614
a64135a2
MR
6615 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
6616 spec->pwr_nids = stac92hd73xx_pwr_nids;
6617
55e30141
TI
6618 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6619
6620 if (!spec->volknob_init)
6621 snd_hda_add_verbs(codec, stac92hd73xx_core_init);
6622
9009b0e4 6623 err = stac92xx_parse_auto_config(codec);
e1f0d669 6624
55e30141 6625 if (!err)
e1f0d669 6626 err = -EINVAL;
e1f0d669
MR
6627 if (err < 0) {
6628 stac92xx_free(codec);
6629 return err;
6630 }
6631
6632 codec->patch_ops = stac92xx_patch_ops;
6633
2d34e1b3
TI
6634 codec->proc_widget_hook = stac92hd7x_proc_hook;
6635
55e30141
TI
6636 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6637
e1f0d669
MR
6638 return 0;
6639}
6640
cbbf50b2 6641static int hp_bnb2011_with_dock(struct hda_codec *codec)
335e3b86
VK
6642{
6643 if (codec->vendor_id != 0x111d7605 &&
6644 codec->vendor_id != 0x111d76d1)
6645 return 0;
6646
6647 switch (codec->subsystem_id) {
6648 case 0x103c1618:
6649 case 0x103c1619:
6650 case 0x103c161a:
6651 case 0x103c161b:
6652 case 0x103c161c:
6653 case 0x103c161d:
6654 case 0x103c161e:
6655 case 0x103c161f:
335e3b86
VK
6656
6657 case 0x103c162a:
6658 case 0x103c162b:
6659
6660 case 0x103c1630:
6661 case 0x103c1631:
6662
6663 case 0x103c1633:
cbbf50b2 6664 case 0x103c1634:
335e3b86
VK
6665 case 0x103c1635:
6666
335e3b86
VK
6667 case 0x103c3587:
6668 case 0x103c3588:
6669 case 0x103c3589:
6670 case 0x103c358a:
6671
6672 case 0x103c3667:
6673 case 0x103c3668:
cbbf50b2
VK
6674 case 0x103c3669:
6675
6676 return 1;
335e3b86
VK
6677 }
6678 return 0;
6679}
6680
699d8995
VK
6681static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid)
6682{
6683 struct sigmatel_spec *spec = codec->spec;
6684 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
6685 int i;
6686
6687 spec->auto_pin_nids[spec->auto_pin_cnt] = nid;
6688 spec->auto_pin_cnt++;
6689
6690 if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
6691 get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) {
6692 for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) {
6693 if (nid == stac92hd83xxx_dmic_nids[i]) {
6694 spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid;
6695 spec->auto_dmic_cnt++;
6696 }
6697 }
6698 }
6699}
6700
6701static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid)
6702{
6703 struct sigmatel_spec *spec = codec->spec;
6704
6705 spec->auto_adc_nids[spec->auto_adc_cnt] = nid;
6706 spec->auto_adc_cnt++;
6707}
6708
6709static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid)
6710{
6711 int i, j;
6712 struct sigmatel_spec *spec = codec->spec;
6713
6714 for (i = 0; i < spec->auto_adc_cnt; i++) {
6715 if (get_connection_index(codec,
6716 spec->auto_adc_nids[i], nid) >= 0) {
6717 /* mux and volume for adc_nids[i] */
6718 if (!spec->auto_mux_nids[i]) {
6719 spec->auto_mux_nids[i] = nid;
6720 /* 92hd codecs capture volume is in mux */
6721 spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid,
6722 3, 0, HDA_OUTPUT);
6723 }
6724 for (j = 0; j < spec->auto_dmic_cnt; j++) {
6725 if (get_connection_index(codec, nid,
6726 spec->auto_dmic_nids[j]) >= 0) {
6727 /* dmux for adc_nids[i] */
6728 if (!spec->auto_dmux_nids[i])
6729 spec->auto_dmux_nids[i] = nid;
6730 break;
6731 }
6732 }
6733 break;
6734 }
6735 }
6736}
6737
6738static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
6739{
6740 hda_nid_t nid, end_nid;
6741 unsigned int wid_caps, wid_type;
6742 struct sigmatel_spec *spec = codec->spec;
6743
6744 end_nid = codec->start_nid + codec->num_nodes;
6745
6746 for (nid = codec->start_nid; nid < end_nid; nid++) {
6747 wid_caps = get_wcaps(codec, nid);
6748 wid_type = get_wcaps_type(wid_caps);
6749
6750 if (wid_type == AC_WID_PIN)
6751 stac92hd8x_add_pin(codec, nid);
6752
6753 if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL))
6754 stac92hd8x_add_adc(codec, nid);
6755 }
6756
6757 for (nid = codec->start_nid; nid < end_nid; nid++) {
6758 wid_caps = get_wcaps(codec, nid);
6759 wid_type = get_wcaps_type(wid_caps);
6760
6761 if (wid_type == AC_WID_AUD_SEL)
6762 stac92hd8x_add_mux(codec, nid);
6763 }
6764
6765 spec->pin_nids = spec->auto_pin_nids;
6766 spec->num_pins = spec->auto_pin_cnt;
6767 spec->adc_nids = spec->auto_adc_nids;
6768 spec->num_adcs = spec->auto_adc_cnt;
6769 spec->capvols = spec->auto_capvols;
6770 spec->capsws = spec->auto_capvols;
6771 spec->num_caps = spec->auto_adc_cnt;
6772 spec->mux_nids = spec->auto_mux_nids;
6773 spec->num_muxes = spec->auto_adc_cnt;
6774 spec->dmux_nids = spec->auto_dmux_nids;
6775 spec->num_dmuxes = spec->auto_adc_cnt;
6776 spec->dmic_nids = spec->auto_dmic_nids;
6777 spec->num_dmics = spec->auto_dmic_cnt;
6778}
6779
372f8c75
TI
6780static void stac_setup_gpio(struct hda_codec *codec)
6781{
6782 struct sigmatel_spec *spec = codec->spec;
6783
6784 if (spec->gpio_led) {
6785 if (!spec->vref_mute_led_nid) {
6786 spec->gpio_mask |= spec->gpio_led;
6787 spec->gpio_dir |= spec->gpio_led;
6788 spec->gpio_data |= spec->gpio_led;
6789 } else {
6790 codec->patch_ops.set_power_state =
6791 stac92xx_set_power_state;
6792 }
6793 }
6794
6795 if (spec->mic_mute_led_gpio) {
6796 spec->gpio_mask |= spec->mic_mute_led_gpio;
6797 spec->gpio_dir |= spec->mic_mute_led_gpio;
6798 spec->mic_mute_led_on = true;
6799 spec->gpio_data |= spec->mic_mute_led_gpio;
6800 }
6801}
6802
d0513fc6
MR
6803static int patch_stac92hd83xxx(struct hda_codec *codec)
6804{
6805 struct sigmatel_spec *spec;
6806 int err;
6807
361dab3e
TI
6808 err = alloc_stac_spec(codec, 0, NULL); /* pins filled later */
6809 if (err < 0)
6810 return err;
d0513fc6 6811
c36b5b05 6812 codec->epss = 0; /* longer delay needed for D3 */
699d8995
VK
6813 stac92hd8x_fill_auto_spec(codec);
6814
361dab3e 6815 spec = codec->spec;
1db7ccdb 6816 spec->linear_tone_beep = 0;
0ffa9807 6817 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
d0513fc6 6818 spec->digbeep_nid = 0x21;
d0513fc6 6819 spec->pwr_nids = stac92hd83xxx_pwr_nids;
d0513fc6 6820 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
c21ca4a8 6821 spec->multiout.dac_nids = spec->dac_nids;
d0513fc6 6822
372f8c75
TI
6823 snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl,
6824 stac92hd83xxx_fixups);
b4e81876 6825
372f8c75
TI
6826 snd_hda_add_verbs(codec, stac92hd83xxx_core_init);
6827 spec->default_polarity = -1; /* no default cfg */
5556e147 6828
372f8c75 6829 codec->patch_ops = stac92xx_patch_ops;
e108c7b7 6830
372f8c75 6831 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
b4e81876 6832
372f8c75 6833 stac_setup_gpio(codec);
62cbde18 6834
9009b0e4 6835 err = stac92xx_parse_auto_config(codec);
372f8c75 6836 if (!err)
d0513fc6 6837 err = -EINVAL;
d0513fc6
MR
6838 if (err < 0) {
6839 stac92xx_free(codec);
6840 return err;
6841 }
6842
2d34e1b3
TI
6843 codec->proc_widget_hook = stac92hd_proc_hook;
6844
372f8c75
TI
6845 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6846
d0513fc6
MR
6847 return 0;
6848}
6849
6df703ae
HRK
6850static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
6851 hda_nid_t dig0pin)
6852{
6853 struct sigmatel_spec *spec = codec->spec;
6854 int idx;
6855
6856 for (idx = 0; idx < spec->num_pins; idx++)
6857 if (spec->pin_nids[idx] == dig0pin)
6858 break;
6859 if ((idx + 2) >= spec->num_pins)
6860 return 0;
6861
6862 /* dig1pin case */
330ee995 6863 if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE)
6df703ae
HRK
6864 return 2;
6865
6866 /* dig0pin + dig2pin case */
330ee995 6867 if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE)
6df703ae 6868 return 2;
330ee995 6869 if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE)
6df703ae
HRK
6870 return 1;
6871 else
6872 return 0;
6873}
6874
75d1aeb9
TI
6875/* HP dv7 bass switch - GPIO5 */
6876#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
6877static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
6878 struct snd_ctl_elem_value *ucontrol)
6879{
6880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6881 struct sigmatel_spec *spec = codec->spec;
6882 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
6883 return 0;
6884}
6885
6886static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
6887 struct snd_ctl_elem_value *ucontrol)
6888{
6889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6890 struct sigmatel_spec *spec = codec->spec;
6891 unsigned int gpio_data;
6892
6893 gpio_data = (spec->gpio_data & ~0x20) |
6894 (ucontrol->value.integer.value[0] ? 0x20 : 0);
6895 if (gpio_data == spec->gpio_data)
6896 return 0;
6897 spec->gpio_data = gpio_data;
6898 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
6899 return 1;
6900}
6901
2b63536f 6902static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
75d1aeb9
TI
6903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6904 .info = stac_hp_bass_gpio_info,
6905 .get = stac_hp_bass_gpio_get,
6906 .put = stac_hp_bass_gpio_put,
6907};
6908
6909static int stac_add_hp_bass_switch(struct hda_codec *codec)
6910{
6911 struct sigmatel_spec *spec = codec->spec;
6912
6913 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
6914 "Bass Speaker Playback Switch", 0))
6915 return -ENOMEM;
6916
6917 spec->gpio_mask |= 0x20;
6918 spec->gpio_dir |= 0x20;
6919 spec->gpio_data |= 0x20;
6920 return 0;
6921}
6922
e035b841
MR
6923static int patch_stac92hd71bxx(struct hda_codec *codec)
6924{
6925 struct sigmatel_spec *spec;
2b63536f 6926 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
361dab3e 6927 int err;
e035b841 6928
361dab3e
TI
6929 err = alloc_stac_spec(codec, STAC92HD71BXX_NUM_PINS,
6930 stac92hd71bxx_pin_nids_4port);
6931 if (err < 0)
6932 return err;
e035b841 6933
361dab3e 6934 spec = codec->spec;
1b0e372d 6935 spec->linear_tone_beep = 0;
8daaaa97 6936 codec->patch_ops = stac92xx_patch_ops;
616f89e7
HRK
6937 switch (codec->vendor_id) {
6938 case 0x111d76b6:
6939 case 0x111d76b7:
616f89e7
HRK
6940 break;
6941 case 0x111d7603:
6942 case 0x111d7608:
6943 /* On 92HD75Bx 0x27 isn't a pin nid */
6944 spec->num_pins--;
6945 /* fallthrough */
6946 default:
6947 spec->pin_nids = stac92hd71bxx_pin_nids_6port;
6948 }
aafc4412 6949 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
e035b841 6950
0f6fcb73
TI
6951 snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl,
6952 stac92hd71bxx_fixups);
6953
6954 /* GPIO0 = EAPD */
6955 spec->gpio_mask = 0x01;
6956 spec->gpio_dir = 0x01;
6957 spec->gpio_data = 0x01;
41c3b648 6958
6df703ae
HRK
6959 spec->dmic_nids = stac92hd71bxx_dmic_nids;
6960 spec->dmux_nids = stac92hd71bxx_dmux_nids;
6961
6479c631
TI
6962 spec->num_caps = STAC92HD71BXX_NUM_CAPS;
6963 spec->capvols = stac92hd71bxx_capvols;
6964 spec->capsws = stac92hd71bxx_capsws;
6965
541eee87
MR
6966 switch (codec->vendor_id) {
6967 case 0x111d76b6: /* 4 Port without Analog Mixer */
6968 case 0x111d76b7:
23c7b521
HRK
6969 unmute_init++;
6970 /* fallthru */
541eee87
MR
6971 case 0x111d76b4: /* 6 Port without Analog Mixer */
6972 case 0x111d76b5:
0ffa9807 6973 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
ab5a6ebe 6974 spec->num_dmics = stac92xx_connected_ports(codec,
6df703ae
HRK
6975 stac92hd71bxx_dmic_nids,
6976 STAC92HD71BXX_NUM_DMICS);
541eee87 6977 break;
aafc4412 6978 case 0x111d7608: /* 5 Port with Analog Mixer */
8daaaa97 6979 if ((codec->revision_id & 0xf) == 0 ||
8c2f767b 6980 (codec->revision_id & 0xf) == 1)
8daaaa97 6981 spec->stream_delay = 40; /* 40 milliseconds */
8daaaa97 6982
aafc4412 6983 /* disable VSW */
ca8d33fc 6984 unmute_init++;
330ee995
TI
6985 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
6986 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
2b63536f 6987 spec->dmic_nids = stac92hd71bxx_dmic_5port_nids;
ab5a6ebe 6988 spec->num_dmics = stac92xx_connected_ports(codec,
2b63536f 6989 stac92hd71bxx_dmic_5port_nids,
6df703ae 6990 STAC92HD71BXX_NUM_DMICS - 1);
aafc4412
MR
6991 break;
6992 case 0x111d7603: /* 6 Port with Analog Mixer */
8c2f767b 6993 if ((codec->revision_id & 0xf) == 1)
8daaaa97 6994 spec->stream_delay = 40; /* 40 milliseconds */
8daaaa97 6995
aafc4412 6996 /* fallthru */
541eee87 6997 default:
0ffa9807 6998 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
ab5a6ebe 6999 spec->num_dmics = stac92xx_connected_ports(codec,
6df703ae
HRK
7000 stac92hd71bxx_dmic_nids,
7001 STAC92HD71BXX_NUM_DMICS);
5207e10e 7002 break;
541eee87
MR
7003 }
7004
5e68fb3c 7005 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
0f6fcb73 7006 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
5e68fb3c 7007
ca8d33fc
MR
7008 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
7009 snd_hda_sequence_write_cache(codec, unmute_init);
7010
d78d7a90 7011 spec->aloopback_ctl = stac92hd71bxx_loopback;
4b33c767 7012 spec->aloopback_mask = 0x50;
541eee87
MR
7013 spec->aloopback_shift = 0;
7014
8daaaa97 7015 spec->powerdown_adcs = 1;
1cd2224c 7016 spec->digbeep_nid = 0x26;
e035b841
MR
7017 spec->mux_nids = stac92hd71bxx_mux_nids;
7018 spec->adc_nids = stac92hd71bxx_adc_nids;
d9737751 7019 spec->smux_nids = stac92hd71bxx_smux_nids;
aafc4412 7020 spec->pwr_nids = stac92hd71bxx_pwr_nids;
e035b841
MR
7021
7022 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
7023 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
5207e10e 7024 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
6df703ae 7025 spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
e035b841 7026
0f6fcb73 7027 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5bdaaada 7028
372f8c75 7029 stac_setup_gpio(codec);
6a14f585 7030
c21ca4a8 7031 spec->multiout.dac_nids = spec->dac_nids;
e035b841 7032
9009b0e4 7033 err = stac92xx_parse_auto_config(codec);
0f6fcb73 7034 if (!err)
e035b841 7035 err = -EINVAL;
e035b841
MR
7036 if (err < 0) {
7037 stac92xx_free(codec);
7038 return err;
7039 }
7040
2d34e1b3
TI
7041 codec->proc_widget_hook = stac92hd7x_proc_hook;
7042
0f6fcb73
TI
7043 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7044
e035b841 7045 return 0;
86d190e7 7046}
e035b841 7047
2f2f4251
M
7048static int patch_stac922x(struct hda_codec *codec)
7049{
7050 struct sigmatel_spec *spec;
c7d4b2fa 7051 int err;
2f2f4251 7052
361dab3e
TI
7053 err = alloc_stac_spec(codec, ARRAY_SIZE(stac922x_pin_nids),
7054 stac922x_pin_nids);
7055 if (err < 0)
7056 return err;
2f2f4251 7057
361dab3e 7058 spec = codec->spec;
1b0e372d 7059 spec->linear_tone_beep = 1;
5d5d3bc3 7060
0a427846
TI
7061 snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl,
7062 stac922x_fixups);
2f2f4251 7063
c7d4b2fa
M
7064 spec->adc_nids = stac922x_adc_nids;
7065 spec->mux_nids = stac922x_mux_nids;
2549413e 7066 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
9e05b7a3 7067 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
8b65727b 7068 spec->num_dmics = 0;
a64135a2 7069 spec->num_pwrs = 0;
c7d4b2fa 7070
6479c631
TI
7071 spec->num_caps = STAC922X_NUM_CAPS;
7072 spec->capvols = stac922x_capvols;
7073 spec->capsws = stac922x_capsws;
c7d4b2fa
M
7074
7075 spec->multiout.dac_nids = spec->dac_nids;
19039bd0 7076
0a427846
TI
7077 snd_hda_add_verbs(codec, stac922x_core_init);
7078
7079 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7080
9009b0e4 7081 err = stac92xx_parse_auto_config(codec);
0a427846 7082 if (!err)
9e507abd 7083 err = -EINVAL;
3cc08dc6
MP
7084 if (err < 0) {
7085 stac92xx_free(codec);
7086 return err;
7087 }
7088
7089 codec->patch_ops = stac92xx_patch_ops;
7090
807a4636
TI
7091 /* Fix Mux capture level; max to 2 */
7092 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
7093 (0 << AC_AMPCAP_OFFSET_SHIFT) |
7094 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
7095 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
7096 (0 << AC_AMPCAP_MUTE_SHIFT));
7097
0a427846
TI
7098 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7099
3cc08dc6
MP
7100 return 0;
7101}
7102
7103static int patch_stac927x(struct hda_codec *codec)
7104{
7105 struct sigmatel_spec *spec;
7106 int err;
7107
361dab3e
TI
7108 err = alloc_stac_spec(codec, ARRAY_SIZE(stac927x_pin_nids),
7109 stac927x_pin_nids);
7110 if (err < 0)
7111 return err;
3cc08dc6 7112
361dab3e 7113 spec = codec->spec;
1b0e372d 7114 spec->linear_tone_beep = 1;
45c1d85b 7115 codec->slave_dig_outs = stac927x_slave_dig_outs;
29ac8363
TI
7116
7117 snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl,
7118 stac927x_fixups);
3cc08dc6 7119
1cd2224c 7120 spec->digbeep_nid = 0x23;
8e9068b1
MR
7121 spec->adc_nids = stac927x_adc_nids;
7122 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
7123 spec->mux_nids = stac927x_mux_nids;
7124 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
d9737751
MR
7125 spec->smux_nids = stac927x_smux_nids;
7126 spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
65973632 7127 spec->spdif_labels = stac927x_spdif_labels;
b76c850f 7128 spec->dac_list = stac927x_dac_nids;
8e9068b1
MR
7129 spec->multiout.dac_nids = spec->dac_nids;
7130
29ac8363
TI
7131 /* GPIO0 High = Enable EAPD */
7132 spec->eapd_mask = spec->gpio_mask = 0x01;
7133 spec->gpio_dir = spec->gpio_data = 0x01;
af6ee302 7134
29ac8363 7135 spec->num_dmics = 0;
7f16859a 7136
6479c631
TI
7137 spec->num_caps = STAC927X_NUM_CAPS;
7138 spec->capvols = stac927x_capvols;
7139 spec->capsws = stac927x_capsws;
7140
a64135a2 7141 spec->num_pwrs = 0;
d78d7a90 7142 spec->aloopback_ctl = stac927x_loopback;
e1f0d669
MR
7143 spec->aloopback_mask = 0x40;
7144 spec->aloopback_shift = 0;
c0cea0d0 7145 spec->eapd_switch = 1;
8e9068b1 7146
29ac8363
TI
7147 if (!spec->volknob_init)
7148 snd_hda_add_verbs(codec, stac927x_core_init);
7149
7150 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7151
9009b0e4 7152 err = stac92xx_parse_auto_config(codec);
29ac8363 7153 if (!err)
9e507abd 7154 err = -EINVAL;
c7d4b2fa
M
7155 if (err < 0) {
7156 stac92xx_free(codec);
7157 return err;
7158 }
2f2f4251
M
7159
7160 codec->patch_ops = stac92xx_patch_ops;
7161
2d34e1b3
TI
7162 codec->proc_widget_hook = stac927x_proc_hook;
7163
52987656
TI
7164 /*
7165 * !!FIXME!!
7166 * The STAC927x seem to require fairly long delays for certain
7167 * command sequences. With too short delays (even if the answer
7168 * is set to RIRB properly), it results in the silence output
7169 * on some hardwares like Dell.
7170 *
7171 * The below flag enables the longer delay (see get_response
7172 * in hda_intel.c).
7173 */
7174 codec->bus->needs_damn_long_delay = 1;
7175
29ac8363 7176 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
e28d8322 7177
2f2f4251
M
7178 return 0;
7179}
7180
f3302a59
MP
7181static int patch_stac9205(struct hda_codec *codec)
7182{
7183 struct sigmatel_spec *spec;
8259980e 7184 int err;
f3302a59 7185
361dab3e
TI
7186 err = alloc_stac_spec(codec, ARRAY_SIZE(stac9205_pin_nids),
7187 stac9205_pin_nids);
7188 if (err < 0)
7189 return err;
f3302a59 7190
361dab3e 7191 spec = codec->spec;
1b0e372d 7192 spec->linear_tone_beep = 1;
fe6322ca
TI
7193
7194 snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl,
7195 stac9205_fixups);
f3302a59 7196
1cd2224c 7197 spec->digbeep_nid = 0x23;
f3302a59 7198 spec->adc_nids = stac9205_adc_nids;
9e05b7a3 7199 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
f3302a59 7200 spec->mux_nids = stac9205_mux_nids;
2549413e 7201 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
d9737751
MR
7202 spec->smux_nids = stac9205_smux_nids;
7203 spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
8b65727b 7204 spec->dmic_nids = stac9205_dmic_nids;
f6e9852a 7205 spec->num_dmics = STAC9205_NUM_DMICS;
e1f0d669 7206 spec->dmux_nids = stac9205_dmux_nids;
1697055e 7207 spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
a64135a2 7208 spec->num_pwrs = 0;
f3302a59 7209
fe6322ca 7210 snd_hda_add_verbs(codec, stac9205_core_init);
d78d7a90 7211 spec->aloopback_ctl = stac9205_loopback;
f3302a59 7212
6479c631
TI
7213 spec->num_caps = STAC9205_NUM_CAPS;
7214 spec->capvols = stac9205_capvols;
7215 spec->capsws = stac9205_capsws;
7216
e1f0d669
MR
7217 spec->aloopback_mask = 0x40;
7218 spec->aloopback_shift = 0;
f3302a59 7219 spec->multiout.dac_nids = spec->dac_nids;
87d48363 7220
fe6322ca
TI
7221 /* GPIO0 High = EAPD */
7222 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
7223 spec->gpio_data = 0x01;
87d48363 7224
fe6322ca
TI
7225 /* Turn on/off EAPD per HP plugging */
7226 spec->eapd_switch = 1;
4fe5195c 7227
fe6322ca 7228 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
33382403 7229
9009b0e4 7230 err = stac92xx_parse_auto_config(codec);
fe6322ca 7231 if (!err)
9e507abd 7232 err = -EINVAL;
f3302a59
MP
7233 if (err < 0) {
7234 stac92xx_free(codec);
7235 return err;
7236 }
7237
7238 codec->patch_ops = stac92xx_patch_ops;
7239
2d34e1b3
TI
7240 codec->proc_widget_hook = stac9205_proc_hook;
7241
fe6322ca
TI
7242 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7243
f3302a59
MP
7244 return 0;
7245}
7246
db064e50 7247/*
6d859065 7248 * STAC9872 hack
db064e50
TI
7249 */
7250
2b63536f 7251static const struct hda_verb stac9872_core_init[] = {
1624cb9a 7252 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
6d859065
GM
7253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
7254 {}
7255};
7256
2b63536f 7257static const hda_nid_t stac9872_pin_nids[] = {
caa10b6e
TI
7258 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
7259 0x11, 0x13, 0x14,
7260};
7261
2b63536f 7262static const hda_nid_t stac9872_adc_nids[] = {
caa10b6e
TI
7263 0x8 /*,0x6*/
7264};
7265
2b63536f 7266static const hda_nid_t stac9872_mux_nids[] = {
caa10b6e
TI
7267 0x15
7268};
7269
2b63536f 7270static const unsigned long stac9872_capvols[] = {
6479c631
TI
7271 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7272};
7273#define stac9872_capsws stac9872_capvols
7274
fc268c10
TI
7275static const struct hda_pintbl stac9872_vaio_pin_configs[] = {
7276 { 0x0a, 0x03211020 },
7277 { 0x0b, 0x411111f0 },
7278 { 0x0c, 0x411111f0 },
7279 { 0x0d, 0x03a15030 },
7280 { 0x0e, 0x411111f0 },
7281 { 0x0f, 0x90170110 },
7282 { 0x11, 0x411111f0 },
7283 { 0x13, 0x411111f0 },
7284 { 0x14, 0x90a7013e },
7285 {}
307282c8
TI
7286};
7287
fc268c10
TI
7288static const struct hda_model_fixup stac9872_models[] = {
7289 { .id = STAC_9872_VAIO, .name = "vaio" },
7290 {}
307282c8
TI
7291};
7292
fc268c10
TI
7293static const struct hda_fixup stac9872_fixups[] = {
7294 [STAC_9872_VAIO] = {
7295 .type = HDA_FIXUP_PINS,
7296 .v.pins = stac9872_vaio_pin_configs,
7297 },
307282c8
TI
7298};
7299
fc268c10 7300static const struct snd_pci_quirk stac9872_fixup_tbl[] = {
b04add95
TI
7301 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
7302 "Sony VAIO F/S", STAC_9872_VAIO),
307282c8
TI
7303 {} /* terminator */
7304};
7305
6d859065 7306static int patch_stac9872(struct hda_codec *codec)
db064e50
TI
7307{
7308 struct sigmatel_spec *spec;
1e137f92 7309 int err;
db064e50 7310
361dab3e
TI
7311 err = alloc_stac_spec(codec, ARRAY_SIZE(stac9872_pin_nids),
7312 stac9872_pin_nids);
7313 if (err < 0)
7314 return err;
7315
7316 spec = codec->spec;
1b0e372d 7317 spec->linear_tone_beep = 1;
caa10b6e 7318
fc268c10
TI
7319 snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl,
7320 stac9872_fixups);
db064e50 7321
1e137f92
TI
7322 spec->multiout.dac_nids = spec->dac_nids;
7323 spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids);
7324 spec->adc_nids = stac9872_adc_nids;
7325 spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
7326 spec->mux_nids = stac9872_mux_nids;
6479c631
TI
7327 spec->num_caps = 1;
7328 spec->capvols = stac9872_capvols;
7329 spec->capsws = stac9872_capsws;
fc268c10
TI
7330 snd_hda_add_verbs(codec, stac9872_core_init);
7331
7332 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1e137f92 7333
9009b0e4 7334 err = stac92xx_parse_auto_config(codec);
1e137f92
TI
7335 if (err < 0) {
7336 stac92xx_free(codec);
7337 return -EINVAL;
7338 }
7339 spec->input_mux = &spec->private_imux;
7340 codec->patch_ops = stac92xx_patch_ops;
fc268c10
TI
7341
7342 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7343
db064e50
TI
7344 return 0;
7345}
7346
7347
2f2f4251
M
7348/*
7349 * patch entries
7350 */
2b63536f 7351static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
2f2f4251
M
7352 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
7353 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
7354 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
7355 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
7356 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
7357 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
7358 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
22a27c7f
MP
7359 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
7360 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
7361 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
7362 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
7363 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
7364 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3cc08dc6
MP
7365 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
7366 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
7367 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
7368 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
7369 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
7370 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
7371 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
7372 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
7373 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
7374 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
8e21c34c
TD
7375 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
7376 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
7377 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
7378 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
7379 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
7380 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
7bd3c0f7
TI
7381 { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
7382 { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
6d859065
GM
7383 /* The following does not take into account .id=0x83847661 when subsys =
7384 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
7385 * currently not fully supported.
7386 */
7387 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
7388 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
7389 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
a5c0f886 7390 { .id = 0x83847698, .name = "STAC9205", .patch = patch_stac9205 },
f3302a59
MP
7391 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
7392 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
7393 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
7394 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
7395 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
7396 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
7397 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
7398 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
aafc4412 7399 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
d0513fc6 7400 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
a9694faa 7401 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
d0513fc6 7402 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
ff2e7337 7403 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
8a345a04
CC
7404 { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx},
7405 { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx},
36706005
CC
7406 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
7407 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
7408 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
7409 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
aafc4412 7410 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
541eee87
MR
7411 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
7412 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
e1f0d669 7413 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
541eee87
MR
7414 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
7415 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
7416 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
7417 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
7418 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
7419 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
7420 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
7421 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
4d8ec5f3
CC
7422 { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx },
7423 { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx },
7424 { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx },
7425 { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx },
7426 { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx },
7427 { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx },
7428 { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx },
7429 { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx },
7430 { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx },
7431 { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx },
7432 { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx },
7433 { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx },
7434 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
7435 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
7436 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
46724c2e 7437 { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx},
ab5a6ebe 7438 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
4dfb8a45
VK
7439 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
7440 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
ab5a6ebe 7441 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
ad5d8755
CC
7442 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
7443 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
7444 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
7445 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
7446 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
7447 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
7448 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
7449 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
7450 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
7451 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
7452 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
7453 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
2f2f4251
M
7454 {} /* terminator */
7455};
1289e9e8
TI
7456
7457MODULE_ALIAS("snd-hda-codec-id:8384*");
7458MODULE_ALIAS("snd-hda-codec-id:111d*");
7459
7460MODULE_LICENSE("GPL");
7461MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
7462
7463static struct hda_codec_preset_list sigmatel_list = {
7464 .preset = snd_hda_preset_sigmatel,
7465 .owner = THIS_MODULE,
7466};
7467
7468static int __init patch_sigmatel_init(void)
7469{
7470 return snd_hda_add_codec_preset(&sigmatel_list);
7471}
7472
7473static void __exit patch_sigmatel_exit(void)
7474{
7475 snd_hda_delete_codec_preset(&sigmatel_list);
7476}
7477
7478module_init(patch_sigmatel_init)
7479module_exit(patch_sigmatel_exit)
This page took 1.257685 seconds and 5 git commands to generate.