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