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