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