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