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