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