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