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