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