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