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