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