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