]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/hda/patch_sigmatel.c
ALSA: ELD proc interface for HDMI sinks
[net-next-2.6.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>
31#include <sound/core.h>
c7d4b2fa 32#include <sound/asoundef.h>
45a6ac16 33#include <sound/jack.h>
2f2f4251
M
34#include "hda_codec.h"
35#include "hda_local.h"
3c9a3203 36#include "hda_patch.h"
1cd2224c 37#include "hda_beep.h"
2f2f4251 38
c39555d6 39#define STAC_VREF_EVENT 0x00
74aeaabc 40#define STAC_INSERT_EVENT 0x10
a64135a2
MR
41#define STAC_PWR_EVENT 0x20
42#define STAC_HP_EVENT 0x30
4e55096e 43
f5fcc13c
TI
44enum {
45 STAC_REF,
bf277785 46 STAC_9200_OQO,
dfe495d0
TI
47 STAC_9200_DELL_D21,
48 STAC_9200_DELL_D22,
49 STAC_9200_DELL_D23,
50 STAC_9200_DELL_M21,
51 STAC_9200_DELL_M22,
52 STAC_9200_DELL_M23,
53 STAC_9200_DELL_M24,
54 STAC_9200_DELL_M25,
55 STAC_9200_DELL_M26,
56 STAC_9200_DELL_M27,
1194b5b7 57 STAC_9200_GATEWAY,
117f257d 58 STAC_9200_PANASONIC,
f5fcc13c
TI
59 STAC_9200_MODELS
60};
61
62enum {
63 STAC_9205_REF,
dfe495d0 64 STAC_9205_DELL_M42,
ae0a8ed8
TD
65 STAC_9205_DELL_M43,
66 STAC_9205_DELL_M44,
f5fcc13c
TI
67 STAC_9205_MODELS
68};
69
e1f0d669
MR
70enum {
71 STAC_92HD73XX_REF,
a7662640 72 STAC_DELL_M6,
6b3ab21e 73 STAC_DELL_EQ,
e1f0d669
MR
74 STAC_92HD73XX_MODELS
75};
76
d0513fc6
MR
77enum {
78 STAC_92HD83XXX_REF,
79 STAC_92HD83XXX_MODELS
80};
81
e035b841
MR
82enum {
83 STAC_92HD71BXX_REF,
a7662640
MR
84 STAC_DELL_M4_1,
85 STAC_DELL_M4_2,
6a14f585 86 STAC_HP_M4,
e035b841
MR
87 STAC_92HD71BXX_MODELS
88};
89
8e21c34c
TD
90enum {
91 STAC_925x_REF,
92 STAC_M2_2,
93 STAC_MA6,
2c11f955 94 STAC_PA6,
8e21c34c
TD
95 STAC_925x_MODELS
96};
97
f5fcc13c
TI
98enum {
99 STAC_D945_REF,
100 STAC_D945GTP3,
101 STAC_D945GTP5,
5d5d3bc3
IZ
102 STAC_INTEL_MAC_V1,
103 STAC_INTEL_MAC_V2,
104 STAC_INTEL_MAC_V3,
105 STAC_INTEL_MAC_V4,
106 STAC_INTEL_MAC_V5,
536319af
NB
107 STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter
108 * is given, one of the above models will be
109 * chosen according to the subsystem id. */
dfe495d0 110 /* for backward compatibility */
f5fcc13c 111 STAC_MACMINI,
3fc24d85 112 STAC_MACBOOK,
6f0778d8
NB
113 STAC_MACBOOK_PRO_V1,
114 STAC_MACBOOK_PRO_V2,
f16928fb 115 STAC_IMAC_INTEL,
0dae0f83 116 STAC_IMAC_INTEL_20,
8c650087 117 STAC_ECS_202,
dfe495d0
TI
118 STAC_922X_DELL_D81,
119 STAC_922X_DELL_D82,
120 STAC_922X_DELL_M81,
121 STAC_922X_DELL_M82,
f5fcc13c
TI
122 STAC_922X_MODELS
123};
124
125enum {
126 STAC_D965_REF,
127 STAC_D965_3ST,
128 STAC_D965_5ST,
4ff076e5 129 STAC_DELL_3ST,
8e9068b1 130 STAC_DELL_BIOS,
f5fcc13c
TI
131 STAC_927X_MODELS
132};
403d1944 133
74aeaabc
MR
134struct sigmatel_event {
135 hda_nid_t nid;
136 int data;
137};
138
139struct sigmatel_jack {
140 hda_nid_t nid;
141 int type;
142 struct snd_jack *jack;
143};
144
2f2f4251 145struct sigmatel_spec {
c8b6bf9b 146 struct snd_kcontrol_new *mixers[4];
c7d4b2fa
M
147 unsigned int num_mixers;
148
403d1944 149 int board_config;
c0cea0d0 150 unsigned int eapd_switch: 1;
c7d4b2fa 151 unsigned int surr_switch: 1;
403d1944
MP
152 unsigned int line_switch: 1;
153 unsigned int mic_switch: 1;
3cc08dc6 154 unsigned int alt_switch: 1;
82bc955f 155 unsigned int hp_detect: 1;
00ef50c2 156 unsigned int spdif_mute: 1;
c7d4b2fa 157
4fe5195c 158 /* gpio lines */
0fc9dec4 159 unsigned int eapd_mask;
4fe5195c
MR
160 unsigned int gpio_mask;
161 unsigned int gpio_dir;
162 unsigned int gpio_data;
163 unsigned int gpio_mute;
164
8daaaa97
MR
165 /* stream */
166 unsigned int stream_delay;
167
4fe5195c 168 /* analog loopback */
e1f0d669
MR
169 unsigned char aloopback_mask;
170 unsigned char aloopback_shift;
8259980e 171
a64135a2
MR
172 /* power management */
173 unsigned int num_pwrs;
d0513fc6 174 unsigned int *pwr_mapping;
a64135a2 175 hda_nid_t *pwr_nids;
b76c850f 176 hda_nid_t *dac_list;
a64135a2 177
74aeaabc
MR
178 /* jack detection */
179 struct snd_array jacks;
180
181 /* events */
182 struct snd_array events;
183
2f2f4251 184 /* playback */
b22b4821 185 struct hda_input_mux *mono_mux;
89385035 186 struct hda_input_mux *amp_mux;
b22b4821 187 unsigned int cur_mmux;
2f2f4251 188 struct hda_multi_out multiout;
3cc08dc6 189 hda_nid_t dac_nids[5];
2f2f4251
M
190
191 /* capture */
192 hda_nid_t *adc_nids;
2f2f4251 193 unsigned int num_adcs;
dabbed6f
M
194 hda_nid_t *mux_nids;
195 unsigned int num_muxes;
8b65727b
MP
196 hda_nid_t *dmic_nids;
197 unsigned int num_dmics;
e1f0d669 198 hda_nid_t *dmux_nids;
1697055e 199 unsigned int num_dmuxes;
d9737751
MR
200 hda_nid_t *smux_nids;
201 unsigned int num_smuxes;
65973632 202 const char **spdif_labels;
d9737751 203
dabbed6f 204 hda_nid_t dig_in_nid;
b22b4821 205 hda_nid_t mono_nid;
1cd2224c
MR
206 hda_nid_t anabeep_nid;
207 hda_nid_t digbeep_nid;
2f2f4251 208
2f2f4251
M
209 /* pin widgets */
210 hda_nid_t *pin_nids;
211 unsigned int num_pins;
2f2f4251 212 unsigned int *pin_configs;
11b44bbd 213 unsigned int *bios_pin_configs;
2f2f4251
M
214
215 /* codec specific stuff */
216 struct hda_verb *init;
c8b6bf9b 217 struct snd_kcontrol_new *mixer;
2f2f4251
M
218
219 /* capture source */
8b65727b 220 struct hda_input_mux *dinput_mux;
e1f0d669 221 unsigned int cur_dmux[2];
c7d4b2fa 222 struct hda_input_mux *input_mux;
3cc08dc6 223 unsigned int cur_mux[3];
d9737751
MR
224 struct hda_input_mux *sinput_mux;
225 unsigned int cur_smux[2];
2a9c7816
MR
226 unsigned int cur_amux;
227 hda_nid_t *amp_nids;
228 unsigned int num_amps;
8daaaa97 229 unsigned int powerdown_adcs;
2f2f4251 230
403d1944
MP
231 /* i/o switches */
232 unsigned int io_switch[2];
0fb87bb4 233 unsigned int clfe_swap;
d7a89436 234 unsigned int hp_switch; /* NID of HP as line-out */
5f10c4a9 235 unsigned int aloopback;
2f2f4251 236
c7d4b2fa
M
237 struct hda_pcm pcm_rec[2]; /* PCM information */
238
239 /* dynamic controls and input_mux */
240 struct auto_pin_cfg autocfg;
603c4019 241 struct snd_array kctls;
8b65727b 242 struct hda_input_mux private_dimux;
c7d4b2fa 243 struct hda_input_mux private_imux;
d9737751 244 struct hda_input_mux private_smux;
89385035 245 struct hda_input_mux private_amp_mux;
b22b4821 246 struct hda_input_mux private_mono_mux;
2f2f4251
M
247};
248
249static hda_nid_t stac9200_adc_nids[1] = {
250 0x03,
251};
252
253static hda_nid_t stac9200_mux_nids[1] = {
254 0x0c,
255};
256
257static hda_nid_t stac9200_dac_nids[1] = {
258 0x02,
259};
260
a64135a2
MR
261static hda_nid_t stac92hd73xx_pwr_nids[8] = {
262 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
263 0x0f, 0x10, 0x11
264};
265
0ffa9807
MR
266static hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
267 0x26, 0,
268};
269
e1f0d669
MR
270static hda_nid_t stac92hd73xx_adc_nids[2] = {
271 0x1a, 0x1b
272};
273
2a9c7816
MR
274#define DELL_M6_AMP 2
275static hda_nid_t stac92hd73xx_amp_nids[3] = {
276 0x0b, 0x0c, 0x0e
89385035
MR
277};
278
e1f0d669
MR
279#define STAC92HD73XX_NUM_DMICS 2
280static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
281 0x13, 0x14, 0
282};
283
284#define STAC92HD73_DAC_COUNT 5
285static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
286 0x15, 0x16, 0x17, 0x18, 0x19,
287};
288
289static hda_nid_t stac92hd73xx_mux_nids[4] = {
290 0x28, 0x29, 0x2a, 0x2b,
291};
292
293static hda_nid_t stac92hd73xx_dmux_nids[2] = {
294 0x20, 0x21,
295};
296
d9737751
MR
297static hda_nid_t stac92hd73xx_smux_nids[2] = {
298 0x22, 0x23,
299};
300
d0513fc6
MR
301#define STAC92HD83XXX_NUM_DMICS 2
302static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
303 0x11, 0x12, 0
304};
305
306#define STAC92HD81_DAC_COUNT 2
307#define STAC92HD83_DAC_COUNT 3
308static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
309 0x13, 0x14, 0x22,
310};
311
312static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
313 0x17, 0x18,
314};
315
316static hda_nid_t stac92hd83xxx_adc_nids[2] = {
317 0x15, 0x16,
318};
319
320static hda_nid_t stac92hd83xxx_pwr_nids[4] = {
321 0xa, 0xb, 0xd, 0xe,
322};
323
0ffa9807
MR
324static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
325 0x1e, 0,
326};
327
d0513fc6
MR
328static unsigned int stac92hd83xxx_pwr_mapping[4] = {
329 0x03, 0x0c, 0x10, 0x40,
330};
331
a64135a2
MR
332static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
333 0x0a, 0x0d, 0x0f
334};
335
e035b841
MR
336static hda_nid_t stac92hd71bxx_adc_nids[2] = {
337 0x12, 0x13,
338};
339
340static hda_nid_t stac92hd71bxx_mux_nids[2] = {
341 0x1a, 0x1b
342};
343
4b33c767
MR
344static hda_nid_t stac92hd71bxx_dmux_nids[2] = {
345 0x1c, 0x1d,
e1f0d669
MR
346};
347
d9737751
MR
348static hda_nid_t stac92hd71bxx_smux_nids[2] = {
349 0x24, 0x25,
350};
351
aea7bb0a 352static hda_nid_t stac92hd71bxx_dac_nids[1] = {
e035b841
MR
353 0x10, /*0x11, */
354};
355
356#define STAC92HD71BXX_NUM_DMICS 2
357static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
358 0x18, 0x19, 0
359};
360
0ffa9807
MR
361static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
362 0x22, 0
363};
364
8e21c34c
TD
365static hda_nid_t stac925x_adc_nids[1] = {
366 0x03,
367};
368
369static hda_nid_t stac925x_mux_nids[1] = {
370 0x0f,
371};
372
373static hda_nid_t stac925x_dac_nids[1] = {
374 0x02,
375};
376
f6e9852a
TI
377#define STAC925X_NUM_DMICS 1
378static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
379 0x15, 0
2c11f955
TD
380};
381
1697055e
TI
382static hda_nid_t stac925x_dmux_nids[1] = {
383 0x14,
384};
385
2f2f4251
M
386static hda_nid_t stac922x_adc_nids[2] = {
387 0x06, 0x07,
388};
389
390static hda_nid_t stac922x_mux_nids[2] = {
391 0x12, 0x13,
392};
393
3cc08dc6
MP
394static hda_nid_t stac927x_adc_nids[3] = {
395 0x07, 0x08, 0x09
396};
397
398static hda_nid_t stac927x_mux_nids[3] = {
399 0x15, 0x16, 0x17
400};
401
d9737751
MR
402static hda_nid_t stac927x_smux_nids[1] = {
403 0x21,
404};
405
b76c850f
MR
406static hda_nid_t stac927x_dac_nids[6] = {
407 0x02, 0x03, 0x04, 0x05, 0x06, 0
408};
409
e1f0d669
MR
410static hda_nid_t stac927x_dmux_nids[1] = {
411 0x1b,
412};
413
7f16859a
MR
414#define STAC927X_NUM_DMICS 2
415static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
416 0x13, 0x14, 0
417};
418
65973632
MR
419static const char *stac927x_spdif_labels[5] = {
420 "Digital Playback", "ADAT", "Analog Mux 1",
421 "Analog Mux 2", "Analog Mux 3"
422};
423
f3302a59
MP
424static hda_nid_t stac9205_adc_nids[2] = {
425 0x12, 0x13
426};
427
428static hda_nid_t stac9205_mux_nids[2] = {
429 0x19, 0x1a
430};
431
e1f0d669 432static hda_nid_t stac9205_dmux_nids[1] = {
1697055e 433 0x1d,
e1f0d669
MR
434};
435
d9737751
MR
436static hda_nid_t stac9205_smux_nids[1] = {
437 0x21,
438};
439
f6e9852a
TI
440#define STAC9205_NUM_DMICS 2
441static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
442 0x17, 0x18, 0
8b65727b
MP
443};
444
c7d4b2fa 445static hda_nid_t stac9200_pin_nids[8] = {
93ed1503
TD
446 0x08, 0x09, 0x0d, 0x0e,
447 0x0f, 0x10, 0x11, 0x12,
2f2f4251
M
448};
449
8e21c34c
TD
450static hda_nid_t stac925x_pin_nids[8] = {
451 0x07, 0x08, 0x0a, 0x0b,
452 0x0c, 0x0d, 0x10, 0x11,
453};
454
2f2f4251
M
455static hda_nid_t stac922x_pin_nids[10] = {
456 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
457 0x0f, 0x10, 0x11, 0x15, 0x1b,
458};
459
a7662640 460static hda_nid_t stac92hd73xx_pin_nids[13] = {
e1f0d669
MR
461 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
462 0x0f, 0x10, 0x11, 0x12, 0x13,
d9737751 463 0x14, 0x22, 0x23
e1f0d669
MR
464};
465
d0513fc6
MR
466static hda_nid_t stac92hd83xxx_pin_nids[14] = {
467 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
468 0x0f, 0x10, 0x11, 0x12, 0x13,
469 0x1d, 0x1e, 0x1f, 0x20
470};
0ffa9807 471static hda_nid_t stac92hd71bxx_pin_nids[11] = {
e035b841
MR
472 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
473 0x0f, 0x14, 0x18, 0x19, 0x1e,
0ffa9807 474 0x1f,
e035b841
MR
475};
476
3cc08dc6
MP
477static hda_nid_t stac927x_pin_nids[14] = {
478 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
479 0x0f, 0x10, 0x11, 0x12, 0x13,
480 0x14, 0x21, 0x22, 0x23,
481};
482
f3302a59
MP
483static hda_nid_t stac9205_pin_nids[12] = {
484 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
485 0x0f, 0x14, 0x16, 0x17, 0x18,
486 0x21, 0x22,
f3302a59
MP
487};
488
89385035
MR
489#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info
490
491static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
493{
494 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
495 struct sigmatel_spec *spec = codec->spec;
496 hda_nid_t nid = spec->amp_nids[spec->cur_amux];
497
498 kcontrol->private_value ^= get_amp_nid(kcontrol);
499 kcontrol->private_value |= nid;
500
501 return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
502}
503
504static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_value *ucontrol)
506{
507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct sigmatel_spec *spec = codec->spec;
509 hda_nid_t nid = spec->amp_nids[spec->cur_amux];
510
511 kcontrol->private_value ^= get_amp_nid(kcontrol);
512 kcontrol->private_value |= nid;
513
514 return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
515}
516
8b65727b
MP
517static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
518 struct snd_ctl_elem_info *uinfo)
519{
520 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
521 struct sigmatel_spec *spec = codec->spec;
522 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
523}
524
525static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
527{
528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
529 struct sigmatel_spec *spec = codec->spec;
e1f0d669 530 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8b65727b 531
e1f0d669 532 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
8b65727b
MP
533 return 0;
534}
535
536static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
537 struct snd_ctl_elem_value *ucontrol)
538{
539 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
540 struct sigmatel_spec *spec = codec->spec;
e1f0d669 541 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8b65727b
MP
542
543 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
e1f0d669 544 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
8b65727b
MP
545}
546
d9737751
MR
547static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_info *uinfo)
549{
550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
551 struct sigmatel_spec *spec = codec->spec;
552 return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
553}
554
555static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
556 struct snd_ctl_elem_value *ucontrol)
557{
558 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
559 struct sigmatel_spec *spec = codec->spec;
560 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
561
562 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
563 return 0;
564}
565
566static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
567 struct snd_ctl_elem_value *ucontrol)
568{
569 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
570 struct sigmatel_spec *spec = codec->spec;
00ef50c2 571 struct hda_input_mux *smux = &spec->private_smux;
d9737751 572 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
00ef50c2
MR
573 int err, val;
574 hda_nid_t nid;
d9737751 575
00ef50c2 576 err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
d9737751 577 spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
00ef50c2
MR
578 if (err < 0)
579 return err;
580
581 if (spec->spdif_mute) {
582 if (smux_idx == 0)
583 nid = spec->multiout.dig_out_nid;
584 else
585 nid = codec->slave_dig_outs[smux_idx - 1];
586 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
587 val = AMP_OUT_MUTE;
00ef50c2 588 else
c1e99bd9 589 val = AMP_OUT_UNMUTE;
00ef50c2
MR
590 /* un/mute SPDIF out */
591 snd_hda_codec_write_cache(codec, nid, 0,
592 AC_VERB_SET_AMP_GAIN_MUTE, val);
593 }
594 return 0;
d9737751
MR
595}
596
c8b6bf9b 597static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2f2f4251
M
598{
599 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
600 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa 601 return snd_hda_input_mux_info(spec->input_mux, uinfo);
2f2f4251
M
602}
603
c8b6bf9b 604static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2f2f4251
M
605{
606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
607 struct sigmatel_spec *spec = codec->spec;
608 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
609
610 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
611 return 0;
612}
613
c8b6bf9b 614static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2f2f4251
M
615{
616 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
617 struct sigmatel_spec *spec = codec->spec;
618 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
619
c7d4b2fa 620 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
2f2f4251
M
621 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
622}
623
b22b4821
MR
624static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_info *uinfo)
626{
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 struct sigmatel_spec *spec = codec->spec;
629 return snd_hda_input_mux_info(spec->mono_mux, uinfo);
630}
631
632static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol)
634{
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct sigmatel_spec *spec = codec->spec;
637
638 ucontrol->value.enumerated.item[0] = spec->cur_mmux;
639 return 0;
640}
641
642static int stac92xx_mono_mux_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;
647
648 return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
649 spec->mono_nid, &spec->cur_mmux);
650}
651
89385035
MR
652static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol,
653 struct snd_ctl_elem_info *uinfo)
654{
655 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
656 struct sigmatel_spec *spec = codec->spec;
657 return snd_hda_input_mux_info(spec->amp_mux, uinfo);
658}
659
660static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol,
661 struct snd_ctl_elem_value *ucontrol)
662{
663 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
664 struct sigmatel_spec *spec = codec->spec;
665
666 ucontrol->value.enumerated.item[0] = spec->cur_amux;
667 return 0;
668}
669
670static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol,
671 struct snd_ctl_elem_value *ucontrol)
672{
673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
674 struct sigmatel_spec *spec = codec->spec;
675 struct snd_kcontrol *ctl =
676 snd_hda_find_mixer_ctl(codec, "Amp Capture Volume");
677 if (!ctl)
678 return -EINVAL;
679
680 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE |
681 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
682
683 return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol,
684 0, &spec->cur_amux);
685}
686
5f10c4a9
ML
687#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
688
689static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
690 struct snd_ctl_elem_value *ucontrol)
691{
692 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
e1f0d669 693 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5f10c4a9
ML
694 struct sigmatel_spec *spec = codec->spec;
695
e1f0d669
MR
696 ucontrol->value.integer.value[0] = !!(spec->aloopback &
697 (spec->aloopback_mask << idx));
5f10c4a9
ML
698 return 0;
699}
700
701static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol)
703{
704 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
705 struct sigmatel_spec *spec = codec->spec;
e1f0d669 706 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5f10c4a9 707 unsigned int dac_mode;
e1f0d669 708 unsigned int val, idx_val;
5f10c4a9 709
e1f0d669
MR
710 idx_val = spec->aloopback_mask << idx;
711 if (ucontrol->value.integer.value[0])
712 val = spec->aloopback | idx_val;
713 else
714 val = spec->aloopback & ~idx_val;
68ea7b2f 715 if (spec->aloopback == val)
5f10c4a9
ML
716 return 0;
717
68ea7b2f 718 spec->aloopback = val;
5f10c4a9 719
e1f0d669
MR
720 /* Only return the bits defined by the shift value of the
721 * first two bytes of the mask
722 */
5f10c4a9 723 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
e1f0d669
MR
724 kcontrol->private_value & 0xFFFF, 0x0);
725 dac_mode >>= spec->aloopback_shift;
5f10c4a9 726
e1f0d669 727 if (spec->aloopback & idx_val) {
5f10c4a9 728 snd_hda_power_up(codec);
e1f0d669 729 dac_mode |= idx_val;
5f10c4a9
ML
730 } else {
731 snd_hda_power_down(codec);
e1f0d669 732 dac_mode &= ~idx_val;
5f10c4a9
ML
733 }
734
735 snd_hda_codec_write_cache(codec, codec->afg, 0,
736 kcontrol->private_value >> 16, dac_mode);
737
738 return 1;
739}
740
c7d4b2fa 741static struct hda_verb stac9200_core_init[] = {
2f2f4251 742 /* set dac0mux for dac converter */
c7d4b2fa 743 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2f2f4251
M
744 {}
745};
746
1194b5b7
TI
747static struct hda_verb stac9200_eapd_init[] = {
748 /* set dac0mux for dac converter */
749 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
750 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
751 {}
752};
753
e1f0d669
MR
754static struct hda_verb stac92hd73xx_6ch_core_init[] = {
755 /* set master volume and direct control */
756 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
757 /* setup audio connections */
758 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
759 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
760 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
761 /* setup adcs to point to mixer */
762 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
763 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
e1f0d669
MR
764 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
765 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
766 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
767 /* setup import muxs */
768 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
769 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
770 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
771 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
772 {}
773};
774
d654a660
MR
775static struct hda_verb dell_eq_core_init[] = {
776 /* set master volume to max value without distortion
777 * and direct control */
778 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
779 /* setup audio connections */
780 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
f7cf0a7c
MR
781 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
782 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
d654a660
MR
783 /* setup adcs to point to mixer */
784 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
785 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
786 /* setup import muxs */
787 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
788 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
789 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
790 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
791 {}
792};
793
52fe0f9d 794static struct hda_verb dell_m6_core_init[] = {
6b3ab21e 795 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
52fe0f9d 796 /* setup audio connections */
7747ecce
MR
797 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
798 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
52fe0f9d
MR
799 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
800 /* setup adcs to point to mixer */
801 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
802 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
803 /* setup import muxs */
804 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
805 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
806 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
807 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
808 {}
809};
810
e1f0d669
MR
811static struct hda_verb stac92hd73xx_8ch_core_init[] = {
812 /* set master volume and direct control */
813 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
814 /* setup audio connections */
815 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
816 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
817 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
818 /* connect hp ports to dac3 */
819 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
820 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
821 /* setup adcs to point to mixer */
822 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
823 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
e1f0d669
MR
824 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
825 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
826 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
827 /* setup import muxs */
828 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
829 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
830 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
831 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
832 {}
833};
834
835static struct hda_verb stac92hd73xx_10ch_core_init[] = {
836 /* set master volume and direct control */
837 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
838 /* setup audio connections */
839 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
840 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
841 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
842 /* dac3 is connected to import3 mux */
843 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
844 /* connect hp ports to dac4 */
845 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
846 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
847 /* setup adcs to point to mixer */
848 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
849 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
e1f0d669
MR
850 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
851 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
852 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
853 /* setup import muxs */
854 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
855 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
856 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
857 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
858 {}
859};
860
d0513fc6
MR
861static struct hda_verb stac92hd83xxx_core_init[] = {
862 /* start of config #1 */
863 { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
864
865 /* start of config #2 */
866 { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
867 { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
868 { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
869
870 /* power state controls amps */
871 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
872};
873
e035b841 874static struct hda_verb stac92hd71bxx_core_init[] = {
541eee87
MR
875 /* set master volume and direct control */
876 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
877 /* connect headphone jack to dac1 */
878 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
541eee87
MR
879 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
880 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
881 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
882 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
541eee87
MR
883};
884
4b33c767 885#define HD_DISABLE_PORTF 2
541eee87 886static struct hda_verb stac92hd71bxx_analog_core_init[] = {
aafc4412
MR
887 /* start of config #1 */
888
889 /* connect port 0f to audio mixer */
890 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
aafc4412
MR
891 /* unmute right and left channels for node 0x0f */
892 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
893 /* start of config #2 */
894
e035b841
MR
895 /* set master volume and direct control */
896 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
897 /* connect headphone jack to dac1 */
898 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
aafc4412 899 /* unmute right and left channels for nodes 0x0a, 0xd */
e035b841
MR
900 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
901 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e035b841
MR
902 {}
903};
904
8e21c34c
TD
905static struct hda_verb stac925x_core_init[] = {
906 /* set dac0mux for dac converter */
907 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
908 {}
909};
910
c7d4b2fa 911static struct hda_verb stac922x_core_init[] = {
2f2f4251 912 /* set master volume and direct control */
c7d4b2fa 913 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
2f2f4251
M
914 {}
915};
916
93ed1503 917static struct hda_verb d965_core_init[] = {
19039bd0 918 /* set master volume and direct control */
93ed1503 919 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
19039bd0
TI
920 /* unmute node 0x1b */
921 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
922 /* select node 0x03 as DAC */
923 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
924 {}
925};
926
3cc08dc6
MP
927static struct hda_verb stac927x_core_init[] = {
928 /* set master volume and direct control */
929 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
1cd2224c
MR
930 /* enable analog pc beep path */
931 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
3cc08dc6
MP
932 {}
933};
934
f3302a59
MP
935static struct hda_verb stac9205_core_init[] = {
936 /* set master volume and direct control */
937 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
d0513fc6
MR
938 /* enable analog pc beep path */
939 { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
f3302a59
MP
940 {}
941};
942
b22b4821
MR
943#define STAC_MONO_MUX \
944 { \
945 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
946 .name = "Mono Mux", \
947 .count = 1, \
948 .info = stac92xx_mono_mux_enum_info, \
949 .get = stac92xx_mono_mux_enum_get, \
950 .put = stac92xx_mono_mux_enum_put, \
951 }
952
89385035
MR
953#define STAC_AMP_MUX \
954 { \
955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
956 .name = "Amp Selector Capture Switch", \
957 .count = 1, \
958 .info = stac92xx_amp_mux_enum_info, \
959 .get = stac92xx_amp_mux_enum_get, \
960 .put = stac92xx_amp_mux_enum_put, \
961 }
962
963#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \
964 { \
965 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
966 .name = xname, \
967 .index = 0, \
968 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
969 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
970 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
971 .info = stac92xx_amp_volume_info, \
972 .get = stac92xx_amp_volume_get, \
973 .put = stac92xx_amp_volume_put, \
974 .tlv = { .c = snd_hda_mixer_amp_tlv }, \
975 .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \
976 }
977
9e05b7a3 978#define STAC_INPUT_SOURCE(cnt) \
ca7c5a8b
ML
979 { \
980 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
981 .name = "Input Source", \
9e05b7a3 982 .count = cnt, \
ca7c5a8b
ML
983 .info = stac92xx_mux_enum_info, \
984 .get = stac92xx_mux_enum_get, \
985 .put = stac92xx_mux_enum_put, \
986 }
987
e1f0d669 988#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
5f10c4a9
ML
989 { \
990 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
991 .name = "Analog Loopback", \
e1f0d669 992 .count = cnt, \
5f10c4a9
ML
993 .info = stac92xx_aloopback_info, \
994 .get = stac92xx_aloopback_get, \
995 .put = stac92xx_aloopback_put, \
996 .private_value = verb_read | (verb_write << 16), \
997 }
998
c8b6bf9b 999static struct snd_kcontrol_new stac9200_mixer[] = {
2f2f4251
M
1000 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
1001 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
9e05b7a3 1002 STAC_INPUT_SOURCE(1),
2f2f4251
M
1003 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1004 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
2f2f4251
M
1005 { } /* end */
1006};
1007
2a9c7816 1008#define DELL_M6_MIXER 6
e1f0d669 1009static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
2a9c7816 1010 /* start of config #1 */
e1f0d669
MR
1011 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1012 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1013
e1f0d669
MR
1014 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
1015 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
1016
2a9c7816
MR
1017 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1018 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1019
1020 /* start of config #2 */
1021 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1022 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1023
e1f0d669
MR
1024 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1025 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1026
2a9c7816
MR
1027 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
1028
1029 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1030 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1031
1032 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1033 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1034
e1f0d669
MR
1035 { } /* end */
1036};
1037
1038static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
e1f0d669
MR
1039 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
1040
e1f0d669
MR
1041 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1042 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1043
1044 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1045 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1046
1047 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1048 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1049
1050 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1051 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1052
1053 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
1054 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
1055
1056 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1057 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1058
1059 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1060 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1061 { } /* end */
1062};
1063
1064static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
e1f0d669
MR
1065 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
1066
e1f0d669
MR
1067 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1068 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1069
1070 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1071 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1072
1073 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1074 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1075
1076 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1077 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1078
1079 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
1080 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
1081
1082 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1083 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1084
1085 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1086 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1087 { } /* end */
1088};
1089
d0513fc6
MR
1090
1091static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1092 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT),
1093 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT),
1094
1095 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1096 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1097
1098 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT),
1099 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT),
1100
1101 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT),
1102 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT),
1103
1104 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT),
1105 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT),
1106
1107 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT),
1108 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT),
1109
1110 /*
1111 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT),
1112 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT),
1113 */
1114 { } /* end */
1115};
1116
541eee87 1117static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
e035b841 1118 STAC_INPUT_SOURCE(2),
4b33c767 1119 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
e035b841 1120
9b35947f
MR
1121 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1122 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
9b35947f
MR
1123
1124 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1125 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1cd2224c
MR
1126 /* analog pc-beep replaced with digital beep support */
1127 /*
f7c5dda2
MR
1128 HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT),
1129 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
1cd2224c 1130 */
f7c5dda2 1131
687cb98e
MR
1132 HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT),
1133 HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT),
4b33c767 1134
687cb98e
MR
1135 HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT),
1136 HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT),
4b33c767
MR
1137
1138 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT),
1139 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT),
1140
1141 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT),
1142 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT),
e035b841
MR
1143 { } /* end */
1144};
1145
541eee87 1146static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
541eee87
MR
1147 STAC_INPUT_SOURCE(2),
1148 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
1149
541eee87
MR
1150 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1151 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
541eee87
MR
1152
1153 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1154 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
541eee87
MR
1155 { } /* end */
1156};
1157
8e21c34c 1158static struct snd_kcontrol_new stac925x_mixer[] = {
9e05b7a3 1159 STAC_INPUT_SOURCE(1),
8e21c34c 1160 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
587755f1 1161 HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT),
8e21c34c
TD
1162 { } /* end */
1163};
1164
9e05b7a3 1165static struct snd_kcontrol_new stac9205_mixer[] = {
9e05b7a3 1166 STAC_INPUT_SOURCE(2),
e1f0d669 1167 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
9e05b7a3
ML
1168
1169 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
1170 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
9e05b7a3
ML
1171
1172 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
1173 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
2f2f4251
M
1174 { } /* end */
1175};
1176
19039bd0 1177/* This needs to be generated dynamically based on sequence */
9e05b7a3
ML
1178static struct snd_kcontrol_new stac922x_mixer[] = {
1179 STAC_INPUT_SOURCE(2),
9e05b7a3
ML
1180 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
1181 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
9e05b7a3
ML
1182
1183 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
1184 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
19039bd0
TI
1185 { } /* end */
1186};
1187
9e05b7a3 1188
d1d985f0 1189static struct snd_kcontrol_new stac927x_mixer[] = {
9e05b7a3 1190 STAC_INPUT_SOURCE(3),
e1f0d669 1191 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
3cc08dc6 1192
9e05b7a3
ML
1193 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
1194 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
9e05b7a3
ML
1195
1196 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
1197 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
9e05b7a3
ML
1198
1199 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
1200 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
f3302a59
MP
1201 { } /* end */
1202};
1203
1697055e
TI
1204static struct snd_kcontrol_new stac_dmux_mixer = {
1205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1206 .name = "Digital Input Source",
1207 /* count set later */
1208 .info = stac92xx_dmux_enum_info,
1209 .get = stac92xx_dmux_enum_get,
1210 .put = stac92xx_dmux_enum_put,
1211};
1212
d9737751
MR
1213static struct snd_kcontrol_new stac_smux_mixer = {
1214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
e3487970 1215 .name = "IEC958 Playback Source",
d9737751
MR
1216 /* count set later */
1217 .info = stac92xx_smux_enum_info,
1218 .get = stac92xx_smux_enum_get,
1219 .put = stac92xx_smux_enum_put,
1220};
1221
2134ea4f
TI
1222static const char *slave_vols[] = {
1223 "Front Playback Volume",
1224 "Surround Playback Volume",
1225 "Center Playback Volume",
1226 "LFE Playback Volume",
1227 "Side Playback Volume",
1228 "Headphone Playback Volume",
1229 "Headphone Playback Volume",
1230 "Speaker Playback Volume",
1231 "External Speaker Playback Volume",
1232 "Speaker2 Playback Volume",
1233 NULL
1234};
1235
1236static const char *slave_sws[] = {
1237 "Front Playback Switch",
1238 "Surround Playback Switch",
1239 "Center Playback Switch",
1240 "LFE Playback Switch",
1241 "Side Playback Switch",
1242 "Headphone Playback Switch",
1243 "Headphone Playback Switch",
1244 "Speaker Playback Switch",
1245 "External Speaker Playback Switch",
1246 "Speaker2 Playback Switch",
edb54a55 1247 "IEC958 Playback Switch",
2134ea4f
TI
1248 NULL
1249};
1250
603c4019
TI
1251static void stac92xx_free_kctls(struct hda_codec *codec);
1252
2f2f4251
M
1253static int stac92xx_build_controls(struct hda_codec *codec)
1254{
1255 struct sigmatel_spec *spec = codec->spec;
1256 int err;
c7d4b2fa 1257 int i;
2f2f4251
M
1258
1259 err = snd_hda_add_new_ctls(codec, spec->mixer);
1260 if (err < 0)
1261 return err;
c7d4b2fa
M
1262
1263 for (i = 0; i < spec->num_mixers; i++) {
1264 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1265 if (err < 0)
1266 return err;
1267 }
1697055e
TI
1268 if (spec->num_dmuxes > 0) {
1269 stac_dmux_mixer.count = spec->num_dmuxes;
d13bd412 1270 err = snd_hda_ctl_add(codec,
1697055e
TI
1271 snd_ctl_new1(&stac_dmux_mixer, codec));
1272 if (err < 0)
1273 return err;
1274 }
d9737751 1275 if (spec->num_smuxes > 0) {
00ef50c2
MR
1276 int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
1277 struct hda_input_mux *smux = &spec->private_smux;
1278 /* check for mute support on SPDIF out */
1279 if (wcaps & AC_WCAP_OUT_AMP) {
1280 smux->items[smux->num_items].label = "Off";
1281 smux->items[smux->num_items].index = 0;
1282 smux->num_items++;
1283 spec->spdif_mute = 1;
1284 }
d9737751
MR
1285 stac_smux_mixer.count = spec->num_smuxes;
1286 err = snd_ctl_add(codec->bus->card,
1287 snd_ctl_new1(&stac_smux_mixer, codec));
1288 if (err < 0)
1289 return err;
1290 }
c7d4b2fa 1291
dabbed6f
M
1292 if (spec->multiout.dig_out_nid) {
1293 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
1294 if (err < 0)
1295 return err;
9a08160b
TI
1296 err = snd_hda_create_spdif_share_sw(codec,
1297 &spec->multiout);
1298 if (err < 0)
1299 return err;
1300 spec->multiout.share_spdif = 1;
dabbed6f 1301 }
da74ae3e 1302 if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
dabbed6f
M
1303 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1304 if (err < 0)
1305 return err;
1306 }
2134ea4f
TI
1307
1308 /* if we have no master control, let's create it */
1309 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 1310 unsigned int vmaster_tlv[4];
2134ea4f 1311 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1c82ed1b 1312 HDA_OUTPUT, vmaster_tlv);
2134ea4f 1313 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 1314 vmaster_tlv, slave_vols);
2134ea4f
TI
1315 if (err < 0)
1316 return err;
1317 }
1318 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1319 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1320 NULL, slave_sws);
1321 if (err < 0)
1322 return err;
1323 }
1324
603c4019 1325 stac92xx_free_kctls(codec); /* no longer needed */
dabbed6f 1326 return 0;
2f2f4251
M
1327}
1328
403d1944 1329static unsigned int ref9200_pin_configs[8] = {
dabbed6f 1330 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
2f2f4251
M
1331 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1332};
1333
dfe495d0
TI
1334/*
1335 STAC 9200 pin configs for
1336 102801A8
1337 102801DE
1338 102801E8
1339*/
1340static unsigned int dell9200_d21_pin_configs[8] = {
af6c016e
TI
1341 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
1342 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
dfe495d0
TI
1343};
1344
1345/*
1346 STAC 9200 pin configs for
1347 102801C0
1348 102801C1
1349*/
1350static unsigned int dell9200_d22_pin_configs[8] = {
af6c016e
TI
1351 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1352 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
dfe495d0
TI
1353};
1354
1355/*
1356 STAC 9200 pin configs for
1357 102801C4 (Dell Dimension E310)
1358 102801C5
1359 102801C7
1360 102801D9
1361 102801DA
1362 102801E3
1363*/
1364static unsigned int dell9200_d23_pin_configs[8] = {
af6c016e
TI
1365 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1366 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
dfe495d0
TI
1367};
1368
1369
1370/*
1371 STAC 9200-32 pin configs for
1372 102801B5 (Dell Inspiron 630m)
1373 102801D8 (Dell Inspiron 640m)
1374*/
1375static unsigned int dell9200_m21_pin_configs[8] = {
af6c016e
TI
1376 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
1377 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
dfe495d0
TI
1378};
1379
1380/*
1381 STAC 9200-32 pin configs for
1382 102801C2 (Dell Latitude D620)
1383 102801C8
1384 102801CC (Dell Latitude D820)
1385 102801D4
1386 102801D6
1387*/
1388static unsigned int dell9200_m22_pin_configs[8] = {
af6c016e
TI
1389 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
1390 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
dfe495d0
TI
1391};
1392
1393/*
1394 STAC 9200-32 pin configs for
1395 102801CE (Dell XPS M1710)
1396 102801CF (Dell Precision M90)
1397*/
1398static unsigned int dell9200_m23_pin_configs[8] = {
1399 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
1400 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
1401};
1402
1403/*
1404 STAC 9200-32 pin configs for
1405 102801C9
1406 102801CA
1407 102801CB (Dell Latitude 120L)
1408 102801D3
1409*/
1410static unsigned int dell9200_m24_pin_configs[8] = {
af6c016e
TI
1411 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
1412 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
dfe495d0
TI
1413};
1414
1415/*
1416 STAC 9200-32 pin configs for
1417 102801BD (Dell Inspiron E1505n)
1418 102801EE
1419 102801EF
1420*/
1421static unsigned int dell9200_m25_pin_configs[8] = {
af6c016e
TI
1422 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1423 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
dfe495d0
TI
1424};
1425
1426/*
1427 STAC 9200-32 pin configs for
1428 102801F5 (Dell Inspiron 1501)
1429 102801F6
1430*/
1431static unsigned int dell9200_m26_pin_configs[8] = {
af6c016e
TI
1432 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
1433 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
dfe495d0
TI
1434};
1435
1436/*
1437 STAC 9200-32
1438 102801CD (Dell Inspiron E1705/9400)
1439*/
1440static unsigned int dell9200_m27_pin_configs[8] = {
af6c016e
TI
1441 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1442 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
dfe495d0
TI
1443};
1444
bf277785
TD
1445static unsigned int oqo9200_pin_configs[8] = {
1446 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
1447 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
1448};
1449
dfe495d0 1450
f5fcc13c
TI
1451static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1452 [STAC_REF] = ref9200_pin_configs,
bf277785 1453 [STAC_9200_OQO] = oqo9200_pin_configs,
dfe495d0
TI
1454 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
1455 [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
1456 [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
1457 [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
1458 [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
1459 [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
1460 [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
1461 [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
1462 [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
1463 [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
117f257d 1464 [STAC_9200_PANASONIC] = ref9200_pin_configs,
403d1944
MP
1465};
1466
f5fcc13c
TI
1467static const char *stac9200_models[STAC_9200_MODELS] = {
1468 [STAC_REF] = "ref",
bf277785 1469 [STAC_9200_OQO] = "oqo",
dfe495d0
TI
1470 [STAC_9200_DELL_D21] = "dell-d21",
1471 [STAC_9200_DELL_D22] = "dell-d22",
1472 [STAC_9200_DELL_D23] = "dell-d23",
1473 [STAC_9200_DELL_M21] = "dell-m21",
1474 [STAC_9200_DELL_M22] = "dell-m22",
1475 [STAC_9200_DELL_M23] = "dell-m23",
1476 [STAC_9200_DELL_M24] = "dell-m24",
1477 [STAC_9200_DELL_M25] = "dell-m25",
1478 [STAC_9200_DELL_M26] = "dell-m26",
1479 [STAC_9200_DELL_M27] = "dell-m27",
1194b5b7 1480 [STAC_9200_GATEWAY] = "gateway",
117f257d 1481 [STAC_9200_PANASONIC] = "panasonic",
f5fcc13c
TI
1482};
1483
1484static struct snd_pci_quirk stac9200_cfg_tbl[] = {
1485 /* SigmaTel reference board */
1486 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1487 "DFI LanParty", STAC_REF),
e7377071 1488 /* Dell laptops have BIOS problem */
dfe495d0
TI
1489 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
1490 "unknown Dell", STAC_9200_DELL_D21),
f5fcc13c 1491 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
dfe495d0
TI
1492 "Dell Inspiron 630m", STAC_9200_DELL_M21),
1493 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
1494 "Dell Inspiron E1505n", STAC_9200_DELL_M25),
1495 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
1496 "unknown Dell", STAC_9200_DELL_D22),
1497 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
1498 "unknown Dell", STAC_9200_DELL_D22),
f5fcc13c 1499 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
dfe495d0
TI
1500 "Dell Latitude D620", STAC_9200_DELL_M22),
1501 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
1502 "unknown Dell", STAC_9200_DELL_D23),
1503 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
1504 "unknown Dell", STAC_9200_DELL_D23),
1505 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
1506 "unknown Dell", STAC_9200_DELL_M22),
1507 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
1508 "unknown Dell", STAC_9200_DELL_M24),
1509 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
1510 "unknown Dell", STAC_9200_DELL_M24),
f5fcc13c 1511 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
dfe495d0 1512 "Dell Latitude 120L", STAC_9200_DELL_M24),
877b866d 1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
dfe495d0 1514 "Dell Latitude D820", STAC_9200_DELL_M22),
46f02ca3 1515 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
dfe495d0 1516 "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
46f02ca3 1517 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
dfe495d0 1518 "Dell XPS M1710", STAC_9200_DELL_M23),
f0f96745 1519 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
dfe495d0
TI
1520 "Dell Precision M90", STAC_9200_DELL_M23),
1521 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
1522 "unknown Dell", STAC_9200_DELL_M22),
1523 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
1524 "unknown Dell", STAC_9200_DELL_M22),
8286c53e 1525 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
dfe495d0 1526 "unknown Dell", STAC_9200_DELL_M22),
49c605db 1527 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
dfe495d0
TI
1528 "Dell Inspiron 640m", STAC_9200_DELL_M21),
1529 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
1530 "unknown Dell", STAC_9200_DELL_D23),
1531 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
1532 "unknown Dell", STAC_9200_DELL_D23),
1533 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
1534 "unknown Dell", STAC_9200_DELL_D21),
1535 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
1536 "unknown Dell", STAC_9200_DELL_D23),
1537 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
1538 "unknown Dell", STAC_9200_DELL_D21),
1539 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
1540 "unknown Dell", STAC_9200_DELL_M25),
1541 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
1542 "unknown Dell", STAC_9200_DELL_M25),
49c605db 1543 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
dfe495d0
TI
1544 "Dell Inspiron 1501", STAC_9200_DELL_M26),
1545 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
1546 "unknown Dell", STAC_9200_DELL_M26),
49c605db 1547 /* Panasonic */
117f257d 1548 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
1194b5b7
TI
1549 /* Gateway machines needs EAPD to be set on resume */
1550 SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
1551 SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
1552 STAC_9200_GATEWAY),
1553 SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
1554 STAC_9200_GATEWAY),
bf277785
TD
1555 /* OQO Mobile */
1556 SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
403d1944
MP
1557 {} /* terminator */
1558};
1559
8e21c34c
TD
1560static unsigned int ref925x_pin_configs[8] = {
1561 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
09a99959 1562 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
8e21c34c
TD
1563};
1564
1565static unsigned int stac925x_MA6_pin_configs[8] = {
1566 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1567 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
1568};
1569
2c11f955
TD
1570static unsigned int stac925x_PA6_pin_configs[8] = {
1571 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1572 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
1573};
1574
8e21c34c 1575static unsigned int stac925xM2_2_pin_configs[8] = {
7353e14d
SL
1576 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
1577 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
8e21c34c
TD
1578};
1579
1580static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1581 [STAC_REF] = ref925x_pin_configs,
1582 [STAC_M2_2] = stac925xM2_2_pin_configs,
1583 [STAC_MA6] = stac925x_MA6_pin_configs,
2c11f955 1584 [STAC_PA6] = stac925x_PA6_pin_configs,
8e21c34c
TD
1585};
1586
1587static const char *stac925x_models[STAC_925x_MODELS] = {
1588 [STAC_REF] = "ref",
1589 [STAC_M2_2] = "m2-2",
1590 [STAC_MA6] = "m6",
2c11f955 1591 [STAC_PA6] = "pa6",
8e21c34c
TD
1592};
1593
1594static struct snd_pci_quirk stac925x_cfg_tbl[] = {
1595 /* SigmaTel reference board */
1596 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
2c11f955 1597 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
8e21c34c
TD
1598 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
1599 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
1600 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
2c11f955 1601 SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
8e21c34c
TD
1602 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
1603 {} /* terminator */
1604};
1605
a7662640 1606static unsigned int ref92hd73xx_pin_configs[13] = {
e1f0d669
MR
1607 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1608 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1609 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
a7662640
MR
1610 0x01452050,
1611};
1612
1613static unsigned int dell_m6_pin_configs[13] = {
1614 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
7c2ba97b 1615 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0,
a7662640
MR
1616 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1617 0x4f0000f0,
e1f0d669
MR
1618};
1619
1620static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
a7662640
MR
1621 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1622 [STAC_DELL_M6] = dell_m6_pin_configs,
6b3ab21e 1623 [STAC_DELL_EQ] = dell_m6_pin_configs,
e1f0d669
MR
1624};
1625
1626static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1627 [STAC_92HD73XX_REF] = "ref",
a7662640 1628 [STAC_DELL_M6] = "dell-m6",
6b3ab21e 1629 [STAC_DELL_EQ] = "dell-eq",
e1f0d669
MR
1630};
1631
1632static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1633 /* SigmaTel reference board */
1634 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
a7662640
MR
1635 "DFI LanParty", STAC_92HD73XX_REF),
1636 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1637 "unknown Dell", STAC_DELL_M6),
1638 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1639 "unknown Dell", STAC_DELL_M6),
1640 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1641 "unknown Dell", STAC_DELL_M6),
1642 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1643 "unknown Dell", STAC_DELL_M6),
1644 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1645 "unknown Dell", STAC_DELL_M6),
1646 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1647 "unknown Dell", STAC_DELL_M6),
1648 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1649 "unknown Dell", STAC_DELL_M6),
e1f0d669
MR
1650 {} /* terminator */
1651};
1652
d0513fc6
MR
1653static unsigned int ref92hd83xxx_pin_configs[14] = {
1654 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
1655 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
1656 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0,
1657 0x01451160, 0x98560170,
1658};
1659
1660static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1661 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1662};
1663
1664static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1665 [STAC_92HD83XXX_REF] = "ref",
1666};
1667
1668static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1669 /* SigmaTel reference board */
1670 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1671 "DFI LanParty", STAC_92HD71BXX_REF),
1672};
1673
0ffa9807 1674static unsigned int ref92hd71bxx_pin_configs[11] = {
e035b841 1675 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
4b33c767 1676 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
0ffa9807 1677 0x90a000f0, 0x01452050, 0x01452050,
e035b841
MR
1678};
1679
0ffa9807 1680static unsigned int dell_m4_1_pin_configs[11] = {
a7662640 1681 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
07bcb316 1682 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
0ffa9807 1683 0x40f000f0, 0x4f0000f0, 0x4f0000f0,
a7662640
MR
1684};
1685
0ffa9807 1686static unsigned int dell_m4_2_pin_configs[11] = {
a7662640
MR
1687 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1688 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
0ffa9807 1689 0x40f000f0, 0x044413b0, 0x044413b0,
a7662640
MR
1690};
1691
e035b841
MR
1692static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1693 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
a7662640
MR
1694 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1695 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
6a14f585 1696 [STAC_HP_M4] = NULL,
e035b841
MR
1697};
1698
1699static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1700 [STAC_92HD71BXX_REF] = "ref",
a7662640
MR
1701 [STAC_DELL_M4_1] = "dell-m4-1",
1702 [STAC_DELL_M4_2] = "dell-m4-2",
6a14f585 1703 [STAC_HP_M4] = "hp-m4",
e035b841
MR
1704};
1705
1706static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1707 /* SigmaTel reference board */
1708 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1709 "DFI LanParty", STAC_92HD71BXX_REF),
9a9e2359
MR
1710 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1711 "unknown HP", STAC_HP_M4),
a7662640
MR
1712 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
1713 "unknown Dell", STAC_DELL_M4_1),
1714 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
1715 "unknown Dell", STAC_DELL_M4_1),
1716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
1717 "unknown Dell", STAC_DELL_M4_1),
1718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
1719 "unknown Dell", STAC_DELL_M4_1),
1720 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
1721 "unknown Dell", STAC_DELL_M4_1),
1722 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
1723 "unknown Dell", STAC_DELL_M4_1),
1724 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
1725 "unknown Dell", STAC_DELL_M4_1),
1726 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
1727 "unknown Dell", STAC_DELL_M4_2),
1728 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
1729 "unknown Dell", STAC_DELL_M4_2),
1730 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
1731 "unknown Dell", STAC_DELL_M4_2),
1732 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
1733 "unknown Dell", STAC_DELL_M4_2),
e035b841
MR
1734 {} /* terminator */
1735};
1736
403d1944
MP
1737static unsigned int ref922x_pin_configs[10] = {
1738 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1739 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
2f2f4251
M
1740 0x40000100, 0x40000100,
1741};
1742
dfe495d0
TI
1743/*
1744 STAC 922X pin configs for
1745 102801A7
1746 102801AB
1747 102801A9
1748 102801D1
1749 102801D2
1750*/
1751static unsigned int dell_922x_d81_pin_configs[10] = {
1752 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1753 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1754 0x01813122, 0x400001f2,
1755};
1756
1757/*
1758 STAC 922X pin configs for
1759 102801AC
1760 102801D0
1761*/
1762static unsigned int dell_922x_d82_pin_configs[10] = {
1763 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1764 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1765 0x01813122, 0x400001f1,
1766};
1767
1768/*
1769 STAC 922X pin configs for
1770 102801BF
1771*/
1772static unsigned int dell_922x_m81_pin_configs[10] = {
1773 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1774 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1775 0x40C003f1, 0x405003f0,
1776};
1777
1778/*
1779 STAC 9221 A1 pin configs for
1780 102801D7 (Dell XPS M1210)
1781*/
1782static unsigned int dell_922x_m82_pin_configs[10] = {
7f9310c1
JZ
1783 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1784 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
dfe495d0
TI
1785 0x508003f3, 0x405003f4,
1786};
1787
403d1944 1788static unsigned int d945gtp3_pin_configs[10] = {
869264c4 1789 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
403d1944
MP
1790 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1791 0x02a19120, 0x40000100,
1792};
1793
1794static unsigned int d945gtp5_pin_configs[10] = {
869264c4
MP
1795 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1796 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
403d1944
MP
1797 0x02a19320, 0x40000100,
1798};
1799
5d5d3bc3
IZ
1800static unsigned int intel_mac_v1_pin_configs[10] = {
1801 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1802 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1803 0x400000fc, 0x400000fb,
1804};
1805
1806static unsigned int intel_mac_v2_pin_configs[10] = {
1807 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1808 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1809 0x400000fc, 0x400000fb,
6f0778d8
NB
1810};
1811
5d5d3bc3
IZ
1812static unsigned int intel_mac_v3_pin_configs[10] = {
1813 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1814 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
3fc24d85
TI
1815 0x400000fc, 0x400000fb,
1816};
1817
5d5d3bc3
IZ
1818static unsigned int intel_mac_v4_pin_configs[10] = {
1819 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1820 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
f16928fb
SF
1821 0x400000fc, 0x400000fb,
1822};
1823
5d5d3bc3
IZ
1824static unsigned int intel_mac_v5_pin_configs[10] = {
1825 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1826 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1827 0x400000fc, 0x400000fb,
0dae0f83
TI
1828};
1829
8c650087
MCC
1830static unsigned int ecs202_pin_configs[10] = {
1831 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
1832 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
1833 0x9037012e, 0x40e000f2,
1834};
76c08828 1835
19039bd0 1836static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
f5fcc13c 1837 [STAC_D945_REF] = ref922x_pin_configs,
19039bd0
TI
1838 [STAC_D945GTP3] = d945gtp3_pin_configs,
1839 [STAC_D945GTP5] = d945gtp5_pin_configs,
5d5d3bc3
IZ
1840 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
1841 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
1842 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
1843 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
1844 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
536319af 1845 [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs,
dfe495d0 1846 /* for backward compatibility */
5d5d3bc3
IZ
1847 [STAC_MACMINI] = intel_mac_v3_pin_configs,
1848 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
1849 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
1850 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
1851 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
1852 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
8c650087 1853 [STAC_ECS_202] = ecs202_pin_configs,
dfe495d0
TI
1854 [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
1855 [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
1856 [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
1857 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
403d1944
MP
1858};
1859
f5fcc13c
TI
1860static const char *stac922x_models[STAC_922X_MODELS] = {
1861 [STAC_D945_REF] = "ref",
1862 [STAC_D945GTP5] = "5stack",
1863 [STAC_D945GTP3] = "3stack",
5d5d3bc3
IZ
1864 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
1865 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
1866 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
1867 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
1868 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
536319af 1869 [STAC_INTEL_MAC_AUTO] = "intel-mac-auto",
dfe495d0 1870 /* for backward compatibility */
f5fcc13c 1871 [STAC_MACMINI] = "macmini",
3fc24d85 1872 [STAC_MACBOOK] = "macbook",
6f0778d8
NB
1873 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
1874 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
f16928fb 1875 [STAC_IMAC_INTEL] = "imac-intel",
0dae0f83 1876 [STAC_IMAC_INTEL_20] = "imac-intel-20",
8c650087 1877 [STAC_ECS_202] = "ecs202",
dfe495d0
TI
1878 [STAC_922X_DELL_D81] = "dell-d81",
1879 [STAC_922X_DELL_D82] = "dell-d82",
1880 [STAC_922X_DELL_M81] = "dell-m81",
1881 [STAC_922X_DELL_M82] = "dell-m82",
f5fcc13c
TI
1882};
1883
1884static struct snd_pci_quirk stac922x_cfg_tbl[] = {
1885 /* SigmaTel reference board */
1886 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1887 "DFI LanParty", STAC_D945_REF),
1888 /* Intel 945G based systems */
1889 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
1890 "Intel D945G", STAC_D945GTP3),
1891 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
1892 "Intel D945G", STAC_D945GTP3),
1893 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
1894 "Intel D945G", STAC_D945GTP3),
1895 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
1896 "Intel D945G", STAC_D945GTP3),
1897 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
1898 "Intel D945G", STAC_D945GTP3),
1899 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
1900 "Intel D945G", STAC_D945GTP3),
1901 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
1902 "Intel D945G", STAC_D945GTP3),
1903 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
1904 "Intel D945G", STAC_D945GTP3),
1905 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
1906 "Intel D945G", STAC_D945GTP3),
1907 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
1908 "Intel D945G", STAC_D945GTP3),
1909 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
1910 "Intel D945G", STAC_D945GTP3),
1911 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
1912 "Intel D945G", STAC_D945GTP3),
1913 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
1914 "Intel D945G", STAC_D945GTP3),
1915 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
1916 "Intel D945G", STAC_D945GTP3),
1917 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
1918 "Intel D945G", STAC_D945GTP3),
1919 /* Intel D945G 5-stack systems */
1920 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
1921 "Intel D945G", STAC_D945GTP5),
1922 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
1923 "Intel D945G", STAC_D945GTP5),
1924 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
1925 "Intel D945G", STAC_D945GTP5),
1926 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
1927 "Intel D945G", STAC_D945GTP5),
1928 /* Intel 945P based systems */
1929 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
1930 "Intel D945P", STAC_D945GTP3),
1931 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
1932 "Intel D945P", STAC_D945GTP3),
1933 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
1934 "Intel D945P", STAC_D945GTP3),
1935 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
1936 "Intel D945P", STAC_D945GTP3),
1937 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
1938 "Intel D945P", STAC_D945GTP3),
1939 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
1940 "Intel D945P", STAC_D945GTP5),
1941 /* other systems */
536319af 1942 /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
f5fcc13c 1943 SND_PCI_QUIRK(0x8384, 0x7680,
536319af 1944 "Mac", STAC_INTEL_MAC_AUTO),
dfe495d0
TI
1945 /* Dell systems */
1946 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
1947 "unknown Dell", STAC_922X_DELL_D81),
1948 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
1949 "unknown Dell", STAC_922X_DELL_D81),
1950 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
1951 "unknown Dell", STAC_922X_DELL_D81),
1952 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
1953 "unknown Dell", STAC_922X_DELL_D82),
1954 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
1955 "unknown Dell", STAC_922X_DELL_M81),
1956 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
1957 "unknown Dell", STAC_922X_DELL_D82),
1958 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
1959 "unknown Dell", STAC_922X_DELL_D81),
1960 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
1961 "unknown Dell", STAC_922X_DELL_D81),
1962 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
1963 "Dell XPS M1210", STAC_922X_DELL_M82),
8c650087
MCC
1964 /* ECS/PC Chips boards */
1965 SND_PCI_QUIRK(0x1019, 0x2144,
1966 "ECS/PC chips", STAC_ECS_202),
1967 SND_PCI_QUIRK(0x1019, 0x2608,
1968 "ECS/PC chips", STAC_ECS_202),
1969 SND_PCI_QUIRK(0x1019, 0x2633,
1970 "ECS/PC chips P17G/1333", STAC_ECS_202),
1971 SND_PCI_QUIRK(0x1019, 0x2811,
1972 "ECS/PC chips", STAC_ECS_202),
1973 SND_PCI_QUIRK(0x1019, 0x2812,
1974 "ECS/PC chips", STAC_ECS_202),
1975 SND_PCI_QUIRK(0x1019, 0x2813,
1976 "ECS/PC chips", STAC_ECS_202),
1977 SND_PCI_QUIRK(0x1019, 0x2814,
1978 "ECS/PC chips", STAC_ECS_202),
1979 SND_PCI_QUIRK(0x1019, 0x2815,
1980 "ECS/PC chips", STAC_ECS_202),
1981 SND_PCI_QUIRK(0x1019, 0x2816,
1982 "ECS/PC chips", STAC_ECS_202),
1983 SND_PCI_QUIRK(0x1019, 0x2817,
1984 "ECS/PC chips", STAC_ECS_202),
1985 SND_PCI_QUIRK(0x1019, 0x2818,
1986 "ECS/PC chips", STAC_ECS_202),
1987 SND_PCI_QUIRK(0x1019, 0x2819,
1988 "ECS/PC chips", STAC_ECS_202),
1989 SND_PCI_QUIRK(0x1019, 0x2820,
1990 "ECS/PC chips", STAC_ECS_202),
403d1944
MP
1991 {} /* terminator */
1992};
1993
3cc08dc6 1994static unsigned int ref927x_pin_configs[14] = {
93ed1503
TD
1995 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
1996 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
1997 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
1998 0x01c42190, 0x40000100,
3cc08dc6
MP
1999};
2000
93ed1503 2001static unsigned int d965_3st_pin_configs[14] = {
81d3dbde
TD
2002 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
2003 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
2004 0x40000100, 0x40000100, 0x40000100, 0x40000100,
2005 0x40000100, 0x40000100
2006};
2007
93ed1503
TD
2008static unsigned int d965_5st_pin_configs[14] = {
2009 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2010 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2011 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2012 0x40000100, 0x40000100
2013};
2014
4ff076e5
TD
2015static unsigned int dell_3st_pin_configs[14] = {
2016 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
2017 0x01111212, 0x01116211, 0x01813050, 0x01112214,
8e9068b1 2018 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
4ff076e5
TD
2019 0x40c003fc, 0x40000100
2020};
2021
93ed1503 2022static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
8e9068b1
MR
2023 [STAC_D965_REF] = ref927x_pin_configs,
2024 [STAC_D965_3ST] = d965_3st_pin_configs,
2025 [STAC_D965_5ST] = d965_5st_pin_configs,
2026 [STAC_DELL_3ST] = dell_3st_pin_configs,
2027 [STAC_DELL_BIOS] = NULL,
3cc08dc6
MP
2028};
2029
f5fcc13c 2030static const char *stac927x_models[STAC_927X_MODELS] = {
8e9068b1
MR
2031 [STAC_D965_REF] = "ref",
2032 [STAC_D965_3ST] = "3stack",
2033 [STAC_D965_5ST] = "5stack",
2034 [STAC_DELL_3ST] = "dell-3stack",
2035 [STAC_DELL_BIOS] = "dell-bios",
f5fcc13c
TI
2036};
2037
2038static struct snd_pci_quirk stac927x_cfg_tbl[] = {
2039 /* SigmaTel reference board */
2040 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2041 "DFI LanParty", STAC_D965_REF),
81d3dbde 2042 /* Intel 946 based systems */
f5fcc13c
TI
2043 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
2044 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
93ed1503 2045 /* 965 based 3 stack systems */
f5fcc13c
TI
2046 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
2047 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
2048 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
2049 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
2050 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
2051 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
2052 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
2053 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
2054 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
2055 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
2056 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
2057 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
2058 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
2059 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
2060 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
2061 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
4ff076e5 2062 /* Dell 3 stack systems */
8e9068b1 2063 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
dfe495d0 2064 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
4ff076e5
TD
2065 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
2066 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
8e9068b1 2067 /* Dell 3 stack systems with verb table in BIOS */
2f32d909
MR
2068 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
2069 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
8e9068b1 2070 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
24918b61 2071 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
8e9068b1
MR
2072 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
2073 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
2074 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
2075 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
93ed1503 2076 /* 965 based 5 stack systems */
f5fcc13c
TI
2077 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
2078 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
2079 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
2080 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
2081 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
2082 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
2083 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
2084 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
2085 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
3cc08dc6
MP
2086 {} /* terminator */
2087};
2088
f3302a59
MP
2089static unsigned int ref9205_pin_configs[12] = {
2090 0x40000100, 0x40000100, 0x01016011, 0x01014010,
09a99959 2091 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
8b65727b 2092 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
f3302a59
MP
2093};
2094
dfe495d0
TI
2095/*
2096 STAC 9205 pin configs for
2097 102801F1
2098 102801F2
2099 102801FC
2100 102801FD
2101 10280204
2102 1028021F
3fa2ef74 2103 10280228 (Dell Vostro 1500)
dfe495d0
TI
2104*/
2105static unsigned int dell_9205_m42_pin_configs[12] = {
2106 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
2107 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
2108 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
2109};
2110
2111/*
2112 STAC 9205 pin configs for
2113 102801F9
2114 102801FA
2115 102801FE
2116 102801FF (Dell Precision M4300)
2117 10280206
2118 10280200
2119 10280201
2120*/
2121static unsigned int dell_9205_m43_pin_configs[12] = {
ae0a8ed8
TD
2122 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
2123 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
2124 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
2125};
2126
dfe495d0 2127static unsigned int dell_9205_m44_pin_configs[12] = {
ae0a8ed8
TD
2128 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
2129 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
2130 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
2131};
2132
f5fcc13c 2133static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
ae0a8ed8 2134 [STAC_9205_REF] = ref9205_pin_configs,
dfe495d0
TI
2135 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
2136 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
2137 [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
f3302a59
MP
2138};
2139
f5fcc13c
TI
2140static const char *stac9205_models[STAC_9205_MODELS] = {
2141 [STAC_9205_REF] = "ref",
dfe495d0 2142 [STAC_9205_DELL_M42] = "dell-m42",
ae0a8ed8
TD
2143 [STAC_9205_DELL_M43] = "dell-m43",
2144 [STAC_9205_DELL_M44] = "dell-m44",
f5fcc13c
TI
2145};
2146
2147static struct snd_pci_quirk stac9205_cfg_tbl[] = {
2148 /* SigmaTel reference board */
2149 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2150 "DFI LanParty", STAC_9205_REF),
dfe495d0
TI
2151 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
2152 "unknown Dell", STAC_9205_DELL_M42),
2153 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
2154 "unknown Dell", STAC_9205_DELL_M42),
ae0a8ed8 2155 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
b44ef2f1 2156 "Dell Precision", STAC_9205_DELL_M43),
ae0a8ed8
TD
2157 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
2158 "Dell Precision", STAC_9205_DELL_M43),
2159 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
2160 "Dell Precision", STAC_9205_DELL_M43),
dfe495d0
TI
2161 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
2162 "unknown Dell", STAC_9205_DELL_M42),
2163 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
2164 "unknown Dell", STAC_9205_DELL_M42),
ae0a8ed8
TD
2165 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
2166 "Dell Precision", STAC_9205_DELL_M43),
2167 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
dfe495d0 2168 "Dell Precision M4300", STAC_9205_DELL_M43),
dfe495d0
TI
2169 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
2170 "unknown Dell", STAC_9205_DELL_M42),
4549915c
TI
2171 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
2172 "Dell Precision", STAC_9205_DELL_M43),
2173 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
2174 "Dell Precision", STAC_9205_DELL_M43),
2175 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
2176 "Dell Precision", STAC_9205_DELL_M43),
ae0a8ed8
TD
2177 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
2178 "Dell Inspiron", STAC_9205_DELL_M44),
3fa2ef74
MR
2179 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
2180 "Dell Vostro 1500", STAC_9205_DELL_M42),
f3302a59
MP
2181 {} /* terminator */
2182};
2183
11b44bbd
RF
2184static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
2185{
2186 int i;
2187 struct sigmatel_spec *spec = codec->spec;
2188
2189 if (! spec->bios_pin_configs) {
2190 spec->bios_pin_configs = kcalloc(spec->num_pins,
2191 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
2192 if (! spec->bios_pin_configs)
2193 return -ENOMEM;
2194 }
2195
2196 for (i = 0; i < spec->num_pins; i++) {
2197 hda_nid_t nid = spec->pin_nids[i];
2198 unsigned int pin_cfg;
2199
2200 pin_cfg = snd_hda_codec_read(codec, nid, 0,
2201 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
2202 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
2203 nid, pin_cfg);
2204 spec->bios_pin_configs[i] = pin_cfg;
2205 }
2206
2207 return 0;
2208}
2209
87d48363
MR
2210static void stac92xx_set_config_reg(struct hda_codec *codec,
2211 hda_nid_t pin_nid, unsigned int pin_config)
2212{
2213 int i;
2214 snd_hda_codec_write(codec, pin_nid, 0,
2215 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2216 pin_config & 0x000000ff);
2217 snd_hda_codec_write(codec, pin_nid, 0,
2218 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2219 (pin_config & 0x0000ff00) >> 8);
2220 snd_hda_codec_write(codec, pin_nid, 0,
2221 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2222 (pin_config & 0x00ff0000) >> 16);
2223 snd_hda_codec_write(codec, pin_nid, 0,
2224 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2225 pin_config >> 24);
2226 i = snd_hda_codec_read(codec, pin_nid, 0,
2227 AC_VERB_GET_CONFIG_DEFAULT,
2228 0x00);
2229 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
2230 pin_nid, i);
2231}
2232
2f2f4251
M
2233static void stac92xx_set_config_regs(struct hda_codec *codec)
2234{
2235 int i;
2236 struct sigmatel_spec *spec = codec->spec;
2f2f4251 2237
87d48363
MR
2238 if (!spec->pin_configs)
2239 return;
11b44bbd 2240
87d48363
MR
2241 for (i = 0; i < spec->num_pins; i++)
2242 stac92xx_set_config_reg(codec, spec->pin_nids[i],
2243 spec->pin_configs[i]);
2f2f4251 2244}
2f2f4251 2245
dabbed6f 2246/*
c7d4b2fa 2247 * Analog playback callbacks
dabbed6f 2248 */
c7d4b2fa
M
2249static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
2250 struct hda_codec *codec,
c8b6bf9b 2251 struct snd_pcm_substream *substream)
2f2f4251 2252{
dabbed6f 2253 struct sigmatel_spec *spec = codec->spec;
8daaaa97
MR
2254 if (spec->stream_delay)
2255 msleep(spec->stream_delay);
9a08160b
TI
2256 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2257 hinfo);
2f2f4251
M
2258}
2259
2f2f4251
M
2260static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2261 struct hda_codec *codec,
2262 unsigned int stream_tag,
2263 unsigned int format,
c8b6bf9b 2264 struct snd_pcm_substream *substream)
2f2f4251
M
2265{
2266 struct sigmatel_spec *spec = codec->spec;
403d1944 2267 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
2f2f4251
M
2268}
2269
2270static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2271 struct hda_codec *codec,
c8b6bf9b 2272 struct snd_pcm_substream *substream)
2f2f4251
M
2273{
2274 struct sigmatel_spec *spec = codec->spec;
2275 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2276}
2277
dabbed6f
M
2278/*
2279 * Digital playback callbacks
2280 */
2281static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2282 struct hda_codec *codec,
c8b6bf9b 2283 struct snd_pcm_substream *substream)
dabbed6f
M
2284{
2285 struct sigmatel_spec *spec = codec->spec;
2286 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2287}
2288
2289static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2290 struct hda_codec *codec,
c8b6bf9b 2291 struct snd_pcm_substream *substream)
dabbed6f
M
2292{
2293 struct sigmatel_spec *spec = codec->spec;
2294 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2295}
2296
6b97eb45
TI
2297static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2298 struct hda_codec *codec,
2299 unsigned int stream_tag,
2300 unsigned int format,
2301 struct snd_pcm_substream *substream)
2302{
2303 struct sigmatel_spec *spec = codec->spec;
2304 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2305 stream_tag, format, substream);
2306}
2307
dabbed6f 2308
2f2f4251
M
2309/*
2310 * Analog capture callbacks
2311 */
2312static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2313 struct hda_codec *codec,
2314 unsigned int stream_tag,
2315 unsigned int format,
c8b6bf9b 2316 struct snd_pcm_substream *substream)
2f2f4251
M
2317{
2318 struct sigmatel_spec *spec = codec->spec;
8daaaa97 2319 hda_nid_t nid = spec->adc_nids[substream->number];
2f2f4251 2320
8daaaa97
MR
2321 if (spec->powerdown_adcs) {
2322 msleep(40);
2323 snd_hda_codec_write_cache(codec, nid, 0,
2324 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2325 }
2326 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
2f2f4251
M
2327 return 0;
2328}
2329
2330static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2331 struct hda_codec *codec,
c8b6bf9b 2332 struct snd_pcm_substream *substream)
2f2f4251
M
2333{
2334 struct sigmatel_spec *spec = codec->spec;
8daaaa97 2335 hda_nid_t nid = spec->adc_nids[substream->number];
2f2f4251 2336
8daaaa97
MR
2337 snd_hda_codec_cleanup_stream(codec, nid);
2338 if (spec->powerdown_adcs)
2339 snd_hda_codec_write_cache(codec, nid, 0,
2340 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2f2f4251
M
2341 return 0;
2342}
2343
dabbed6f
M
2344static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
2345 .substreams = 1,
2346 .channels_min = 2,
2347 .channels_max = 2,
2348 /* NID is set in stac92xx_build_pcms */
2349 .ops = {
2350 .open = stac92xx_dig_playback_pcm_open,
6b97eb45
TI
2351 .close = stac92xx_dig_playback_pcm_close,
2352 .prepare = stac92xx_dig_playback_pcm_prepare
dabbed6f
M
2353 },
2354};
2355
2356static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
2357 .substreams = 1,
2358 .channels_min = 2,
2359 .channels_max = 2,
2360 /* NID is set in stac92xx_build_pcms */
2361};
2362
2f2f4251
M
2363static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2364 .substreams = 1,
2365 .channels_min = 2,
c7d4b2fa 2366 .channels_max = 8,
2f2f4251
M
2367 .nid = 0x02, /* NID to query formats and rates */
2368 .ops = {
2369 .open = stac92xx_playback_pcm_open,
2370 .prepare = stac92xx_playback_pcm_prepare,
2371 .cleanup = stac92xx_playback_pcm_cleanup
2372 },
2373};
2374
3cc08dc6
MP
2375static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
2376 .substreams = 1,
2377 .channels_min = 2,
2378 .channels_max = 2,
2379 .nid = 0x06, /* NID to query formats and rates */
2380 .ops = {
2381 .open = stac92xx_playback_pcm_open,
2382 .prepare = stac92xx_playback_pcm_prepare,
2383 .cleanup = stac92xx_playback_pcm_cleanup
2384 },
2385};
2386
2f2f4251 2387static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
2f2f4251
M
2388 .channels_min = 2,
2389 .channels_max = 2,
9e05b7a3 2390 /* NID + .substreams is set in stac92xx_build_pcms */
2f2f4251
M
2391 .ops = {
2392 .prepare = stac92xx_capture_pcm_prepare,
2393 .cleanup = stac92xx_capture_pcm_cleanup
2394 },
2395};
2396
2397static int stac92xx_build_pcms(struct hda_codec *codec)
2398{
2399 struct sigmatel_spec *spec = codec->spec;
2400 struct hda_pcm *info = spec->pcm_rec;
2401
2402 codec->num_pcms = 1;
2403 codec->pcm_info = info;
2404
c7d4b2fa 2405 info->name = "STAC92xx Analog";
2f2f4251 2406 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
2f2f4251 2407 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
3cc08dc6 2408 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
9e05b7a3 2409 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
3cc08dc6
MP
2410
2411 if (spec->alt_switch) {
2412 codec->num_pcms++;
2413 info++;
2414 info->name = "STAC92xx Analog Alt";
2415 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
2416 }
2f2f4251 2417
dabbed6f
M
2418 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2419 codec->num_pcms++;
2420 info++;
2421 info->name = "STAC92xx Digital";
7ba72ba1 2422 info->pcm_type = HDA_PCM_TYPE_SPDIF;
dabbed6f
M
2423 if (spec->multiout.dig_out_nid) {
2424 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
2425 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2426 }
2427 if (spec->dig_in_nid) {
2428 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
2429 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2430 }
2431 }
2432
2f2f4251
M
2433 return 0;
2434}
2435
c960a03b
TI
2436static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
2437{
2438 unsigned int pincap = snd_hda_param_read(codec, nid,
2439 AC_PAR_PIN_CAP);
2440 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2441 if (pincap & AC_PINCAP_VREF_100)
2442 return AC_PINCTL_VREF_100;
2443 if (pincap & AC_PINCAP_VREF_80)
2444 return AC_PINCTL_VREF_80;
2445 if (pincap & AC_PINCAP_VREF_50)
2446 return AC_PINCTL_VREF_50;
2447 if (pincap & AC_PINCAP_VREF_GRD)
2448 return AC_PINCTL_VREF_GRD;
2449 return 0;
2450}
2451
403d1944
MP
2452static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
2453
2454{
82beb8fd
TI
2455 snd_hda_codec_write_cache(codec, nid, 0,
2456 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
403d1944
MP
2457}
2458
7c2ba97b
MR
2459#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
2460
2461static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2462 struct snd_ctl_elem_value *ucontrol)
2463{
2464 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2465 struct sigmatel_spec *spec = codec->spec;
2466
d7a89436 2467 ucontrol->value.integer.value[0] = !!spec->hp_switch;
7c2ba97b
MR
2468 return 0;
2469}
2470
2471static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2472 struct snd_ctl_elem_value *ucontrol)
2473{
2474 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2475 struct sigmatel_spec *spec = codec->spec;
d7a89436
TI
2476 int nid = kcontrol->private_value;
2477
2478 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
7c2ba97b
MR
2479
2480 /* check to be sure that the ports are upto date with
2481 * switch changes
2482 */
74aeaabc 2483 codec->patch_ops.unsol_event(codec, (STAC_HP_EVENT | nid) << 26);
7c2ba97b
MR
2484
2485 return 1;
2486}
2487
a5ce8890 2488#define stac92xx_io_switch_info snd_ctl_boolean_mono_info
403d1944
MP
2489
2490static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2491{
2492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2493 struct sigmatel_spec *spec = codec->spec;
2494 int io_idx = kcontrol-> private_value & 0xff;
2495
2496 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
2497 return 0;
2498}
2499
2500static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2501{
2502 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2503 struct sigmatel_spec *spec = codec->spec;
2504 hda_nid_t nid = kcontrol->private_value >> 8;
2505 int io_idx = kcontrol-> private_value & 0xff;
68ea7b2f 2506 unsigned short val = !!ucontrol->value.integer.value[0];
403d1944
MP
2507
2508 spec->io_switch[io_idx] = val;
2509
2510 if (val)
2511 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
c960a03b
TI
2512 else {
2513 unsigned int pinctl = AC_PINCTL_IN_EN;
2514 if (io_idx) /* set VREF for mic */
2515 pinctl |= stac92xx_get_vref(codec, nid);
2516 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2517 }
40c1d308
JZ
2518
2519 /* check the auto-mute again: we need to mute/unmute the speaker
2520 * appropriately according to the pin direction
2521 */
2522 if (spec->hp_detect)
74aeaabc
MR
2523 codec->patch_ops.unsol_event(codec,
2524 (STAC_HP_EVENT | nid) << 26);
40c1d308 2525
403d1944
MP
2526 return 1;
2527}
2528
0fb87bb4
ML
2529#define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
2530
2531static int stac92xx_clfe_switch_get(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;
2536
2537 ucontrol->value.integer.value[0] = spec->clfe_swap;
2538 return 0;
2539}
2540
2541static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
2542 struct snd_ctl_elem_value *ucontrol)
2543{
2544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2545 struct sigmatel_spec *spec = codec->spec;
2546 hda_nid_t nid = kcontrol->private_value & 0xff;
68ea7b2f 2547 unsigned int val = !!ucontrol->value.integer.value[0];
0fb87bb4 2548
68ea7b2f 2549 if (spec->clfe_swap == val)
0fb87bb4
ML
2550 return 0;
2551
68ea7b2f 2552 spec->clfe_swap = val;
0fb87bb4
ML
2553
2554 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
2555 spec->clfe_swap ? 0x4 : 0x0);
2556
2557 return 1;
2558}
2559
7c2ba97b
MR
2560#define STAC_CODEC_HP_SWITCH(xname) \
2561 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2562 .name = xname, \
2563 .index = 0, \
2564 .info = stac92xx_hp_switch_info, \
2565 .get = stac92xx_hp_switch_get, \
2566 .put = stac92xx_hp_switch_put, \
2567 }
2568
403d1944
MP
2569#define STAC_CODEC_IO_SWITCH(xname, xpval) \
2570 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2571 .name = xname, \
2572 .index = 0, \
2573 .info = stac92xx_io_switch_info, \
2574 .get = stac92xx_io_switch_get, \
2575 .put = stac92xx_io_switch_put, \
2576 .private_value = xpval, \
2577 }
2578
0fb87bb4
ML
2579#define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
2580 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2581 .name = xname, \
2582 .index = 0, \
2583 .info = stac92xx_clfe_switch_info, \
2584 .get = stac92xx_clfe_switch_get, \
2585 .put = stac92xx_clfe_switch_put, \
2586 .private_value = xpval, \
2587 }
403d1944 2588
c7d4b2fa
M
2589enum {
2590 STAC_CTL_WIDGET_VOL,
2591 STAC_CTL_WIDGET_MUTE,
09a99959 2592 STAC_CTL_WIDGET_MONO_MUX,
89385035
MR
2593 STAC_CTL_WIDGET_AMP_MUX,
2594 STAC_CTL_WIDGET_AMP_VOL,
7c2ba97b 2595 STAC_CTL_WIDGET_HP_SWITCH,
403d1944 2596 STAC_CTL_WIDGET_IO_SWITCH,
0fb87bb4 2597 STAC_CTL_WIDGET_CLFE_SWITCH
c7d4b2fa
M
2598};
2599
c8b6bf9b 2600static struct snd_kcontrol_new stac92xx_control_templates[] = {
c7d4b2fa
M
2601 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2602 HDA_CODEC_MUTE(NULL, 0, 0, 0),
09a99959 2603 STAC_MONO_MUX,
89385035
MR
2604 STAC_AMP_MUX,
2605 STAC_AMP_VOL(NULL, 0, 0, 0, 0),
7c2ba97b 2606 STAC_CODEC_HP_SWITCH(NULL),
403d1944 2607 STAC_CODEC_IO_SWITCH(NULL, 0),
0fb87bb4 2608 STAC_CODEC_CLFE_SWITCH(NULL, 0),
c7d4b2fa
M
2609};
2610
2611/* add dynamic controls */
4d4e9bb3
TI
2612static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2613 struct snd_kcontrol_new *ktemp,
2614 int idx, const char *name,
2615 unsigned long val)
c7d4b2fa 2616{
c8b6bf9b 2617 struct snd_kcontrol_new *knew;
c7d4b2fa 2618
603c4019
TI
2619 snd_array_init(&spec->kctls, sizeof(*knew), 32);
2620 knew = snd_array_new(&spec->kctls);
2621 if (!knew)
2622 return -ENOMEM;
4d4e9bb3 2623 *knew = *ktemp;
4682eee0 2624 knew->index = idx;
82fe0c58 2625 knew->name = kstrdup(name, GFP_KERNEL);
4d4e9bb3 2626 if (!knew->name)
c7d4b2fa
M
2627 return -ENOMEM;
2628 knew->private_value = val;
c7d4b2fa
M
2629 return 0;
2630}
2631
4d4e9bb3
TI
2632static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
2633 int type, int idx, const char *name,
2634 unsigned long val)
2635{
2636 return stac92xx_add_control_temp(spec,
2637 &stac92xx_control_templates[type],
2638 idx, name, val);
2639}
2640
4682eee0
MR
2641
2642/* add dynamic controls */
4d4e9bb3
TI
2643static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2644 const char *name, unsigned long val)
4682eee0
MR
2645{
2646 return stac92xx_add_control_idx(spec, type, 0, name, val);
2647}
2648
403d1944
MP
2649/* flag inputs as additional dynamic lineouts */
2650static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
2651{
2652 struct sigmatel_spec *spec = codec->spec;
7b043899
SL
2653 unsigned int wcaps, wtype;
2654 int i, num_dacs = 0;
2655
2656 /* use the wcaps cache to count all DACs available for line-outs */
2657 for (i = 0; i < codec->num_nodes; i++) {
2658 wcaps = codec->wcaps[i];
2659 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8e9068b1 2660
7b043899
SL
2661 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
2662 num_dacs++;
2663 }
403d1944 2664
7b043899
SL
2665 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
2666
403d1944
MP
2667 switch (cfg->line_outs) {
2668 case 3:
2669 /* add line-in as side */
7b043899 2670 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
c480f79b
TI
2671 cfg->line_out_pins[cfg->line_outs] =
2672 cfg->input_pins[AUTO_PIN_LINE];
403d1944
MP
2673 spec->line_switch = 1;
2674 cfg->line_outs++;
2675 }
2676 break;
2677 case 2:
2678 /* add line-in as clfe and mic as side */
7b043899 2679 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
c480f79b
TI
2680 cfg->line_out_pins[cfg->line_outs] =
2681 cfg->input_pins[AUTO_PIN_LINE];
403d1944
MP
2682 spec->line_switch = 1;
2683 cfg->line_outs++;
2684 }
7b043899 2685 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
c480f79b
TI
2686 cfg->line_out_pins[cfg->line_outs] =
2687 cfg->input_pins[AUTO_PIN_MIC];
403d1944
MP
2688 spec->mic_switch = 1;
2689 cfg->line_outs++;
2690 }
2691 break;
2692 case 1:
2693 /* add line-in as surr and mic as clfe */
7b043899 2694 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
c480f79b
TI
2695 cfg->line_out_pins[cfg->line_outs] =
2696 cfg->input_pins[AUTO_PIN_LINE];
403d1944
MP
2697 spec->line_switch = 1;
2698 cfg->line_outs++;
2699 }
7b043899 2700 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
c480f79b
TI
2701 cfg->line_out_pins[cfg->line_outs] =
2702 cfg->input_pins[AUTO_PIN_MIC];
403d1944
MP
2703 spec->mic_switch = 1;
2704 cfg->line_outs++;
2705 }
2706 break;
2707 }
2708
2709 return 0;
2710}
2711
7b043899
SL
2712
2713static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2714{
2715 int i;
2716
2717 for (i = 0; i < spec->multiout.num_dacs; i++) {
2718 if (spec->multiout.dac_nids[i] == nid)
2719 return 1;
2720 }
2721
2722 return 0;
2723}
2724
3cc08dc6 2725/*
7b043899
SL
2726 * Fill in the dac_nids table from the parsed pin configuration
2727 * This function only works when every pin in line_out_pins[]
2728 * contains atleast one DAC in its connection list. Some 92xx
2729 * codecs are not connected directly to a DAC, such as the 9200
2730 * and 9202/925x. For those, dac_nids[] must be hard-coded.
3cc08dc6 2731 */
19039bd0 2732static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
df802952 2733 struct auto_pin_cfg *cfg)
c7d4b2fa
M
2734{
2735 struct sigmatel_spec *spec = codec->spec;
7b043899
SL
2736 int i, j, conn_len = 0;
2737 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
2738 unsigned int wcaps, wtype;
2739
c7d4b2fa
M
2740 for (i = 0; i < cfg->line_outs; i++) {
2741 nid = cfg->line_out_pins[i];
7b043899
SL
2742 conn_len = snd_hda_get_connections(codec, nid, conn,
2743 HDA_MAX_CONNECTIONS);
2744 for (j = 0; j < conn_len; j++) {
2745 wcaps = snd_hda_param_read(codec, conn[j],
2746 AC_PAR_AUDIO_WIDGET_CAP);
2747 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7b043899
SL
2748 if (wtype != AC_WID_AUD_OUT ||
2749 (wcaps & AC_WCAP_DIGITAL))
2750 continue;
2751 /* conn[j] is a DAC routed to this line-out */
2752 if (!is_in_dac_nids(spec, conn[j]))
2753 break;
2754 }
2755
2756 if (j == conn_len) {
df802952
TI
2757 if (spec->multiout.num_dacs > 0) {
2758 /* we have already working output pins,
2759 * so let's drop the broken ones again
2760 */
2761 cfg->line_outs = spec->multiout.num_dacs;
2762 break;
2763 }
7b043899
SL
2764 /* error out, no available DAC found */
2765 snd_printk(KERN_ERR
2766 "%s: No available DAC for pin 0x%x\n",
2767 __func__, nid);
2768 return -ENODEV;
2769 }
2770
2771 spec->multiout.dac_nids[i] = conn[j];
2772 spec->multiout.num_dacs++;
2773 if (conn_len > 1) {
2774 /* select this DAC in the pin's input mux */
82beb8fd
TI
2775 snd_hda_codec_write_cache(codec, nid, 0,
2776 AC_VERB_SET_CONNECT_SEL, j);
c7d4b2fa 2777
7b043899
SL
2778 }
2779 }
c7d4b2fa 2780
7b043899
SL
2781 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2782 spec->multiout.num_dacs,
2783 spec->multiout.dac_nids[0],
2784 spec->multiout.dac_nids[1],
2785 spec->multiout.dac_nids[2],
2786 spec->multiout.dac_nids[3],
2787 spec->multiout.dac_nids[4]);
c7d4b2fa
M
2788 return 0;
2789}
2790
eb06ed8f
TI
2791/* create volume control/switch for the given prefx type */
2792static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
2793{
2794 char name[32];
2795 int err;
2796
2797 sprintf(name, "%s Playback Volume", pfx);
2798 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
2799 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2800 if (err < 0)
2801 return err;
2802 sprintf(name, "%s Playback Switch", pfx);
2803 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
2804 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2805 if (err < 0)
2806 return err;
2807 return 0;
2808}
2809
ae0afd81
MR
2810static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2811{
2812 if (!spec->multiout.hp_nid)
2813 spec->multiout.hp_nid = nid;
2814 else if (spec->multiout.num_dacs > 4) {
2815 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2816 return 1;
2817 } else {
2818 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
2819 spec->multiout.num_dacs++;
2820 }
2821 return 0;
2822}
2823
2824static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2825{
2826 if (is_in_dac_nids(spec, nid))
2827 return 1;
2828 if (spec->multiout.hp_nid == nid)
2829 return 1;
2830 return 0;
2831}
2832
c7d4b2fa 2833/* add playback controls from the parsed DAC table */
0fb87bb4 2834static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
19039bd0 2835 const struct auto_pin_cfg *cfg)
c7d4b2fa 2836{
19039bd0
TI
2837 static const char *chname[4] = {
2838 "Front", "Surround", NULL /*CLFE*/, "Side"
2839 };
d21995e3 2840 hda_nid_t nid = 0;
c7d4b2fa
M
2841 int i, err;
2842
0fb87bb4 2843 struct sigmatel_spec *spec = codec->spec;
b5895dc8 2844 unsigned int wid_caps, pincap;
0fb87bb4
ML
2845
2846
40ac8c4f 2847 for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
403d1944 2848 if (!spec->multiout.dac_nids[i])
c7d4b2fa
M
2849 continue;
2850
2851 nid = spec->multiout.dac_nids[i];
2852
2853 if (i == 2) {
2854 /* Center/LFE */
eb06ed8f
TI
2855 err = create_controls(spec, "Center", nid, 1);
2856 if (err < 0)
c7d4b2fa 2857 return err;
eb06ed8f
TI
2858 err = create_controls(spec, "LFE", nid, 2);
2859 if (err < 0)
c7d4b2fa 2860 return err;
0fb87bb4
ML
2861
2862 wid_caps = get_wcaps(codec, nid);
2863
2864 if (wid_caps & AC_WCAP_LR_SWAP) {
2865 err = stac92xx_add_control(spec,
2866 STAC_CTL_WIDGET_CLFE_SWITCH,
2867 "Swap Center/LFE Playback Switch", nid);
2868
2869 if (err < 0)
2870 return err;
2871 }
2872
c7d4b2fa 2873 } else {
eb06ed8f
TI
2874 err = create_controls(spec, chname[i], nid, 3);
2875 if (err < 0)
c7d4b2fa
M
2876 return err;
2877 }
2878 }
2879
fedb7569
MR
2880 if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
2881 cfg->hp_outs && !spec->multiout.hp_nid)
2882 spec->multiout.hp_nid = nid;
2883
7c2ba97b
MR
2884 if (cfg->hp_outs > 1) {
2885 err = stac92xx_add_control(spec,
2886 STAC_CTL_WIDGET_HP_SWITCH,
d7a89436
TI
2887 "Headphone as Line Out Switch",
2888 cfg->hp_pins[cfg->hp_outs - 1]);
7c2ba97b
MR
2889 if (err < 0)
2890 return err;
2891 }
2892
b5895dc8
MR
2893 if (spec->line_switch) {
2894 nid = cfg->input_pins[AUTO_PIN_LINE];
2895 pincap = snd_hda_param_read(codec, nid,
2896 AC_PAR_PIN_CAP);
2897 if (pincap & AC_PINCAP_OUT) {
2898 err = stac92xx_add_control(spec,
2899 STAC_CTL_WIDGET_IO_SWITCH,
2900 "Line In as Output Switch", nid << 8);
2901 if (err < 0)
2902 return err;
2903 }
2904 }
403d1944 2905
b5895dc8 2906 if (spec->mic_switch) {
cace16f1 2907 unsigned int def_conf;
ae0afd81
MR
2908 unsigned int mic_pin = AUTO_PIN_MIC;
2909again:
2910 nid = cfg->input_pins[mic_pin];
cace16f1
MR
2911 def_conf = snd_hda_codec_read(codec, nid, 0,
2912 AC_VERB_GET_CONFIG_DEFAULT, 0);
cace16f1
MR
2913 /* some laptops have an internal analog microphone
2914 * which can't be used as a output */
2915 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2916 pincap = snd_hda_param_read(codec, nid,
2917 AC_PAR_PIN_CAP);
2918 if (pincap & AC_PINCAP_OUT) {
2919 err = stac92xx_add_control(spec,
2920 STAC_CTL_WIDGET_IO_SWITCH,
2921 "Mic as Output Switch", (nid << 8) | 1);
ae0afd81
MR
2922 nid = snd_hda_codec_read(codec, nid, 0,
2923 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2924 if (!check_in_dac_nids(spec, nid))
2925 add_spec_dacs(spec, nid);
cace16f1
MR
2926 if (err < 0)
2927 return err;
2928 }
ae0afd81
MR
2929 } else if (mic_pin == AUTO_PIN_MIC) {
2930 mic_pin = AUTO_PIN_FRONT_MIC;
2931 goto again;
b5895dc8
MR
2932 }
2933 }
403d1944 2934
c7d4b2fa
M
2935 return 0;
2936}
2937
eb06ed8f
TI
2938/* add playback controls for Speaker and HP outputs */
2939static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2940 struct auto_pin_cfg *cfg)
2941{
2942 struct sigmatel_spec *spec = codec->spec;
2943 hda_nid_t nid;
2944 int i, old_num_dacs, err;
2945
2946 old_num_dacs = spec->multiout.num_dacs;
2947 for (i = 0; i < cfg->hp_outs; i++) {
2948 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
2949 if (wid_caps & AC_WCAP_UNSOL_CAP)
2950 spec->hp_detect = 1;
2951 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
2952 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2953 if (check_in_dac_nids(spec, nid))
2954 nid = 0;
2955 if (! nid)
c7d4b2fa 2956 continue;
eb06ed8f
TI
2957 add_spec_dacs(spec, nid);
2958 }
2959 for (i = 0; i < cfg->speaker_outs; i++) {
7b043899 2960 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
eb06ed8f
TI
2961 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2962 if (check_in_dac_nids(spec, nid))
2963 nid = 0;
eb06ed8f
TI
2964 if (! nid)
2965 continue;
2966 add_spec_dacs(spec, nid);
c7d4b2fa 2967 }
1b290a51
MR
2968 for (i = 0; i < cfg->line_outs; i++) {
2969 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
2970 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2971 if (check_in_dac_nids(spec, nid))
2972 nid = 0;
2973 if (! nid)
2974 continue;
2975 add_spec_dacs(spec, nid);
2976 }
eb06ed8f
TI
2977 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
2978 static const char *pfxs[] = {
2979 "Speaker", "External Speaker", "Speaker2",
2980 };
2981 err = create_controls(spec, pfxs[i - old_num_dacs],
2982 spec->multiout.dac_nids[i], 3);
2983 if (err < 0)
2984 return err;
2985 }
2986 if (spec->multiout.hp_nid) {
2626a263
TI
2987 err = create_controls(spec, "Headphone",
2988 spec->multiout.hp_nid, 3);
eb06ed8f
TI
2989 if (err < 0)
2990 return err;
2991 }
c7d4b2fa
M
2992
2993 return 0;
2994}
2995
b22b4821 2996/* labels for mono mux outputs */
d0513fc6
MR
2997static const char *stac92xx_mono_labels[4] = {
2998 "DAC0", "DAC1", "Mixer", "DAC2"
b22b4821
MR
2999};
3000
3001/* create mono mux for mono out on capable codecs */
3002static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3003{
3004 struct sigmatel_spec *spec = codec->spec;
3005 struct hda_input_mux *mono_mux = &spec->private_mono_mux;
3006 int i, num_cons;
3007 hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)];
3008
3009 num_cons = snd_hda_get_connections(codec,
3010 spec->mono_nid,
3011 con_lst,
3012 HDA_MAX_NUM_INPUTS);
3013 if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
3014 return -EINVAL;
3015
3016 for (i = 0; i < num_cons; i++) {
3017 mono_mux->items[mono_mux->num_items].label =
3018 stac92xx_mono_labels[i];
3019 mono_mux->items[mono_mux->num_items].index = i;
3020 mono_mux->num_items++;
3021 }
09a99959
MR
3022
3023 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
3024 "Mono Mux", spec->mono_nid);
b22b4821
MR
3025}
3026
89385035
MR
3027/* labels for amp mux outputs */
3028static const char *stac92xx_amp_labels[3] = {
4b33c767 3029 "Front Microphone", "Microphone", "Line In",
89385035
MR
3030};
3031
3032/* create amp out controls mux on capable codecs */
3033static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec)
3034{
3035 struct sigmatel_spec *spec = codec->spec;
3036 struct hda_input_mux *amp_mux = &spec->private_amp_mux;
3037 int i, err;
3038
2a9c7816 3039 for (i = 0; i < spec->num_amps; i++) {
89385035
MR
3040 amp_mux->items[amp_mux->num_items].label =
3041 stac92xx_amp_labels[i];
3042 amp_mux->items[amp_mux->num_items].index = i;
3043 amp_mux->num_items++;
3044 }
3045
2a9c7816
MR
3046 if (spec->num_amps > 1) {
3047 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX,
3048 "Amp Selector Capture Switch", 0);
3049 if (err < 0)
3050 return err;
3051 }
89385035
MR
3052 return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL,
3053 "Amp Capture Volume",
3054 HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT));
3055}
3056
3057
1cd2224c
MR
3058/* create PC beep volume controls */
3059static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3060 hda_nid_t nid)
3061{
3062 struct sigmatel_spec *spec = codec->spec;
3063 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3064 int err;
3065
3066 /* check for mute support for the the amp */
3067 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
3068 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
3069 "PC Beep Playback Switch",
3070 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
3071 if (err < 0)
3072 return err;
3073 }
3074
3075 /* check to see if there is volume support for the amp */
3076 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
3077 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
3078 "PC Beep Playback Volume",
3079 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
3080 if (err < 0)
3081 return err;
3082 }
3083 return 0;
3084}
3085
4d4e9bb3
TI
3086#ifdef CONFIG_SND_HDA_INPUT_BEEP
3087#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
3088
3089static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
3090 struct snd_ctl_elem_value *ucontrol)
3091{
3092 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3093 ucontrol->value.integer.value[0] = codec->beep->enabled;
3094 return 0;
3095}
3096
3097static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
3098 struct snd_ctl_elem_value *ucontrol)
3099{
3100 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3101 int enabled = !!ucontrol->value.integer.value[0];
3102 if (codec->beep->enabled != enabled) {
3103 codec->beep->enabled = enabled;
3104 return 1;
3105 }
3106 return 0;
3107}
3108
3109static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
3110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3111 .info = stac92xx_dig_beep_switch_info,
3112 .get = stac92xx_dig_beep_switch_get,
3113 .put = stac92xx_dig_beep_switch_put,
3114};
3115
3116static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
3117{
3118 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
3119 0, "PC Beep Playback Switch", 0);
3120}
3121#endif
3122
4682eee0
MR
3123static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3124{
3125 struct sigmatel_spec *spec = codec->spec;
3126 int wcaps, nid, i, err = 0;
3127
3128 for (i = 0; i < spec->num_muxes; i++) {
3129 nid = spec->mux_nids[i];
3130 wcaps = get_wcaps(codec, nid);
3131
3132 if (wcaps & AC_WCAP_OUT_AMP) {
3133 err = stac92xx_add_control_idx(spec,
3134 STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume",
3135 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3136 if (err < 0)
3137 return err;
3138 }
3139 }
3140 return 0;
3141};
3142
d9737751 3143static const char *stac92xx_spdif_labels[3] = {
65973632 3144 "Digital Playback", "Analog Mux 1", "Analog Mux 2",
d9737751
MR
3145};
3146
3147static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3148{
3149 struct sigmatel_spec *spec = codec->spec;
3150 struct hda_input_mux *spdif_mux = &spec->private_smux;
65973632 3151 const char **labels = spec->spdif_labels;
d9737751 3152 int i, num_cons;
65973632 3153 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
d9737751
MR
3154
3155 num_cons = snd_hda_get_connections(codec,
3156 spec->smux_nids[0],
3157 con_lst,
3158 HDA_MAX_NUM_INPUTS);
65973632 3159 if (!num_cons)
d9737751
MR
3160 return -EINVAL;
3161
65973632
MR
3162 if (!labels)
3163 labels = stac92xx_spdif_labels;
3164
d9737751 3165 for (i = 0; i < num_cons; i++) {
65973632 3166 spdif_mux->items[spdif_mux->num_items].label = labels[i];
d9737751
MR
3167 spdif_mux->items[spdif_mux->num_items].index = i;
3168 spdif_mux->num_items++;
3169 }
3170
3171 return 0;
3172}
3173
8b65727b 3174/* labels for dmic mux inputs */
ddc2cec4 3175static const char *stac92xx_dmic_labels[5] = {
8b65727b
MP
3176 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
3177 "Digital Mic 3", "Digital Mic 4"
3178};
3179
3180/* create playback/capture controls for input pins on dmic capable codecs */
3181static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3182 const struct auto_pin_cfg *cfg)
3183{
3184 struct sigmatel_spec *spec = codec->spec;
3185 struct hda_input_mux *dimux = &spec->private_dimux;
3186 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
0678accd
MR
3187 int err, i, j;
3188 char name[32];
8b65727b
MP
3189
3190 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
3191 dimux->items[dimux->num_items].index = 0;
3192 dimux->num_items++;
3193
3194 for (i = 0; i < spec->num_dmics; i++) {
0678accd 3195 hda_nid_t nid;
8b65727b
MP
3196 int index;
3197 int num_cons;
0678accd 3198 unsigned int wcaps;
8b65727b
MP
3199 unsigned int def_conf;
3200
3201 def_conf = snd_hda_codec_read(codec,
3202 spec->dmic_nids[i],
3203 0,
3204 AC_VERB_GET_CONFIG_DEFAULT,
3205 0);
3206 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
3207 continue;
3208
0678accd 3209 nid = spec->dmic_nids[i];
8b65727b 3210 num_cons = snd_hda_get_connections(codec,
e1f0d669 3211 spec->dmux_nids[0],
8b65727b
MP
3212 con_lst,
3213 HDA_MAX_NUM_INPUTS);
3214 for (j = 0; j < num_cons; j++)
0678accd 3215 if (con_lst[j] == nid) {
8b65727b
MP
3216 index = j;
3217 goto found;
3218 }
3219 continue;
3220found:
d0513fc6
MR
3221 wcaps = get_wcaps(codec, nid) &
3222 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
0678accd 3223
d0513fc6 3224 if (wcaps) {
0678accd
MR
3225 sprintf(name, "%s Capture Volume",
3226 stac92xx_dmic_labels[dimux->num_items]);
3227
3228 err = stac92xx_add_control(spec,
3229 STAC_CTL_WIDGET_VOL,
3230 name,
d0513fc6
MR
3231 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3232 (wcaps & AC_WCAP_OUT_AMP) ?
3233 HDA_OUTPUT : HDA_INPUT));
0678accd
MR
3234 if (err < 0)
3235 return err;
3236 }
3237
8b65727b
MP
3238 dimux->items[dimux->num_items].label =
3239 stac92xx_dmic_labels[dimux->num_items];
3240 dimux->items[dimux->num_items].index = index;
3241 dimux->num_items++;
3242 }
3243
3244 return 0;
3245}
3246
c7d4b2fa
M
3247/* create playback/capture controls for input pins */
3248static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
3249{
3250 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa
M
3251 struct hda_input_mux *imux = &spec->private_imux;
3252 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
3253 int i, j, k;
3254
3255 for (i = 0; i < AUTO_PIN_LAST; i++) {
314634bc
TI
3256 int index;
3257
3258 if (!cfg->input_pins[i])
3259 continue;
3260 index = -1;
3261 for (j = 0; j < spec->num_muxes; j++) {
3262 int num_cons;
3263 num_cons = snd_hda_get_connections(codec,
3264 spec->mux_nids[j],
3265 con_lst,
3266 HDA_MAX_NUM_INPUTS);
3267 for (k = 0; k < num_cons; k++)
3268 if (con_lst[k] == cfg->input_pins[i]) {
3269 index = k;
3270 goto found;
3271 }
c7d4b2fa 3272 }
314634bc
TI
3273 continue;
3274 found:
3275 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3276 imux->items[imux->num_items].index = index;
3277 imux->num_items++;
c7d4b2fa
M
3278 }
3279
7b043899 3280 if (imux->num_items) {
62fe78e9
SR
3281 /*
3282 * Set the current input for the muxes.
3283 * The STAC9221 has two input muxes with identical source
3284 * NID lists. Hopefully this won't get confused.
3285 */
3286 for (i = 0; i < spec->num_muxes; i++) {
82beb8fd
TI
3287 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
3288 AC_VERB_SET_CONNECT_SEL,
3289 imux->items[0].index);
62fe78e9
SR
3290 }
3291 }
3292
c7d4b2fa
M
3293 return 0;
3294}
3295
c7d4b2fa
M
3296static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
3297{
3298 struct sigmatel_spec *spec = codec->spec;
3299 int i;
3300
3301 for (i = 0; i < spec->autocfg.line_outs; i++) {
3302 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3303 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
3304 }
3305}
3306
3307static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
3308{
3309 struct sigmatel_spec *spec = codec->spec;
eb06ed8f 3310 int i;
c7d4b2fa 3311
eb06ed8f
TI
3312 for (i = 0; i < spec->autocfg.hp_outs; i++) {
3313 hda_nid_t pin;
3314 pin = spec->autocfg.hp_pins[i];
3315 if (pin) /* connect to front */
3316 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
3317 }
3318 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
3319 hda_nid_t pin;
3320 pin = spec->autocfg.speaker_pins[i];
3321 if (pin) /* connect to front */
3322 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
3323 }
c7d4b2fa
M
3324}
3325
3cc08dc6 3326static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
c7d4b2fa
M
3327{
3328 struct sigmatel_spec *spec = codec->spec;
3329 int err;
bcecd9bd 3330 int hp_speaker_swap = 0;
c7d4b2fa 3331
8b65727b
MP
3332 if ((err = snd_hda_parse_pin_def_config(codec,
3333 &spec->autocfg,
3334 spec->dmic_nids)) < 0)
c7d4b2fa 3335 return err;
82bc955f 3336 if (! spec->autocfg.line_outs)
869264c4 3337 return 0; /* can't find valid pin config */
19039bd0 3338
bcecd9bd
JZ
3339 /* If we have no real line-out pin and multiple hp-outs, HPs should
3340 * be set up as multi-channel outputs.
3341 */
3342 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
3343 spec->autocfg.hp_outs > 1) {
3344 /* Copy hp_outs to line_outs, backup line_outs in
3345 * speaker_outs so that the following routines can handle
3346 * HP pins as primary outputs.
3347 */
3348 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
3349 sizeof(spec->autocfg.line_out_pins));
3350 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
3351 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
3352 sizeof(spec->autocfg.hp_pins));
3353 spec->autocfg.line_outs = spec->autocfg.hp_outs;
3354 hp_speaker_swap = 1;
3355 }
09a99959 3356 if (spec->autocfg.mono_out_pin) {
d0513fc6
MR
3357 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
3358 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
09a99959
MR
3359 u32 caps = query_amp_caps(codec,
3360 spec->autocfg.mono_out_pin, dir);
3361 hda_nid_t conn_list[1];
3362
3363 /* get the mixer node and then the mono mux if it exists */
3364 if (snd_hda_get_connections(codec,
3365 spec->autocfg.mono_out_pin, conn_list, 1) &&
3366 snd_hda_get_connections(codec, conn_list[0],
3367 conn_list, 1)) {
3368
3369 int wcaps = get_wcaps(codec, conn_list[0]);
3370 int wid_type = (wcaps & AC_WCAP_TYPE)
3371 >> AC_WCAP_TYPE_SHIFT;
3372 /* LR swap check, some stac925x have a mux that
3373 * changes the DACs output path instead of the
3374 * mono-mux path.
3375 */
3376 if (wid_type == AC_WID_AUD_SEL &&
3377 !(wcaps & AC_WCAP_LR_SWAP))
3378 spec->mono_nid = conn_list[0];
3379 }
d0513fc6
MR
3380 if (dir) {
3381 hda_nid_t nid = spec->autocfg.mono_out_pin;
3382
3383 /* most mono outs have a least a mute/unmute switch */
3384 dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
3385 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
3386 "Mono Playback Switch",
3387 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
09a99959
MR
3388 if (err < 0)
3389 return err;
d0513fc6
MR
3390 /* check for volume support for the amp */
3391 if ((caps & AC_AMPCAP_NUM_STEPS)
3392 >> AC_AMPCAP_NUM_STEPS_SHIFT) {
3393 err = stac92xx_add_control(spec,
3394 STAC_CTL_WIDGET_VOL,
3395 "Mono Playback Volume",
3396 HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
3397 if (err < 0)
3398 return err;
3399 }
09a99959
MR
3400 }
3401
3402 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
3403 AC_PINCTL_OUT_EN);
3404 }
bcecd9bd 3405
403d1944
MP
3406 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
3407 return err;
19039bd0
TI
3408 if (spec->multiout.num_dacs == 0)
3409 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3410 return err;
c7d4b2fa 3411
0fb87bb4
ML
3412 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
3413
3414 if (err < 0)
3415 return err;
3416
1cd2224c
MR
3417 /* setup analog beep controls */
3418 if (spec->anabeep_nid > 0) {
3419 err = stac92xx_auto_create_beep_ctls(codec,
3420 spec->anabeep_nid);
3421 if (err < 0)
3422 return err;
3423 }
3424
3425 /* setup digital beep controls and input device */
3426#ifdef CONFIG_SND_HDA_INPUT_BEEP
3427 if (spec->digbeep_nid > 0) {
3428 hda_nid_t nid = spec->digbeep_nid;
4d4e9bb3 3429 unsigned int caps;
1cd2224c
MR
3430
3431 err = stac92xx_auto_create_beep_ctls(codec, nid);
3432 if (err < 0)
3433 return err;
3434 err = snd_hda_attach_beep_device(codec, nid);
3435 if (err < 0)
3436 return err;
4d4e9bb3
TI
3437 /* if no beep switch is available, make its own one */
3438 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3439 if (codec->beep &&
3440 !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) {
3441 err = stac92xx_beep_switch_ctl(codec);
3442 if (err < 0)
3443 return err;
3444 }
1cd2224c
MR
3445 }
3446#endif
3447
bcecd9bd
JZ
3448 if (hp_speaker_swap == 1) {
3449 /* Restore the hp_outs and line_outs */
3450 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
3451 sizeof(spec->autocfg.line_out_pins));
3452 spec->autocfg.hp_outs = spec->autocfg.line_outs;
3453 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
3454 sizeof(spec->autocfg.speaker_pins));
3455 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
3456 memset(spec->autocfg.speaker_pins, 0,
3457 sizeof(spec->autocfg.speaker_pins));
3458 spec->autocfg.speaker_outs = 0;
3459 }
3460
0fb87bb4
ML
3461 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
3462
3463 if (err < 0)
3464 return err;
3465
3466 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
3467
3468 if (err < 0)
c7d4b2fa
M
3469 return err;
3470
b22b4821
MR
3471 if (spec->mono_nid > 0) {
3472 err = stac92xx_auto_create_mono_output_ctls(codec);
3473 if (err < 0)
3474 return err;
3475 }
2a9c7816 3476 if (spec->num_amps > 0) {
89385035
MR
3477 err = stac92xx_auto_create_amp_output_ctls(codec);
3478 if (err < 0)
3479 return err;
3480 }
2a9c7816 3481 if (spec->num_dmics > 0 && !spec->dinput_mux)
8b65727b
MP
3482 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
3483 &spec->autocfg)) < 0)
3484 return err;
4682eee0
MR
3485 if (spec->num_muxes > 0) {
3486 err = stac92xx_auto_create_mux_input_ctls(codec);
3487 if (err < 0)
3488 return err;
3489 }
d9737751
MR
3490 if (spec->num_smuxes > 0) {
3491 err = stac92xx_auto_create_spdif_mux_ctls(codec);
3492 if (err < 0)
3493 return err;
3494 }
8b65727b 3495
c7d4b2fa 3496 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
403d1944 3497 if (spec->multiout.max_channels > 2)
c7d4b2fa 3498 spec->surr_switch = 1;
c7d4b2fa 3499
82bc955f 3500 if (spec->autocfg.dig_out_pin)
3cc08dc6 3501 spec->multiout.dig_out_nid = dig_out;
d0513fc6 3502 if (dig_in && spec->autocfg.dig_in_pin)
3cc08dc6 3503 spec->dig_in_nid = dig_in;
c7d4b2fa 3504
603c4019
TI
3505 if (spec->kctls.list)
3506 spec->mixers[spec->num_mixers++] = spec->kctls.list;
c7d4b2fa
M
3507
3508 spec->input_mux = &spec->private_imux;
2a9c7816 3509 spec->dinput_mux = &spec->private_dimux;
d9737751 3510 spec->sinput_mux = &spec->private_smux;
b22b4821 3511 spec->mono_mux = &spec->private_mono_mux;
89385035 3512 spec->amp_mux = &spec->private_amp_mux;
c7d4b2fa
M
3513 return 1;
3514}
3515
82bc955f
TI
3516/* add playback controls for HP output */
3517static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
3518 struct auto_pin_cfg *cfg)
3519{
3520 struct sigmatel_spec *spec = codec->spec;
eb06ed8f 3521 hda_nid_t pin = cfg->hp_pins[0];
82bc955f
TI
3522 unsigned int wid_caps;
3523
3524 if (! pin)
3525 return 0;
3526
3527 wid_caps = get_wcaps(codec, pin);
505cb341 3528 if (wid_caps & AC_WCAP_UNSOL_CAP)
82bc955f 3529 spec->hp_detect = 1;
82bc955f
TI
3530
3531 return 0;
3532}
3533
160ea0dc
RF
3534/* add playback controls for LFE output */
3535static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
3536 struct auto_pin_cfg *cfg)
3537{
3538 struct sigmatel_spec *spec = codec->spec;
3539 int err;
3540 hda_nid_t lfe_pin = 0x0;
3541 int i;
3542
3543 /*
3544 * search speaker outs and line outs for a mono speaker pin
3545 * with an amp. If one is found, add LFE controls
3546 * for it.
3547 */
3548 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
3549 hda_nid_t pin = spec->autocfg.speaker_pins[i];
64ed0dfd 3550 unsigned int wcaps = get_wcaps(codec, pin);
160ea0dc
RF
3551 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
3552 if (wcaps == AC_WCAP_OUT_AMP)
3553 /* found a mono speaker with an amp, must be lfe */
3554 lfe_pin = pin;
3555 }
3556
3557 /* if speaker_outs is 0, then speakers may be in line_outs */
3558 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
3559 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
3560 hda_nid_t pin = spec->autocfg.line_out_pins[i];
64ed0dfd 3561 unsigned int defcfg;
8b551785 3562 defcfg = snd_hda_codec_read(codec, pin, 0,
160ea0dc
RF
3563 AC_VERB_GET_CONFIG_DEFAULT,
3564 0x00);
8b551785 3565 if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
64ed0dfd 3566 unsigned int wcaps = get_wcaps(codec, pin);
160ea0dc
RF
3567 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
3568 if (wcaps == AC_WCAP_OUT_AMP)
3569 /* found a mono speaker with an amp,
3570 must be lfe */
3571 lfe_pin = pin;
3572 }
3573 }
3574 }
3575
3576 if (lfe_pin) {
eb06ed8f 3577 err = create_controls(spec, "LFE", lfe_pin, 1);
160ea0dc
RF
3578 if (err < 0)
3579 return err;
3580 }
3581
3582 return 0;
3583}
3584
c7d4b2fa
M
3585static int stac9200_parse_auto_config(struct hda_codec *codec)
3586{
3587 struct sigmatel_spec *spec = codec->spec;
3588 int err;
3589
df694daa 3590 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
c7d4b2fa
M
3591 return err;
3592
3593 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
3594 return err;
3595
82bc955f
TI
3596 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
3597 return err;
3598
160ea0dc
RF
3599 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
3600 return err;
3601
355a0ec4
TI
3602 if (spec->num_muxes > 0) {
3603 err = stac92xx_auto_create_mux_input_ctls(codec);
3604 if (err < 0)
3605 return err;
3606 }
3607
82bc955f 3608 if (spec->autocfg.dig_out_pin)
c7d4b2fa 3609 spec->multiout.dig_out_nid = 0x05;
82bc955f 3610 if (spec->autocfg.dig_in_pin)
c7d4b2fa 3611 spec->dig_in_nid = 0x04;
c7d4b2fa 3612
603c4019
TI
3613 if (spec->kctls.list)
3614 spec->mixers[spec->num_mixers++] = spec->kctls.list;
c7d4b2fa
M
3615
3616 spec->input_mux = &spec->private_imux;
8b65727b 3617 spec->dinput_mux = &spec->private_dimux;
c7d4b2fa
M
3618
3619 return 1;
3620}
3621
62fe78e9
SR
3622/*
3623 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
3624 * funky external mute control using GPIO pins.
3625 */
3626
76e1ddfb 3627static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4fe5195c 3628 unsigned int dir_mask, unsigned int data)
62fe78e9
SR
3629{
3630 unsigned int gpiostate, gpiomask, gpiodir;
3631
3632 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
3633 AC_VERB_GET_GPIO_DATA, 0);
4fe5195c 3634 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
62fe78e9
SR
3635
3636 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
3637 AC_VERB_GET_GPIO_MASK, 0);
76e1ddfb 3638 gpiomask |= mask;
62fe78e9
SR
3639
3640 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
3641 AC_VERB_GET_GPIO_DIRECTION, 0);
4fe5195c 3642 gpiodir |= dir_mask;
62fe78e9 3643
76e1ddfb 3644 /* Configure GPIOx as CMOS */
62fe78e9
SR
3645 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
3646
3647 snd_hda_codec_write(codec, codec->afg, 0,
3648 AC_VERB_SET_GPIO_MASK, gpiomask);
76e1ddfb
TI
3649 snd_hda_codec_read(codec, codec->afg, 0,
3650 AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
62fe78e9
SR
3651
3652 msleep(1);
3653
76e1ddfb
TI
3654 snd_hda_codec_read(codec, codec->afg, 0,
3655 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
62fe78e9
SR
3656}
3657
74aeaabc
MR
3658static int stac92xx_add_jack(struct hda_codec *codec,
3659 hda_nid_t nid, int type)
3660{
3661 struct sigmatel_spec *spec = codec->spec;
3662 struct sigmatel_jack *jack;
3663 int def_conf = snd_hda_codec_read(codec, nid,
3664 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
3665 int connectivity = get_defcfg_connect(def_conf);
3666 char name[32];
3667
3668 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
3669 return 0;
3670
3671 snd_array_init(&spec->jacks, sizeof(*jack), 32);
3672 jack = snd_array_new(&spec->jacks);
3673 if (!jack)
3674 return -ENOMEM;
3675 jack->nid = nid;
3676 jack->type = type;
3677
3678 sprintf(name, "%s at %s %s Jack",
3679 snd_hda_get_jack_type(def_conf),
3680 snd_hda_get_jack_connectivity(def_conf),
3681 snd_hda_get_jack_location(def_conf));
3682
3683 return snd_jack_new(codec->bus->card, name, type, &jack->jack);
3684}
3685
3686static int stac92xx_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
3687 int data)
3688{
3689 struct sigmatel_event *event;
3690
3691 snd_array_init(&spec->events, sizeof(*event), 32);
3692 event = snd_array_new(&spec->events);
3693 if (!event)
3694 return -ENOMEM;
3695 event->nid = nid;
3696 event->data = data;
3697
3698 return 0;
3699}
3700
3701static int stac92xx_event_data(struct hda_codec *codec, hda_nid_t nid)
3702{
3703 struct sigmatel_spec *spec = codec->spec;
3704 struct sigmatel_event *events = spec->events.list;
3705 if (events) {
3706 int i;
3707 for (i = 0; i < spec->events.used; i++)
3708 if (events[i].nid == nid)
3709 return events[i].data;
3710 }
3711 return 0;
3712}
3713
314634bc
TI
3714static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
3715 unsigned int event)
3716{
74aeaabc 3717 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
dc81bed1
TI
3718 snd_hda_codec_write_cache(codec, nid, 0,
3719 AC_VERB_SET_UNSOLICITED_ENABLE,
74aeaabc
MR
3720 (AC_USRSP_EN | event | nid));
3721 }
314634bc
TI
3722}
3723
a64135a2
MR
3724static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
3725{
3726 int i;
3727 for (i = 0; i < cfg->hp_outs; i++)
3728 if (cfg->hp_pins[i] == nid)
3729 return 1; /* nid is a HP-Out */
3730
3731 return 0; /* nid is not a HP-Out */
3732};
3733
b76c850f
MR
3734static void stac92xx_power_down(struct hda_codec *codec)
3735{
3736 struct sigmatel_spec *spec = codec->spec;
3737
3738 /* power down inactive DACs */
3739 hda_nid_t *dac;
3740 for (dac = spec->dac_list; *dac; dac++)
4451089e
MR
3741 if (!is_in_dac_nids(spec, *dac) &&
3742 spec->multiout.hp_nid != *dac)
b76c850f
MR
3743 snd_hda_codec_write_cache(codec, *dac, 0,
3744 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3745}
3746
c7d4b2fa
M
3747static int stac92xx_init(struct hda_codec *codec)
3748{
3749 struct sigmatel_spec *spec = codec->spec;
82bc955f 3750 struct auto_pin_cfg *cfg = &spec->autocfg;
45a6ac16 3751 int i, err;
c7d4b2fa 3752
c7d4b2fa
M
3753 snd_hda_sequence_write(codec, spec->init);
3754
8daaaa97
MR
3755 /* power down adcs initially */
3756 if (spec->powerdown_adcs)
3757 for (i = 0; i < spec->num_adcs; i++)
3758 snd_hda_codec_write_cache(codec,
3759 spec->adc_nids[i], 0,
3760 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
82bc955f
TI
3761 /* set up pins */
3762 if (spec->hp_detect) {
505cb341 3763 /* Enable unsolicited responses on the HP widget */
74aeaabc
MR
3764 for (i = 0; i < cfg->hp_outs; i++) {
3765 int type = SND_JACK_HEADPHONE;
3766 hda_nid_t nid = cfg->hp_pins[i];
3767 enable_pin_detect(codec, nid, STAC_HP_EVENT | nid);
3768 /* jack detection */
3769 if (cfg->hp_outs == i)
3770 type |= SND_JACK_LINEOUT;
3771 err = stac92xx_add_jack(codec, nid, type);
3772 if (err < 0)
3773 return err;
3774
3775 }
0a07acaf
TI
3776 /* force to enable the first line-out; the others are set up
3777 * in unsol_event
3778 */
3779 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
74aeaabc 3780 AC_PINCTL_OUT_EN);
82bc955f 3781 /* fake event to set up pins */
74aeaabc
MR
3782 codec->patch_ops.unsol_event(codec,
3783 (STAC_HP_EVENT | spec->autocfg.hp_pins[0]) << 26);
82bc955f
TI
3784 } else {
3785 stac92xx_auto_init_multi_out(codec);
3786 stac92xx_auto_init_hp_out(codec);
3787 }
74aeaabc
MR
3788 for (i = 0; i < cfg->line_outs; i++) {
3789 err = stac92xx_add_jack(codec,
3790 cfg->line_out_pins[i], SND_JACK_LINEOUT);
3791 if (err < 0)
3792 return err;
3793 }
82bc955f 3794 for (i = 0; i < AUTO_PIN_LAST; i++) {
c960a03b
TI
3795 hda_nid_t nid = cfg->input_pins[i];
3796 if (nid) {
4f1e6bc3
TI
3797 unsigned int pinctl;
3798 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
3799 /* for mic pins, force to initialize */
3800 pinctl = stac92xx_get_vref(codec, nid);
3801 } else {
3802 pinctl = snd_hda_codec_read(codec, nid, 0,
3803 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3804 /* if PINCTL already set then skip */
3805 if (pinctl & AC_PINCTL_IN_EN)
3806 continue;
3807 }
3808 pinctl |= AC_PINCTL_IN_EN;
c960a03b 3809 stac92xx_auto_set_pinctl(codec, nid, pinctl);
74aeaabc
MR
3810 err = stac92xx_add_jack(codec, nid,
3811 SND_JACK_MICROPHONE);
3812 if (err < 0)
3813 return err;
3814 enable_pin_detect(codec, nid, STAC_INSERT_EVENT | nid);
c960a03b 3815 }
82bc955f 3816 }
a64135a2
MR
3817 for (i = 0; i < spec->num_dmics; i++)
3818 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
3819 AC_PINCTL_IN_EN);
3820 for (i = 0; i < spec->num_pwrs; i++) {
3821 int event = is_nid_hp_pin(cfg, spec->pwr_nids[i])
3822 ? STAC_HP_EVENT : STAC_PWR_EVENT;
3823 int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i],
3824 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
bce6c2b5
MR
3825 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i],
3826 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
aafc4412 3827 def_conf = get_defcfg_connect(def_conf);
a64135a2
MR
3828 /* outputs are only ports capable of power management
3829 * any attempts on powering down a input port cause the
3830 * referenced VREF to act quirky.
3831 */
3832 if (pinctl & AC_PINCTL_IN_EN)
3833 continue;
aafc4412
MR
3834 /* skip any ports that don't have jacks since presence
3835 * detection is useless */
3836 if (def_conf && def_conf != AC_JACK_PORT_FIXED)
bce6c2b5 3837 continue;
a64135a2
MR
3838 enable_pin_detect(codec, spec->pwr_nids[i], event | i);
3839 codec->patch_ops.unsol_event(codec, (event | i) << 26);
3840 }
b76c850f
MR
3841 if (spec->dac_list)
3842 stac92xx_power_down(codec);
82bc955f
TI
3843 if (cfg->dig_out_pin)
3844 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3845 AC_PINCTL_OUT_EN);
3846 if (cfg->dig_in_pin)
3847 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3848 AC_PINCTL_IN_EN);
3849
4fe5195c
MR
3850 stac_gpio_set(codec, spec->gpio_mask,
3851 spec->gpio_dir, spec->gpio_data);
62fe78e9 3852
c7d4b2fa
M
3853 return 0;
3854}
3855
74aeaabc
MR
3856static void stac92xx_free_jacks(struct hda_codec *codec)
3857{
3858 struct sigmatel_spec *spec = codec->spec;
3859 if (spec->jacks.list) {
3860 struct sigmatel_jack *jacks = spec->jacks.list;
3861 int i;
3862 for (i = 0; i < spec->jacks.used; i++)
3863 snd_device_free(codec->bus->card, &jacks[i].jack);
3864 }
3865 snd_array_free(&spec->jacks);
3866}
3867
603c4019
TI
3868static void stac92xx_free_kctls(struct hda_codec *codec)
3869{
3870 struct sigmatel_spec *spec = codec->spec;
3871
3872 if (spec->kctls.list) {
3873 struct snd_kcontrol_new *kctl = spec->kctls.list;
3874 int i;
3875 for (i = 0; i < spec->kctls.used; i++)
3876 kfree(kctl[i].name);
3877 }
3878 snd_array_free(&spec->kctls);
3879}
3880
2f2f4251
M
3881static void stac92xx_free(struct hda_codec *codec)
3882{
c7d4b2fa 3883 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa
M
3884
3885 if (! spec)
3886 return;
3887
11b44bbd
RF
3888 if (spec->bios_pin_configs)
3889 kfree(spec->bios_pin_configs);
74aeaabc
MR
3890 stac92xx_free_jacks(codec);
3891 snd_array_free(&spec->events);
11b44bbd 3892
c7d4b2fa 3893 kfree(spec);
1cd2224c 3894 snd_hda_detach_beep_device(codec);
2f2f4251
M
3895}
3896
4e55096e
M
3897static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
3898 unsigned int flag)
3899{
3900 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
3901 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
7b043899 3902
f9acba43
TI
3903 if (pin_ctl & AC_PINCTL_IN_EN) {
3904 /*
3905 * we need to check the current set-up direction of
3906 * shared input pins since they can be switched via
3907 * "xxx as Output" mixer switch
3908 */
3909 struct sigmatel_spec *spec = codec->spec;
3910 struct auto_pin_cfg *cfg = &spec->autocfg;
3911 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
3912 spec->line_switch) ||
3913 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
3914 spec->mic_switch))
3915 return;
3916 }
3917
7b043899
SL
3918 /* if setting pin direction bits, clear the current
3919 direction bits first */
3920 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
3921 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
3922
82beb8fd 3923 snd_hda_codec_write_cache(codec, nid, 0,
4e55096e
M
3924 AC_VERB_SET_PIN_WIDGET_CONTROL,
3925 pin_ctl | flag);
3926}
3927
3928static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
3929 unsigned int flag)
3930{
3931 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
3932 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
82beb8fd 3933 snd_hda_codec_write_cache(codec, nid, 0,
4e55096e
M
3934 AC_VERB_SET_PIN_WIDGET_CONTROL,
3935 pin_ctl & ~flag);
3936}
3937
40c1d308 3938static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
314634bc
TI
3939{
3940 if (!nid)
3941 return 0;
3942 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
40c1d308
JZ
3943 & (1 << 31)) {
3944 unsigned int pinctl;
3945 pinctl = snd_hda_codec_read(codec, nid, 0,
3946 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3947 if (pinctl & AC_PINCTL_IN_EN)
3948 return 0; /* mic- or line-input */
3949 else
3950 return 1; /* HP-output */
3951 }
314634bc
TI
3952 return 0;
3953}
3954
d7a89436
TI
3955/* return non-zero if the hp-pin of the given array index isn't
3956 * a jack-detection target
3957 */
3958static int no_hp_sensing(struct sigmatel_spec *spec, int i)
3959{
3960 struct auto_pin_cfg *cfg = &spec->autocfg;
3961
3962 /* ignore sensing of shared line and mic jacks */
3963 if (spec->line_switch &&
3964 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
3965 return 1;
3966 if (spec->mic_switch &&
3967 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
3968 return 1;
3969 /* ignore if the pin is set as line-out */
3970 if (cfg->hp_pins[i] == spec->hp_switch)
3971 return 1;
3972 return 0;
3973}
3974
314634bc 3975static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
4e55096e
M
3976{
3977 struct sigmatel_spec *spec = codec->spec;
3978 struct auto_pin_cfg *cfg = &spec->autocfg;
3979 int i, presence;
3980
eb06ed8f 3981 presence = 0;
4fe5195c
MR
3982 if (spec->gpio_mute)
3983 presence = !(snd_hda_codec_read(codec, codec->afg, 0,
3984 AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
3985
eb06ed8f 3986 for (i = 0; i < cfg->hp_outs; i++) {
314634bc
TI
3987 if (presence)
3988 break;
d7a89436
TI
3989 if (no_hp_sensing(spec, i))
3990 continue;
4fe5195c 3991 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
eb06ed8f 3992 }
4e55096e
M
3993
3994 if (presence) {
d7a89436 3995 /* disable lineouts */
7c2ba97b 3996 if (spec->hp_switch)
d7a89436
TI
3997 stac92xx_reset_pinctl(codec, spec->hp_switch,
3998 AC_PINCTL_OUT_EN);
4e55096e
M
3999 for (i = 0; i < cfg->line_outs; i++)
4000 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
4001 AC_PINCTL_OUT_EN);
eb06ed8f
TI
4002 for (i = 0; i < cfg->speaker_outs; i++)
4003 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
4004 AC_PINCTL_OUT_EN);
c0cea0d0 4005 if (spec->eapd_mask && spec->eapd_switch)
0fc9dec4
MR
4006 stac_gpio_set(codec, spec->gpio_mask,
4007 spec->gpio_dir, spec->gpio_data &
4008 ~spec->eapd_mask);
4e55096e 4009 } else {
d7a89436 4010 /* enable lineouts */
7c2ba97b 4011 if (spec->hp_switch)
d7a89436
TI
4012 stac92xx_set_pinctl(codec, spec->hp_switch,
4013 AC_PINCTL_OUT_EN);
4e55096e
M
4014 for (i = 0; i < cfg->line_outs; i++)
4015 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
4016 AC_PINCTL_OUT_EN);
eb06ed8f
TI
4017 for (i = 0; i < cfg->speaker_outs; i++)
4018 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
4019 AC_PINCTL_OUT_EN);
c0cea0d0 4020 if (spec->eapd_mask && spec->eapd_switch)
0fc9dec4
MR
4021 stac_gpio_set(codec, spec->gpio_mask,
4022 spec->gpio_dir, spec->gpio_data |
4023 spec->eapd_mask);
4e55096e 4024 }
d7a89436
TI
4025 /* toggle hp outs */
4026 for (i = 0; i < cfg->hp_outs; i++) {
4027 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
4028 if (no_hp_sensing(spec, i))
4029 continue;
4030 if (presence)
4031 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
4032 else
4033 stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
4034 }
4e55096e
M
4035}
4036
a64135a2
MR
4037static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
4038{
4039 struct sigmatel_spec *spec = codec->spec;
4040 hda_nid_t nid = spec->pwr_nids[idx];
4041 int presence, val;
4042 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0)
4043 & 0x000000ff;
4044 presence = get_hp_pin_presence(codec, nid);
d0513fc6
MR
4045
4046 /* several codecs have two power down bits */
4047 if (spec->pwr_mapping)
4048 idx = spec->pwr_mapping[idx];
4049 else
4050 idx = 1 << idx;
a64135a2
MR
4051
4052 if (presence)
4053 val &= ~idx;
4054 else
4055 val |= idx;
4056
4057 /* power down unused output ports */
4058 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
74aeaabc
MR
4059}
4060
4061static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4062{
4063 struct sigmatel_spec *spec = codec->spec;
4064 struct sigmatel_jack *jacks = spec->jacks.list;
4065
4066 if (jacks) {
4067 int i;
4068 for (i = 0; i < spec->jacks.used; i++) {
4069 if (jacks->nid == nid) {
4070 unsigned int pin_ctl =
4071 snd_hda_codec_read(codec, nid,
4072 0, AC_VERB_GET_PIN_WIDGET_CONTROL,
4073 0x00);
4074 int type = jacks->type;
4075 if (type == (SND_JACK_LINEOUT
4076 | SND_JACK_HEADPHONE))
4077 type = (pin_ctl & AC_PINCTL_HP_EN)
4078 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
4079 snd_jack_report(jacks->jack,
4080 get_hp_pin_presence(codec, nid)
4081 ? type : 0);
4082 }
4083 jacks++;
4084 }
4085 }
4086}
a64135a2 4087
314634bc
TI
4088static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4089{
a64135a2 4090 struct sigmatel_spec *spec = codec->spec;
74aeaabc
MR
4091 int event = (res >> 26) & 0x70;
4092 int nid = res >> 26 & 0x0f;
a64135a2 4093
74aeaabc 4094 switch (event) {
314634bc
TI
4095 case STAC_HP_EVENT:
4096 stac92xx_hp_detect(codec, res);
a64135a2 4097 /* fallthru */
74aeaabc 4098 case STAC_INSERT_EVENT:
a64135a2 4099 case STAC_PWR_EVENT:
74aeaabc
MR
4100 if (nid) {
4101 if (spec->num_pwrs > 0)
4102 stac92xx_pin_sense(codec, nid);
4103 stac92xx_report_jack(codec, nid);
4104 }
72474be6
MR
4105 break;
4106 case STAC_VREF_EVENT: {
4107 int data = snd_hda_codec_read(codec, codec->afg, 0,
4108 AC_VERB_GET_GPIO_DATA, 0);
74aeaabc 4109 int idx = stac92xx_event_data(codec, nid);
72474be6
MR
4110 /* toggle VREF state based on GPIOx status */
4111 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
4112 !!(data & (1 << idx)));
4113 break;
4114 }
314634bc
TI
4115 }
4116}
4117
cb53c626 4118#ifdef SND_HDA_NEEDS_RESUME
ff6fdc37
M
4119static int stac92xx_resume(struct hda_codec *codec)
4120{
dc81bed1
TI
4121 struct sigmatel_spec *spec = codec->spec;
4122
11b44bbd 4123 stac92xx_set_config_regs(codec);
dc81bed1 4124 snd_hda_sequence_write(codec, spec->init);
4fe5195c
MR
4125 stac_gpio_set(codec, spec->gpio_mask,
4126 spec->gpio_dir, spec->gpio_data);
82beb8fd
TI
4127 snd_hda_codec_resume_amp(codec);
4128 snd_hda_codec_resume_cache(codec);
b76c850f
MR
4129 /* power down inactive DACs */
4130 if (spec->dac_list)
4131 stac92xx_power_down(codec);
dc81bed1
TI
4132 /* invoke unsolicited event to reset the HP state */
4133 if (spec->hp_detect)
4134 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
ff6fdc37
M
4135 return 0;
4136}
4137#endif
4138
2f2f4251
M
4139static struct hda_codec_ops stac92xx_patch_ops = {
4140 .build_controls = stac92xx_build_controls,
4141 .build_pcms = stac92xx_build_pcms,
4142 .init = stac92xx_init,
4143 .free = stac92xx_free,
4e55096e 4144 .unsol_event = stac92xx_unsol_event,
cb53c626 4145#ifdef SND_HDA_NEEDS_RESUME
ff6fdc37
M
4146 .resume = stac92xx_resume,
4147#endif
2f2f4251
M
4148};
4149
4150static int patch_stac9200(struct hda_codec *codec)
4151{
4152 struct sigmatel_spec *spec;
c7d4b2fa 4153 int err;
2f2f4251 4154
e560d8d8 4155 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2f2f4251
M
4156 if (spec == NULL)
4157 return -ENOMEM;
4158
4159 codec->spec = spec;
a4eed138 4160 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
11b44bbd 4161 spec->pin_nids = stac9200_pin_nids;
f5fcc13c
TI
4162 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
4163 stac9200_models,
4164 stac9200_cfg_tbl);
11b44bbd
RF
4165 if (spec->board_config < 0) {
4166 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
4167 err = stac92xx_save_bios_config_regs(codec);
4168 if (err < 0) {
4169 stac92xx_free(codec);
4170 return err;
4171 }
4172 spec->pin_configs = spec->bios_pin_configs;
4173 } else {
403d1944
MP
4174 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
4175 stac92xx_set_config_regs(codec);
4176 }
2f2f4251
M
4177
4178 spec->multiout.max_channels = 2;
4179 spec->multiout.num_dacs = 1;
4180 spec->multiout.dac_nids = stac9200_dac_nids;
4181 spec->adc_nids = stac9200_adc_nids;
4182 spec->mux_nids = stac9200_mux_nids;
dabbed6f 4183 spec->num_muxes = 1;
8b65727b 4184 spec->num_dmics = 0;
9e05b7a3 4185 spec->num_adcs = 1;
a64135a2 4186 spec->num_pwrs = 0;
c7d4b2fa 4187
bf277785
TD
4188 if (spec->board_config == STAC_9200_GATEWAY ||
4189 spec->board_config == STAC_9200_OQO)
1194b5b7
TI
4190 spec->init = stac9200_eapd_init;
4191 else
4192 spec->init = stac9200_core_init;
2f2f4251 4193 spec->mixer = stac9200_mixer;
c7d4b2fa 4194
117f257d
TI
4195 if (spec->board_config == STAC_9200_PANASONIC) {
4196 spec->gpio_mask = spec->gpio_dir = 0x09;
4197 spec->gpio_data = 0x00;
4198 }
4199
c7d4b2fa
M
4200 err = stac9200_parse_auto_config(codec);
4201 if (err < 0) {
4202 stac92xx_free(codec);
4203 return err;
4204 }
2f2f4251
M
4205
4206 codec->patch_ops = stac92xx_patch_ops;
4207
4208 return 0;
4209}
4210
8e21c34c
TD
4211static int patch_stac925x(struct hda_codec *codec)
4212{
4213 struct sigmatel_spec *spec;
4214 int err;
4215
4216 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4217 if (spec == NULL)
4218 return -ENOMEM;
4219
4220 codec->spec = spec;
a4eed138 4221 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
8e21c34c
TD
4222 spec->pin_nids = stac925x_pin_nids;
4223 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
4224 stac925x_models,
4225 stac925x_cfg_tbl);
9e507abd 4226 again:
8e21c34c 4227 if (spec->board_config < 0) {
2c11f955
TD
4228 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
4229 "using BIOS defaults\n");
8e21c34c
TD
4230 err = stac92xx_save_bios_config_regs(codec);
4231 if (err < 0) {
4232 stac92xx_free(codec);
4233 return err;
4234 }
4235 spec->pin_configs = spec->bios_pin_configs;
4236 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
4237 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
4238 stac92xx_set_config_regs(codec);
4239 }
4240
4241 spec->multiout.max_channels = 2;
4242 spec->multiout.num_dacs = 1;
4243 spec->multiout.dac_nids = stac925x_dac_nids;
4244 spec->adc_nids = stac925x_adc_nids;
4245 spec->mux_nids = stac925x_mux_nids;
4246 spec->num_muxes = 1;
9e05b7a3 4247 spec->num_adcs = 1;
a64135a2 4248 spec->num_pwrs = 0;
2c11f955
TD
4249 switch (codec->vendor_id) {
4250 case 0x83847632: /* STAC9202 */
4251 case 0x83847633: /* STAC9202D */
4252 case 0x83847636: /* STAC9251 */
4253 case 0x83847637: /* STAC9251D */
f6e9852a 4254 spec->num_dmics = STAC925X_NUM_DMICS;
2c11f955 4255 spec->dmic_nids = stac925x_dmic_nids;
1697055e
TI
4256 spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
4257 spec->dmux_nids = stac925x_dmux_nids;
2c11f955
TD
4258 break;
4259 default:
4260 spec->num_dmics = 0;
4261 break;
4262 }
8e21c34c
TD
4263
4264 spec->init = stac925x_core_init;
4265 spec->mixer = stac925x_mixer;
4266
4267 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
9e507abd
TI
4268 if (!err) {
4269 if (spec->board_config < 0) {
4270 printk(KERN_WARNING "hda_codec: No auto-config is "
4271 "available, default to model=ref\n");
4272 spec->board_config = STAC_925x_REF;
4273 goto again;
4274 }
4275 err = -EINVAL;
4276 }
8e21c34c
TD
4277 if (err < 0) {
4278 stac92xx_free(codec);
4279 return err;
4280 }
4281
4282 codec->patch_ops = stac92xx_patch_ops;
4283
4284 return 0;
4285}
4286
e1f0d669
MR
4287static struct hda_input_mux stac92hd73xx_dmux = {
4288 .num_items = 4,
4289 .items = {
4290 { "Analog Inputs", 0x0b },
e1f0d669
MR
4291 { "Digital Mic 1", 0x09 },
4292 { "Digital Mic 2", 0x0a },
2a9c7816 4293 { "CD", 0x08 },
e1f0d669
MR
4294 }
4295};
4296
4297static int patch_stac92hd73xx(struct hda_codec *codec)
4298{
4299 struct sigmatel_spec *spec;
4300 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
4301 int err = 0;
4302
4303 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4304 if (spec == NULL)
4305 return -ENOMEM;
4306
4307 codec->spec = spec;
e99d32b3 4308 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
e1f0d669
MR
4309 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
4310 spec->pin_nids = stac92hd73xx_pin_nids;
4311 spec->board_config = snd_hda_check_board_config(codec,
4312 STAC_92HD73XX_MODELS,
4313 stac92hd73xx_models,
4314 stac92hd73xx_cfg_tbl);
4315again:
4316 if (spec->board_config < 0) {
4317 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4318 " STAC92HD73XX, using BIOS defaults\n");
4319 err = stac92xx_save_bios_config_regs(codec);
4320 if (err < 0) {
4321 stac92xx_free(codec);
4322 return err;
4323 }
4324 spec->pin_configs = spec->bios_pin_configs;
4325 } else {
4326 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
4327 stac92xx_set_config_regs(codec);
4328 }
4329
4330 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
4331 conn, STAC92HD73_DAC_COUNT + 2) - 1;
4332
4333 if (spec->multiout.num_dacs < 0) {
4334 printk(KERN_WARNING "hda_codec: Could not determine "
4335 "number of channels defaulting to DAC count\n");
4336 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
4337 }
4338
4339 switch (spec->multiout.num_dacs) {
4340 case 0x3: /* 6 Channel */
4341 spec->mixer = stac92hd73xx_6ch_mixer;
4342 spec->init = stac92hd73xx_6ch_core_init;
4343 break;
4344 case 0x4: /* 8 Channel */
e1f0d669
MR
4345 spec->mixer = stac92hd73xx_8ch_mixer;
4346 spec->init = stac92hd73xx_8ch_core_init;
4347 break;
4348 case 0x5: /* 10 Channel */
e1f0d669
MR
4349 spec->mixer = stac92hd73xx_10ch_mixer;
4350 spec->init = stac92hd73xx_10ch_core_init;
4351 };
4352
4353 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
4354 spec->aloopback_mask = 0x01;
4355 spec->aloopback_shift = 8;
4356
1cd2224c 4357 spec->digbeep_nid = 0x1c;
e1f0d669
MR
4358 spec->mux_nids = stac92hd73xx_mux_nids;
4359 spec->adc_nids = stac92hd73xx_adc_nids;
4360 spec->dmic_nids = stac92hd73xx_dmic_nids;
4361 spec->dmux_nids = stac92hd73xx_dmux_nids;
d9737751 4362 spec->smux_nids = stac92hd73xx_smux_nids;
89385035 4363 spec->amp_nids = stac92hd73xx_amp_nids;
2a9c7816 4364 spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids);
e1f0d669
MR
4365
4366 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
4367 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
1697055e 4368 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
2a9c7816
MR
4369 memcpy(&spec->private_dimux, &stac92hd73xx_dmux,
4370 sizeof(stac92hd73xx_dmux));
4371
a7662640 4372 switch (spec->board_config) {
6b3ab21e 4373 case STAC_DELL_EQ:
d654a660 4374 spec->init = dell_eq_core_init;
6b3ab21e
MR
4375 /* fallthru */
4376 case STAC_DELL_M6:
2a9c7816 4377 spec->num_smuxes = 0;
2a9c7816
MR
4378 spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
4379 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
c0cea0d0 4380 spec->eapd_switch = 0;
2a9c7816 4381 spec->num_amps = 1;
6b3ab21e
MR
4382
4383 if (!spec->init)
4384 spec->init = dell_m6_core_init;
a7662640
MR
4385 switch (codec->subsystem_id) {
4386 case 0x1028025e: /* Analog Mics */
4387 case 0x1028025f:
4388 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
4389 spec->num_dmics = 0;
2a9c7816 4390 spec->private_dimux.num_items = 1;
a7662640 4391 break;
d654a660 4392 case 0x10280271: /* Digital Mics */
a7662640 4393 case 0x10280272:
d654a660
MR
4394 case 0x10280254:
4395 case 0x10280255:
a7662640
MR
4396 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
4397 spec->num_dmics = 1;
2a9c7816 4398 spec->private_dimux.num_items = 2;
a7662640
MR
4399 break;
4400 case 0x10280256: /* Both */
4401 case 0x10280057:
4402 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
4403 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
4404 spec->num_dmics = 1;
2a9c7816 4405 spec->private_dimux.num_items = 2;
a7662640
MR
4406 break;
4407 }
4408 break;
4409 default:
4410 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
2a9c7816 4411 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
c0cea0d0 4412 spec->eapd_switch = 1;
a7662640 4413 }
b2c4f4d7
MR
4414 if (spec->board_config > STAC_92HD73XX_REF) {
4415 /* GPIO0 High = Enable EAPD */
4416 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4417 spec->gpio_data = 0x01;
4418 }
2a9c7816 4419 spec->dinput_mux = &spec->private_dimux;
a7662640 4420
a64135a2
MR
4421 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
4422 spec->pwr_nids = stac92hd73xx_pwr_nids;
4423
d9737751 4424 err = stac92xx_parse_auto_config(codec, 0x25, 0x27);
e1f0d669
MR
4425
4426 if (!err) {
4427 if (spec->board_config < 0) {
4428 printk(KERN_WARNING "hda_codec: No auto-config is "
4429 "available, default to model=ref\n");
4430 spec->board_config = STAC_92HD73XX_REF;
4431 goto again;
4432 }
4433 err = -EINVAL;
4434 }
4435
4436 if (err < 0) {
4437 stac92xx_free(codec);
4438 return err;
4439 }
4440
4441 codec->patch_ops = stac92xx_patch_ops;
4442
4443 return 0;
4444}
4445
d0513fc6
MR
4446static struct hda_input_mux stac92hd83xxx_dmux = {
4447 .num_items = 3,
4448 .items = {
4449 { "Analog Inputs", 0x03 },
4450 { "Digital Mic 1", 0x04 },
4451 { "Digital Mic 2", 0x05 },
4452 }
4453};
4454
4455static int patch_stac92hd83xxx(struct hda_codec *codec)
4456{
4457 struct sigmatel_spec *spec;
4458 int err;
4459
4460 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4461 if (spec == NULL)
4462 return -ENOMEM;
4463
4464 codec->spec = spec;
0ffa9807 4465 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
d0513fc6
MR
4466 spec->mono_nid = 0x19;
4467 spec->digbeep_nid = 0x21;
4468 spec->dmic_nids = stac92hd83xxx_dmic_nids;
4469 spec->dmux_nids = stac92hd83xxx_dmux_nids;
4470 spec->adc_nids = stac92hd83xxx_adc_nids;
4471 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4472 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
4473 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4474 spec->multiout.dac_nids = stac92hd83xxx_dac_nids;
4475
4476 spec->init = stac92hd83xxx_core_init;
4477 switch (codec->vendor_id) {
4478 case 0x111d7605:
4479 spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
4480 break;
4481 default:
4482 spec->num_pwrs--;
4483 spec->init++; /* switch to config #2 */
4484 spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
4485 }
4486
4487 spec->mixer = stac92hd83xxx_mixer;
4488 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
4489 spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids);
4490 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
4491 spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
4492 spec->dinput_mux = &stac92hd83xxx_dmux;
4493 spec->pin_nids = stac92hd83xxx_pin_nids;
4494 spec->board_config = snd_hda_check_board_config(codec,
4495 STAC_92HD83XXX_MODELS,
4496 stac92hd83xxx_models,
4497 stac92hd83xxx_cfg_tbl);
4498again:
4499 if (spec->board_config < 0) {
4500 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4501 " STAC92HD83XXX, using BIOS defaults\n");
4502 err = stac92xx_save_bios_config_regs(codec);
4503 if (err < 0) {
4504 stac92xx_free(codec);
4505 return err;
4506 }
4507 spec->pin_configs = spec->bios_pin_configs;
4508 } else {
4509 spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config];
4510 stac92xx_set_config_regs(codec);
4511 }
4512
4513 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
4514 if (!err) {
4515 if (spec->board_config < 0) {
4516 printk(KERN_WARNING "hda_codec: No auto-config is "
4517 "available, default to model=ref\n");
4518 spec->board_config = STAC_92HD83XXX_REF;
4519 goto again;
4520 }
4521 err = -EINVAL;
4522 }
4523
4524 if (err < 0) {
4525 stac92xx_free(codec);
4526 return err;
4527 }
4528
4529 codec->patch_ops = stac92xx_patch_ops;
4530
4531 return 0;
4532}
4533
8daaaa97
MR
4534#ifdef SND_HDA_NEEDS_RESUME
4535static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
4536{
4537 struct sigmatel_spec *spec = codec->spec;
4538 int i;
4539 snd_hda_codec_write_cache(codec, codec->afg, 0,
4540 AC_VERB_SET_POWER_STATE, pwr);
4541
4542 msleep(1);
4543 for (i = 0; i < spec->num_adcs; i++) {
4544 snd_hda_codec_write_cache(codec,
4545 spec->adc_nids[i], 0,
4546 AC_VERB_SET_POWER_STATE, pwr);
4547 }
4548};
4549
4550static int stac92hd71xx_resume(struct hda_codec *codec)
4551{
4552 stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
4553 return stac92xx_resume(codec);
4554}
4555
4556static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
4557{
c0cea0d0
MR
4558 struct sigmatel_spec *spec = codec->spec;
4559
8daaaa97 4560 stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
c0cea0d0
MR
4561 if (spec->eapd_mask)
4562 stac_gpio_set(codec, spec->gpio_mask,
4563 spec->gpio_dir, spec->gpio_data &
4564 ~spec->eapd_mask);
8daaaa97
MR
4565 return 0;
4566};
4567
4568#endif
4569
4570static struct hda_codec_ops stac92hd71bxx_patch_ops = {
4571 .build_controls = stac92xx_build_controls,
4572 .build_pcms = stac92xx_build_pcms,
4573 .init = stac92xx_init,
4574 .free = stac92xx_free,
4575 .unsol_event = stac92xx_unsol_event,
4576#ifdef SND_HDA_NEEDS_RESUME
4577 .resume = stac92hd71xx_resume,
4578 .suspend = stac92hd71xx_suspend,
4579#endif
4580};
d0513fc6 4581
4b33c767
MR
4582static struct hda_input_mux stac92hd71bxx_dmux = {
4583 .num_items = 4,
4584 .items = {
4585 { "Analog Inputs", 0x00 },
4586 { "Mixer", 0x01 },
4587 { "Digital Mic 1", 0x02 },
4588 { "Digital Mic 2", 0x03 },
4589 }
4590};
4591
e035b841
MR
4592static int patch_stac92hd71bxx(struct hda_codec *codec)
4593{
4594 struct sigmatel_spec *spec;
4595 int err = 0;
4596
4597 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4598 if (spec == NULL)
4599 return -ENOMEM;
4600
4601 codec->spec = spec;
8daaaa97 4602 codec->patch_ops = stac92xx_patch_ops;
e035b841 4603 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
aafc4412 4604 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
e035b841 4605 spec->pin_nids = stac92hd71bxx_pin_nids;
4b33c767
MR
4606 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux,
4607 sizeof(stac92hd71bxx_dmux));
e035b841
MR
4608 spec->board_config = snd_hda_check_board_config(codec,
4609 STAC_92HD71BXX_MODELS,
4610 stac92hd71bxx_models,
4611 stac92hd71bxx_cfg_tbl);
4612again:
4613 if (spec->board_config < 0) {
4614 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4615 " STAC92HD71BXX, using BIOS defaults\n");
4616 err = stac92xx_save_bios_config_regs(codec);
4617 if (err < 0) {
4618 stac92xx_free(codec);
4619 return err;
4620 }
4621 spec->pin_configs = spec->bios_pin_configs;
4622 } else {
4623 spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
4624 stac92xx_set_config_regs(codec);
4625 }
4626
541eee87
MR
4627 switch (codec->vendor_id) {
4628 case 0x111d76b6: /* 4 Port without Analog Mixer */
4629 case 0x111d76b7:
4630 case 0x111d76b4: /* 6 Port without Analog Mixer */
4631 case 0x111d76b5:
4632 spec->mixer = stac92hd71bxx_mixer;
4633 spec->init = stac92hd71bxx_core_init;
0ffa9807 4634 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
541eee87 4635 break;
aafc4412 4636 case 0x111d7608: /* 5 Port with Analog Mixer */
72474be6
MR
4637 switch (codec->subsystem_id) {
4638 case 0x103c361a:
4639 /* Enable VREF power saving on GPIO1 detect */
4640 snd_hda_codec_write(codec, codec->afg, 0,
4641 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
4642 snd_hda_codec_write_cache(codec, codec->afg, 0,
74aeaabc
MR
4643 AC_VERB_SET_UNSOLICITED_ENABLE,
4644 (AC_USRSP_EN | STAC_VREF_EVENT | codec->afg));
4645 err = stac92xx_add_event(spec, codec->afg, 0x02);
4646 if (err < 0)
4647 return err;
72474be6
MR
4648 spec->gpio_mask |= 0x02;
4649 break;
4650 }
8daaaa97
MR
4651 if ((codec->revision_id & 0xf) == 0 ||
4652 (codec->revision_id & 0xf) == 1) {
4653#ifdef SND_HDA_NEEDS_RESUME
4654 codec->patch_ops = stac92hd71bxx_patch_ops;
4655#endif
4656 spec->stream_delay = 40; /* 40 milliseconds */
4657 }
4658
aafc4412
MR
4659 /* no output amps */
4660 spec->num_pwrs = 0;
4661 spec->mixer = stac92hd71bxx_analog_mixer;
4b33c767 4662 spec->dinput_mux = &spec->private_dimux;
aafc4412
MR
4663
4664 /* disable VSW */
4665 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
4666 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0);
4667 break;
4668 case 0x111d7603: /* 6 Port with Analog Mixer */
8daaaa97
MR
4669 if ((codec->revision_id & 0xf) == 1) {
4670#ifdef SND_HDA_NEEDS_RESUME
4671 codec->patch_ops = stac92hd71bxx_patch_ops;
4672#endif
4673 spec->stream_delay = 40; /* 40 milliseconds */
4674 }
4675
aafc4412
MR
4676 /* no output amps */
4677 spec->num_pwrs = 0;
4678 /* fallthru */
541eee87 4679 default:
4b33c767 4680 spec->dinput_mux = &spec->private_dimux;
541eee87
MR
4681 spec->mixer = stac92hd71bxx_analog_mixer;
4682 spec->init = stac92hd71bxx_analog_core_init;
0ffa9807 4683 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
541eee87
MR
4684 }
4685
4b33c767 4686 spec->aloopback_mask = 0x50;
541eee87
MR
4687 spec->aloopback_shift = 0;
4688
b2c4f4d7
MR
4689 if (spec->board_config > STAC_92HD71BXX_REF) {
4690 /* GPIO0 = EAPD */
4691 spec->gpio_mask = 0x01;
4692 spec->gpio_dir = 0x01;
4693 spec->gpio_data = 0x01;
4694 }
e035b841 4695
8daaaa97 4696 spec->powerdown_adcs = 1;
1cd2224c 4697 spec->digbeep_nid = 0x26;
e035b841
MR
4698 spec->mux_nids = stac92hd71bxx_mux_nids;
4699 spec->adc_nids = stac92hd71bxx_adc_nids;
4700 spec->dmic_nids = stac92hd71bxx_dmic_nids;
e1f0d669 4701 spec->dmux_nids = stac92hd71bxx_dmux_nids;
d9737751 4702 spec->smux_nids = stac92hd71bxx_smux_nids;
aafc4412 4703 spec->pwr_nids = stac92hd71bxx_pwr_nids;
e035b841
MR
4704
4705 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
4706 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
e035b841 4707
6a14f585
MR
4708 switch (spec->board_config) {
4709 case STAC_HP_M4:
4710 spec->num_dmics = 0;
b9aea715 4711 spec->num_smuxes = 0;
6a14f585
MR
4712 spec->num_dmuxes = 0;
4713
4714 /* enable internal microphone */
b9aea715
MR
4715 stac92xx_set_config_reg(codec, 0x0e, 0x01813040);
4716 stac92xx_auto_set_pinctl(codec, 0x0e,
4717 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
6a14f585
MR
4718 break;
4719 default:
4720 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
4721 spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
4722 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
4723 };
4724
aea7bb0a 4725 spec->multiout.num_dacs = 1;
e035b841
MR
4726 spec->multiout.hp_nid = 0x11;
4727 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
4b33c767
MR
4728 if (spec->dinput_mux)
4729 spec->private_dimux.num_items +=
4730 spec->num_dmics -
4731 (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1);
e035b841
MR
4732
4733 err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
4734 if (!err) {
4735 if (spec->board_config < 0) {
4736 printk(KERN_WARNING "hda_codec: No auto-config is "
4737 "available, default to model=ref\n");
4738 spec->board_config = STAC_92HD71BXX_REF;
4739 goto again;
4740 }
4741 err = -EINVAL;
4742 }
4743
4744 if (err < 0) {
4745 stac92xx_free(codec);
4746 return err;
4747 }
4748
e035b841
MR
4749 return 0;
4750};
4751
2f2f4251
M
4752static int patch_stac922x(struct hda_codec *codec)
4753{
4754 struct sigmatel_spec *spec;
c7d4b2fa 4755 int err;
2f2f4251 4756
e560d8d8 4757 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2f2f4251
M
4758 if (spec == NULL)
4759 return -ENOMEM;
4760
4761 codec->spec = spec;
a4eed138 4762 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
11b44bbd 4763 spec->pin_nids = stac922x_pin_nids;
f5fcc13c
TI
4764 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
4765 stac922x_models,
4766 stac922x_cfg_tbl);
536319af 4767 if (spec->board_config == STAC_INTEL_MAC_AUTO) {
4fe5195c
MR
4768 spec->gpio_mask = spec->gpio_dir = 0x03;
4769 spec->gpio_data = 0x03;
3fc24d85
TI
4770 /* Intel Macs have all same PCI SSID, so we need to check
4771 * codec SSID to distinguish the exact models
4772 */
6f0778d8 4773 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
3fc24d85 4774 switch (codec->subsystem_id) {
5d5d3bc3
IZ
4775
4776 case 0x106b0800:
4777 spec->board_config = STAC_INTEL_MAC_V1;
c45e20eb 4778 break;
5d5d3bc3
IZ
4779 case 0x106b0600:
4780 case 0x106b0700:
4781 spec->board_config = STAC_INTEL_MAC_V2;
6f0778d8 4782 break;
5d5d3bc3
IZ
4783 case 0x106b0e00:
4784 case 0x106b0f00:
4785 case 0x106b1600:
4786 case 0x106b1700:
4787 case 0x106b0200:
4788 case 0x106b1e00:
4789 spec->board_config = STAC_INTEL_MAC_V3;
3fc24d85 4790 break;
5d5d3bc3
IZ
4791 case 0x106b1a00:
4792 case 0x00000100:
4793 spec->board_config = STAC_INTEL_MAC_V4;
f16928fb 4794 break;
5d5d3bc3
IZ
4795 case 0x106b0a00:
4796 case 0x106b2200:
4797 spec->board_config = STAC_INTEL_MAC_V5;
0dae0f83 4798 break;
536319af
NB
4799 default:
4800 spec->board_config = STAC_INTEL_MAC_V3;
4801 break;
3fc24d85
TI
4802 }
4803 }
4804
9e507abd 4805 again:
11b44bbd
RF
4806 if (spec->board_config < 0) {
4807 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
4808 "using BIOS defaults\n");
4809 err = stac92xx_save_bios_config_regs(codec);
4810 if (err < 0) {
4811 stac92xx_free(codec);
4812 return err;
4813 }
4814 spec->pin_configs = spec->bios_pin_configs;
4815 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
403d1944
MP
4816 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
4817 stac92xx_set_config_regs(codec);
4818 }
2f2f4251 4819
c7d4b2fa
M
4820 spec->adc_nids = stac922x_adc_nids;
4821 spec->mux_nids = stac922x_mux_nids;
2549413e 4822 spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
9e05b7a3 4823 spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
8b65727b 4824 spec->num_dmics = 0;
a64135a2 4825 spec->num_pwrs = 0;
c7d4b2fa
M
4826
4827 spec->init = stac922x_core_init;
2f2f4251 4828 spec->mixer = stac922x_mixer;
c7d4b2fa
M
4829
4830 spec->multiout.dac_nids = spec->dac_nids;
19039bd0 4831
3cc08dc6 4832 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
9e507abd
TI
4833 if (!err) {
4834 if (spec->board_config < 0) {
4835 printk(KERN_WARNING "hda_codec: No auto-config is "
4836 "available, default to model=ref\n");
4837 spec->board_config = STAC_D945_REF;
4838 goto again;
4839 }
4840 err = -EINVAL;
4841 }
3cc08dc6
MP
4842 if (err < 0) {
4843 stac92xx_free(codec);
4844 return err;
4845 }
4846
4847 codec->patch_ops = stac92xx_patch_ops;
4848
807a4636
TI
4849 /* Fix Mux capture level; max to 2 */
4850 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
4851 (0 << AC_AMPCAP_OFFSET_SHIFT) |
4852 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4853 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4854 (0 << AC_AMPCAP_MUTE_SHIFT));
4855
3cc08dc6
MP
4856 return 0;
4857}
4858
4859static int patch_stac927x(struct hda_codec *codec)
4860{
4861 struct sigmatel_spec *spec;
4862 int err;
4863
4864 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4865 if (spec == NULL)
4866 return -ENOMEM;
4867
4868 codec->spec = spec;
a4eed138 4869 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
11b44bbd 4870 spec->pin_nids = stac927x_pin_nids;
f5fcc13c
TI
4871 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
4872 stac927x_models,
4873 stac927x_cfg_tbl);
9e507abd 4874 again:
8e9068b1
MR
4875 if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) {
4876 if (spec->board_config < 0)
4877 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4878 "STAC927x, using BIOS defaults\n");
11b44bbd
RF
4879 err = stac92xx_save_bios_config_regs(codec);
4880 if (err < 0) {
4881 stac92xx_free(codec);
4882 return err;
4883 }
4884 spec->pin_configs = spec->bios_pin_configs;
8e9068b1 4885 } else {
3cc08dc6
MP
4886 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
4887 stac92xx_set_config_regs(codec);
4888 }
4889
1cd2224c 4890 spec->digbeep_nid = 0x23;
8e9068b1
MR
4891 spec->adc_nids = stac927x_adc_nids;
4892 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
4893 spec->mux_nids = stac927x_mux_nids;
4894 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
d9737751
MR
4895 spec->smux_nids = stac927x_smux_nids;
4896 spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
65973632 4897 spec->spdif_labels = stac927x_spdif_labels;
b76c850f 4898 spec->dac_list = stac927x_dac_nids;
8e9068b1
MR
4899 spec->multiout.dac_nids = spec->dac_nids;
4900
81d3dbde 4901 switch (spec->board_config) {
93ed1503 4902 case STAC_D965_3ST:
93ed1503 4903 case STAC_D965_5ST:
8e9068b1 4904 /* GPIO0 High = Enable EAPD */
0fc9dec4 4905 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01;
4fe5195c 4906 spec->gpio_data = 0x01;
8e9068b1
MR
4907 spec->num_dmics = 0;
4908
93ed1503 4909 spec->init = d965_core_init;
9e05b7a3 4910 spec->mixer = stac927x_mixer;
81d3dbde 4911 break;
8e9068b1 4912 case STAC_DELL_BIOS:
780c8be4
MR
4913 switch (codec->subsystem_id) {
4914 case 0x10280209:
4915 case 0x1028022e:
4916 /* correct the device field to SPDIF out */
4917 stac92xx_set_config_reg(codec, 0x21, 0x01442070);
4918 break;
4919 };
03d7ca17
MR
4920 /* configure the analog microphone on some laptops */
4921 stac92xx_set_config_reg(codec, 0x0c, 0x90a79130);
2f32d909 4922 /* correct the front output jack as a hp out */
7989fba9 4923 stac92xx_set_config_reg(codec, 0x0f, 0x0227011f);
c481fca3
MR
4924 /* correct the front input jack as a mic */
4925 stac92xx_set_config_reg(codec, 0x0e, 0x02a79130);
4926 /* fallthru */
8e9068b1
MR
4927 case STAC_DELL_3ST:
4928 /* GPIO2 High = Enable EAPD */
0fc9dec4 4929 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04;
4fe5195c 4930 spec->gpio_data = 0x04;
7f16859a
MR
4931 spec->dmic_nids = stac927x_dmic_nids;
4932 spec->num_dmics = STAC927X_NUM_DMICS;
f1f208d0 4933
8e9068b1
MR
4934 spec->init = d965_core_init;
4935 spec->mixer = stac927x_mixer;
4936 spec->dmux_nids = stac927x_dmux_nids;
1697055e 4937 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
7f16859a
MR
4938 break;
4939 default:
b2c4f4d7
MR
4940 if (spec->board_config > STAC_D965_REF) {
4941 /* GPIO0 High = Enable EAPD */
4942 spec->eapd_mask = spec->gpio_mask = 0x01;
4943 spec->gpio_dir = spec->gpio_data = 0x01;
4944 }
8e9068b1
MR
4945 spec->num_dmics = 0;
4946
4947 spec->init = stac927x_core_init;
4948 spec->mixer = stac927x_mixer;
7f16859a
MR
4949 }
4950
a64135a2 4951 spec->num_pwrs = 0;
e1f0d669
MR
4952 spec->aloopback_mask = 0x40;
4953 spec->aloopback_shift = 0;
c0cea0d0 4954 spec->eapd_switch = 1;
8e9068b1 4955
3cc08dc6 4956 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
9e507abd
TI
4957 if (!err) {
4958 if (spec->board_config < 0) {
4959 printk(KERN_WARNING "hda_codec: No auto-config is "
4960 "available, default to model=ref\n");
4961 spec->board_config = STAC_D965_REF;
4962 goto again;
4963 }
4964 err = -EINVAL;
4965 }
c7d4b2fa
M
4966 if (err < 0) {
4967 stac92xx_free(codec);
4968 return err;
4969 }
2f2f4251
M
4970
4971 codec->patch_ops = stac92xx_patch_ops;
4972
52987656
TI
4973 /*
4974 * !!FIXME!!
4975 * The STAC927x seem to require fairly long delays for certain
4976 * command sequences. With too short delays (even if the answer
4977 * is set to RIRB properly), it results in the silence output
4978 * on some hardwares like Dell.
4979 *
4980 * The below flag enables the longer delay (see get_response
4981 * in hda_intel.c).
4982 */
4983 codec->bus->needs_damn_long_delay = 1;
4984
2f2f4251
M
4985 return 0;
4986}
4987
f3302a59
MP
4988static int patch_stac9205(struct hda_codec *codec)
4989{
4990 struct sigmatel_spec *spec;
8259980e 4991 int err;
f3302a59
MP
4992
4993 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4994 if (spec == NULL)
4995 return -ENOMEM;
4996
4997 codec->spec = spec;
a4eed138 4998 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
11b44bbd 4999 spec->pin_nids = stac9205_pin_nids;
f5fcc13c
TI
5000 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
5001 stac9205_models,
5002 stac9205_cfg_tbl);
9e507abd 5003 again:
11b44bbd
RF
5004 if (spec->board_config < 0) {
5005 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
5006 err = stac92xx_save_bios_config_regs(codec);
5007 if (err < 0) {
5008 stac92xx_free(codec);
5009 return err;
5010 }
5011 spec->pin_configs = spec->bios_pin_configs;
5012 } else {
f3302a59
MP
5013 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
5014 stac92xx_set_config_regs(codec);
5015 }
5016
1cd2224c 5017 spec->digbeep_nid = 0x23;
f3302a59 5018 spec->adc_nids = stac9205_adc_nids;
9e05b7a3 5019 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
f3302a59 5020 spec->mux_nids = stac9205_mux_nids;
2549413e 5021 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
d9737751
MR
5022 spec->smux_nids = stac9205_smux_nids;
5023 spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
8b65727b 5024 spec->dmic_nids = stac9205_dmic_nids;
f6e9852a 5025 spec->num_dmics = STAC9205_NUM_DMICS;
e1f0d669 5026 spec->dmux_nids = stac9205_dmux_nids;
1697055e 5027 spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
a64135a2 5028 spec->num_pwrs = 0;
f3302a59
MP
5029
5030 spec->init = stac9205_core_init;
5031 spec->mixer = stac9205_mixer;
5032
e1f0d669
MR
5033 spec->aloopback_mask = 0x40;
5034 spec->aloopback_shift = 0;
c0cea0d0 5035 spec->eapd_switch = 1;
f3302a59 5036 spec->multiout.dac_nids = spec->dac_nids;
87d48363 5037
ae0a8ed8 5038 switch (spec->board_config){
ae0a8ed8 5039 case STAC_9205_DELL_M43:
87d48363
MR
5040 /* Enable SPDIF in/out */
5041 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
5042 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
5043
4fe5195c
MR
5044 /* Enable unsol response for GPIO4/Dock HP connection */
5045 snd_hda_codec_write(codec, codec->afg, 0,
5046 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
5047 snd_hda_codec_write_cache(codec, codec->afg, 0,
74aeaabc
MR
5048 AC_VERB_SET_UNSOLICITED_ENABLE,
5049 (AC_USRSP_EN | STAC_VREF_EVENT | codec->afg));
5050 err = stac92xx_add_event(spec, codec->afg, 0x01);
5051 if (err < 0)
5052 return err;
4fe5195c
MR
5053
5054 spec->gpio_dir = 0x0b;
0fc9dec4 5055 spec->eapd_mask = 0x01;
4fe5195c
MR
5056 spec->gpio_mask = 0x1b;
5057 spec->gpio_mute = 0x10;
e2e7d624 5058 /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
4fe5195c 5059 * GPIO3 Low = DRM
87d48363 5060 */
4fe5195c 5061 spec->gpio_data = 0x01;
ae0a8ed8 5062 break;
b2c4f4d7
MR
5063 case STAC_9205_REF:
5064 /* SPDIF-In enabled */
5065 break;
ae0a8ed8
TD
5066 default:
5067 /* GPIO0 High = EAPD */
0fc9dec4 5068 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
4fe5195c 5069 spec->gpio_data = 0x01;
ae0a8ed8
TD
5070 break;
5071 }
33382403 5072
f3302a59 5073 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
9e507abd
TI
5074 if (!err) {
5075 if (spec->board_config < 0) {
5076 printk(KERN_WARNING "hda_codec: No auto-config is "
5077 "available, default to model=ref\n");
5078 spec->board_config = STAC_9205_REF;
5079 goto again;
5080 }
5081 err = -EINVAL;
5082 }
f3302a59
MP
5083 if (err < 0) {
5084 stac92xx_free(codec);
5085 return err;
5086 }
5087
5088 codec->patch_ops = stac92xx_patch_ops;
5089
5090 return 0;
5091}
5092
db064e50 5093/*
6d859065 5094 * STAC9872 hack
db064e50
TI
5095 */
5096
99ccc560 5097/* static config for Sony VAIO FE550G and Sony VAIO AR */
db064e50
TI
5098static hda_nid_t vaio_dacs[] = { 0x2 };
5099#define VAIO_HP_DAC 0x5
5100static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
5101static hda_nid_t vaio_mux_nids[] = { 0x15 };
5102
5103static struct hda_input_mux vaio_mux = {
a3a2f429 5104 .num_items = 3,
db064e50 5105 .items = {
d773781c 5106 /* { "HP", 0x0 }, */
1624cb9a
TI
5107 { "Mic Jack", 0x1 },
5108 { "Internal Mic", 0x2 },
db064e50
TI
5109 { "PCM", 0x3 },
5110 }
5111};
5112
5113static struct hda_verb vaio_init[] = {
5114 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
72e7b0dd 5115 {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
db064e50
TI
5116 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
5117 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
5118 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
5119 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
1624cb9a 5120 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
db064e50
TI
5121 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
5122 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
5123 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
5124 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
5125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
5126 {}
5127};
5128
6d859065
GM
5129static struct hda_verb vaio_ar_init[] = {
5130 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
5131 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
5132 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
5133 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
5134/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
5135 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
1624cb9a 5136 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
6d859065
GM
5137 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
5138 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
5139/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
5140 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
5141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
5142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
5143 {}
5144};
5145
db064e50 5146static struct snd_kcontrol_new vaio_mixer[] = {
127e82e3
TI
5147 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
5148 HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
5149 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
5150 HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
db064e50
TI
5151 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
5152 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5153 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
5154 {
5155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5156 .name = "Capture Source",
5157 .count = 1,
5158 .info = stac92xx_mux_enum_info,
5159 .get = stac92xx_mux_enum_get,
5160 .put = stac92xx_mux_enum_put,
5161 },
5162 {}
5163};
5164
6d859065 5165static struct snd_kcontrol_new vaio_ar_mixer[] = {
127e82e3
TI
5166 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
5167 HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
5168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
5169 HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
6d859065
GM
5170 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
5171 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5172 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
5173 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
5174 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
5175 {
5176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5177 .name = "Capture Source",
5178 .count = 1,
5179 .info = stac92xx_mux_enum_info,
5180 .get = stac92xx_mux_enum_get,
5181 .put = stac92xx_mux_enum_put,
5182 },
5183 {}
5184};
5185
5186static struct hda_codec_ops stac9872_patch_ops = {
db064e50
TI
5187 .build_controls = stac92xx_build_controls,
5188 .build_pcms = stac92xx_build_pcms,
5189 .init = stac92xx_init,
5190 .free = stac92xx_free,
cb53c626 5191#ifdef SND_HDA_NEEDS_RESUME
db064e50
TI
5192 .resume = stac92xx_resume,
5193#endif
5194};
5195
72e7b0dd
TI
5196static int stac9872_vaio_init(struct hda_codec *codec)
5197{
5198 int err;
5199
5200 err = stac92xx_init(codec);
5201 if (err < 0)
5202 return err;
5203 if (codec->patch_ops.unsol_event)
5204 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
5205 return 0;
5206}
5207
5208static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
5209{
40c1d308 5210 if (get_hp_pin_presence(codec, 0x0a)) {
72e7b0dd
TI
5211 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
5212 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
5213 } else {
5214 stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
5215 stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
5216 }
5217}
5218
5219static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
5220{
5221 switch (res >> 26) {
5222 case STAC_HP_EVENT:
5223 stac9872_vaio_hp_detect(codec, res);
5224 break;
5225 }
5226}
5227
5228static struct hda_codec_ops stac9872_vaio_patch_ops = {
5229 .build_controls = stac92xx_build_controls,
5230 .build_pcms = stac92xx_build_pcms,
5231 .init = stac9872_vaio_init,
5232 .free = stac92xx_free,
5233 .unsol_event = stac9872_vaio_unsol_event,
5234#ifdef CONFIG_PM
5235 .resume = stac92xx_resume,
5236#endif
5237};
5238
6d859065
GM
5239enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
5240 CXD9872RD_VAIO,
5241 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
5242 STAC9872AK_VAIO,
5243 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
5244 STAC9872K_VAIO,
5245 /* AR Series. id=0x83847664 and subsys=104D1300 */
f5fcc13c
TI
5246 CXD9872AKD_VAIO,
5247 STAC_9872_MODELS,
5248};
5249
5250static const char *stac9872_models[STAC_9872_MODELS] = {
5251 [CXD9872RD_VAIO] = "vaio",
5252 [CXD9872AKD_VAIO] = "vaio-ar",
5253};
5254
5255static struct snd_pci_quirk stac9872_cfg_tbl[] = {
5256 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
5257 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
5258 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
68e22543 5259 SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
db064e50
TI
5260 {}
5261};
5262
6d859065 5263static int patch_stac9872(struct hda_codec *codec)
db064e50
TI
5264{
5265 struct sigmatel_spec *spec;
5266 int board_config;
5267
f5fcc13c
TI
5268 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
5269 stac9872_models,
5270 stac9872_cfg_tbl);
db064e50
TI
5271 if (board_config < 0)
5272 /* unknown config, let generic-parser do its job... */
5273 return snd_hda_parse_generic_codec(codec);
5274
5275 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5276 if (spec == NULL)
5277 return -ENOMEM;
5278
5279 codec->spec = spec;
5280 switch (board_config) {
6d859065
GM
5281 case CXD9872RD_VAIO:
5282 case STAC9872AK_VAIO:
5283 case STAC9872K_VAIO:
db064e50
TI
5284 spec->mixer = vaio_mixer;
5285 spec->init = vaio_init;
5286 spec->multiout.max_channels = 2;
5287 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
5288 spec->multiout.dac_nids = vaio_dacs;
5289 spec->multiout.hp_nid = VAIO_HP_DAC;
5290 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
5291 spec->adc_nids = vaio_adcs;
a64135a2 5292 spec->num_pwrs = 0;
db064e50
TI
5293 spec->input_mux = &vaio_mux;
5294 spec->mux_nids = vaio_mux_nids;
72e7b0dd 5295 codec->patch_ops = stac9872_vaio_patch_ops;
db064e50 5296 break;
6d859065
GM
5297
5298 case CXD9872AKD_VAIO:
5299 spec->mixer = vaio_ar_mixer;
5300 spec->init = vaio_ar_init;
5301 spec->multiout.max_channels = 2;
5302 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
5303 spec->multiout.dac_nids = vaio_dacs;
5304 spec->multiout.hp_nid = VAIO_HP_DAC;
5305 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
a64135a2 5306 spec->num_pwrs = 0;
6d859065
GM
5307 spec->adc_nids = vaio_adcs;
5308 spec->input_mux = &vaio_mux;
5309 spec->mux_nids = vaio_mux_nids;
72e7b0dd 5310 codec->patch_ops = stac9872_patch_ops;
6d859065 5311 break;
db064e50
TI
5312 }
5313
db064e50
TI
5314 return 0;
5315}
5316
5317
2f2f4251
M
5318/*
5319 * patch entries
5320 */
5321struct hda_codec_preset snd_hda_preset_sigmatel[] = {
5322 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
5323 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
5324 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
5325 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
5326 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
5327 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
5328 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
22a27c7f
MP
5329 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
5330 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
5331 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
5332 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
5333 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
5334 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3cc08dc6
MP
5335 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
5336 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
5337 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
5338 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
5339 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
5340 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
5341 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
5342 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
5343 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
5344 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
8e21c34c
TD
5345 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
5346 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
5347 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
5348 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
5349 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
5350 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
7bd3c0f7
TI
5351 { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
5352 { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
6d859065
GM
5353 /* The following does not take into account .id=0x83847661 when subsys =
5354 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
5355 * currently not fully supported.
5356 */
5357 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
5358 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
5359 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
f3302a59
MP
5360 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
5361 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
5362 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
5363 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
5364 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
5365 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
5366 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
5367 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
aafc4412 5368 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
d0513fc6
MR
5369 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
5370 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
aafc4412 5371 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
541eee87
MR
5372 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
5373 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
e1f0d669 5374 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
541eee87
MR
5375 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
5376 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
5377 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
5378 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
5379 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
5380 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
5381 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
5382 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
2f2f4251
M
5383 {} /* terminator */
5384};