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