[ALSA] hda-codec - Add missing Mic Boost controls for ALC262
[linux-block.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
27#include <sound/driver.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/pci.h>
32#include <sound/core.h>
c7d4b2fa 33#include <sound/asoundef.h>
2f2f4251
M
34#include "hda_codec.h"
35#include "hda_local.h"
36
4e55096e
M
37#define NUM_CONTROL_ALLOC 32
38#define STAC_HP_EVENT 0x37
4e55096e 39
f5fcc13c
TI
40enum {
41 STAC_REF,
42 STAC_9200_MODELS
43};
44
45enum {
46 STAC_9205_REF,
47 STAC_9205_MODELS
48};
49
8e21c34c
TD
50enum {
51 STAC_925x_REF,
52 STAC_M2_2,
53 STAC_MA6,
54 STAC_925x_MODELS
55};
56
f5fcc13c
TI
57enum {
58 STAC_D945_REF,
59 STAC_D945GTP3,
60 STAC_D945GTP5,
61 STAC_MACMINI,
62 STAC_922X_MODELS
63};
64
65enum {
66 STAC_D965_REF,
67 STAC_D965_3ST,
68 STAC_D965_5ST,
69 STAC_927X_MODELS
70};
403d1944 71
2f2f4251 72struct sigmatel_spec {
c8b6bf9b 73 struct snd_kcontrol_new *mixers[4];
c7d4b2fa
M
74 unsigned int num_mixers;
75
403d1944 76 int board_config;
c7d4b2fa 77 unsigned int surr_switch: 1;
403d1944
MP
78 unsigned int line_switch: 1;
79 unsigned int mic_switch: 1;
3cc08dc6 80 unsigned int alt_switch: 1;
82bc955f 81 unsigned int hp_detect: 1;
62fe78e9 82 unsigned int gpio_mute: 1;
c7d4b2fa 83
2f2f4251
M
84 /* playback */
85 struct hda_multi_out multiout;
3cc08dc6 86 hda_nid_t dac_nids[5];
2f2f4251
M
87
88 /* capture */
89 hda_nid_t *adc_nids;
2f2f4251 90 unsigned int num_adcs;
dabbed6f
M
91 hda_nid_t *mux_nids;
92 unsigned int num_muxes;
8b65727b
MP
93 hda_nid_t *dmic_nids;
94 unsigned int num_dmics;
95 hda_nid_t dmux_nid;
dabbed6f 96 hda_nid_t dig_in_nid;
2f2f4251 97
2f2f4251
M
98 /* pin widgets */
99 hda_nid_t *pin_nids;
100 unsigned int num_pins;
2f2f4251 101 unsigned int *pin_configs;
11b44bbd 102 unsigned int *bios_pin_configs;
2f2f4251
M
103
104 /* codec specific stuff */
105 struct hda_verb *init;
c8b6bf9b 106 struct snd_kcontrol_new *mixer;
2f2f4251
M
107
108 /* capture source */
8b65727b
MP
109 struct hda_input_mux *dinput_mux;
110 unsigned int cur_dmux;
c7d4b2fa 111 struct hda_input_mux *input_mux;
3cc08dc6 112 unsigned int cur_mux[3];
2f2f4251 113
403d1944
MP
114 /* i/o switches */
115 unsigned int io_switch[2];
2f2f4251 116
c7d4b2fa
M
117 struct hda_pcm pcm_rec[2]; /* PCM information */
118
119 /* dynamic controls and input_mux */
120 struct auto_pin_cfg autocfg;
121 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 122 struct snd_kcontrol_new *kctl_alloc;
8b65727b 123 struct hda_input_mux private_dimux;
c7d4b2fa 124 struct hda_input_mux private_imux;
2f2f4251
M
125};
126
127static hda_nid_t stac9200_adc_nids[1] = {
128 0x03,
129};
130
131static hda_nid_t stac9200_mux_nids[1] = {
132 0x0c,
133};
134
135static hda_nid_t stac9200_dac_nids[1] = {
136 0x02,
137};
138
8e21c34c
TD
139static hda_nid_t stac925x_adc_nids[1] = {
140 0x03,
141};
142
143static hda_nid_t stac925x_mux_nids[1] = {
144 0x0f,
145};
146
147static hda_nid_t stac925x_dac_nids[1] = {
148 0x02,
149};
150
2f2f4251
M
151static hda_nid_t stac922x_adc_nids[2] = {
152 0x06, 0x07,
153};
154
155static hda_nid_t stac922x_mux_nids[2] = {
156 0x12, 0x13,
157};
158
3cc08dc6
MP
159static hda_nid_t stac927x_adc_nids[3] = {
160 0x07, 0x08, 0x09
161};
162
163static hda_nid_t stac927x_mux_nids[3] = {
164 0x15, 0x16, 0x17
165};
166
f3302a59
MP
167static hda_nid_t stac9205_adc_nids[2] = {
168 0x12, 0x13
169};
170
171static hda_nid_t stac9205_mux_nids[2] = {
172 0x19, 0x1a
173};
174
8b65727b
MP
175static hda_nid_t stac9205_dmic_nids[3] = {
176 0x17, 0x18, 0
177};
178
c7d4b2fa 179static hda_nid_t stac9200_pin_nids[8] = {
93ed1503
TD
180 0x08, 0x09, 0x0d, 0x0e,
181 0x0f, 0x10, 0x11, 0x12,
2f2f4251
M
182};
183
8e21c34c
TD
184static hda_nid_t stac925x_pin_nids[8] = {
185 0x07, 0x08, 0x0a, 0x0b,
186 0x0c, 0x0d, 0x10, 0x11,
187};
188
2f2f4251
M
189static hda_nid_t stac922x_pin_nids[10] = {
190 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
191 0x0f, 0x10, 0x11, 0x15, 0x1b,
192};
193
3cc08dc6
MP
194static hda_nid_t stac927x_pin_nids[14] = {
195 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
196 0x0f, 0x10, 0x11, 0x12, 0x13,
197 0x14, 0x21, 0x22, 0x23,
198};
199
f3302a59
MP
200static hda_nid_t stac9205_pin_nids[12] = {
201 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
202 0x0f, 0x14, 0x16, 0x17, 0x18,
203 0x21, 0x22,
204
205};
206
8b65727b
MP
207static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
208 struct snd_ctl_elem_info *uinfo)
209{
210 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
211 struct sigmatel_spec *spec = codec->spec;
212 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
213}
214
215static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_value *ucontrol)
217{
218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
219 struct sigmatel_spec *spec = codec->spec;
220
221 ucontrol->value.enumerated.item[0] = spec->cur_dmux;
222 return 0;
223}
224
225static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol)
227{
228 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
229 struct sigmatel_spec *spec = codec->spec;
230
231 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
232 spec->dmux_nid, &spec->cur_dmux);
233}
234
c8b6bf9b 235static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2f2f4251
M
236{
237 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
238 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa 239 return snd_hda_input_mux_info(spec->input_mux, uinfo);
2f2f4251
M
240}
241
c8b6bf9b 242static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2f2f4251
M
243{
244 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
245 struct sigmatel_spec *spec = codec->spec;
246 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
247
248 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
249 return 0;
250}
251
c8b6bf9b 252static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2f2f4251
M
253{
254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
255 struct sigmatel_spec *spec = codec->spec;
256 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
257
c7d4b2fa 258 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
2f2f4251
M
259 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
260}
261
c7d4b2fa 262static struct hda_verb stac9200_core_init[] = {
2f2f4251 263 /* set dac0mux for dac converter */
c7d4b2fa 264 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2f2f4251
M
265 {}
266};
267
8e21c34c
TD
268static struct hda_verb stac925x_core_init[] = {
269 /* set dac0mux for dac converter */
270 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
271 {}
272};
273
c7d4b2fa 274static struct hda_verb stac922x_core_init[] = {
2f2f4251 275 /* set master volume and direct control */
c7d4b2fa 276 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
2f2f4251
M
277 {}
278};
279
93ed1503 280static struct hda_verb d965_core_init[] = {
19039bd0 281 /* set master volume and direct control */
93ed1503 282 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
19039bd0
TI
283 /* unmute node 0x1b */
284 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
285 /* select node 0x03 as DAC */
286 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
287 {}
288};
289
3cc08dc6
MP
290static struct hda_verb stac927x_core_init[] = {
291 /* set master volume and direct control */
292 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
293 {}
294};
295
f3302a59
MP
296static struct hda_verb stac9205_core_init[] = {
297 /* set master volume and direct control */
298 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
299 {}
300};
301
c8b6bf9b 302static struct snd_kcontrol_new stac9200_mixer[] = {
2f2f4251
M
303 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
304 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
305 {
306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
307 .name = "Input Source",
308 .count = 1,
309 .info = stac92xx_mux_enum_info,
310 .get = stac92xx_mux_enum_get,
311 .put = stac92xx_mux_enum_put,
312 },
313 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
314 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
c7d4b2fa 315 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
2f2f4251
M
316 { } /* end */
317};
318
8e21c34c
TD
319static struct snd_kcontrol_new stac925x_mixer[] = {
320 HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
321 HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT),
322 {
323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
324 .name = "Input Source",
325 .count = 1,
326 .info = stac92xx_mux_enum_info,
327 .get = stac92xx_mux_enum_get,
328 .put = stac92xx_mux_enum_put,
329 },
330 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
331 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
332 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
333 { } /* end */
334};
335
c7d4b2fa 336/* This needs to be generated dynamically based on sequence */
c8b6bf9b 337static struct snd_kcontrol_new stac922x_mixer[] = {
2f2f4251
M
338 {
339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
340 .name = "Input Source",
341 .count = 1,
342 .info = stac92xx_mux_enum_info,
343 .get = stac92xx_mux_enum_get,
344 .put = stac92xx_mux_enum_put,
345 },
346 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
0fd1708a 347 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
2f2f4251
M
348 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
349 { } /* end */
350};
351
19039bd0
TI
352/* This needs to be generated dynamically based on sequence */
353static struct snd_kcontrol_new stac9227_mixer[] = {
354 {
355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
356 .name = "Input Source",
357 .count = 1,
358 .info = stac92xx_mux_enum_info,
359 .get = stac92xx_mux_enum_get,
360 .put = stac92xx_mux_enum_put,
361 },
362 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
363 HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
364 { } /* end */
365};
366
d1d985f0 367static struct snd_kcontrol_new stac927x_mixer[] = {
3cc08dc6
MP
368 {
369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
370 .name = "Input Source",
371 .count = 1,
372 .info = stac92xx_mux_enum_info,
373 .get = stac92xx_mux_enum_get,
374 .put = stac92xx_mux_enum_put,
375 },
376 HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT),
377 HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT),
378 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
379 { } /* end */
380};
381
d1d985f0 382static struct snd_kcontrol_new stac9205_mixer[] = {
8b65727b
MP
383 {
384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
385 .name = "Digital Input Source",
386 .count = 1,
387 .info = stac92xx_dmux_enum_info,
388 .get = stac92xx_dmux_enum_get,
389 .put = stac92xx_dmux_enum_put,
390 },
f3302a59
MP
391 {
392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
393 .name = "Input Source",
394 .count = 1,
395 .info = stac92xx_mux_enum_info,
396 .get = stac92xx_mux_enum_get,
397 .put = stac92xx_mux_enum_put,
398 },
399 HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT),
401 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT),
402 { } /* end */
403};
404
2f2f4251
M
405static int stac92xx_build_controls(struct hda_codec *codec)
406{
407 struct sigmatel_spec *spec = codec->spec;
408 int err;
c7d4b2fa 409 int i;
2f2f4251
M
410
411 err = snd_hda_add_new_ctls(codec, spec->mixer);
412 if (err < 0)
413 return err;
c7d4b2fa
M
414
415 for (i = 0; i < spec->num_mixers; i++) {
416 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
417 if (err < 0)
418 return err;
419 }
420
dabbed6f
M
421 if (spec->multiout.dig_out_nid) {
422 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
423 if (err < 0)
424 return err;
425 }
426 if (spec->dig_in_nid) {
427 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
428 if (err < 0)
429 return err;
430 }
431 return 0;
2f2f4251
M
432}
433
403d1944 434static unsigned int ref9200_pin_configs[8] = {
dabbed6f 435 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
2f2f4251
M
436 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
437};
438
f5fcc13c
TI
439static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
440 [STAC_REF] = ref9200_pin_configs,
403d1944
MP
441};
442
f5fcc13c
TI
443static const char *stac9200_models[STAC_9200_MODELS] = {
444 [STAC_REF] = "ref",
445};
446
447static struct snd_pci_quirk stac9200_cfg_tbl[] = {
448 /* SigmaTel reference board */
449 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
450 "DFI LanParty", STAC_REF),
e7377071 451 /* Dell laptops have BIOS problem */
f5fcc13c
TI
452 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
453 "Dell Inspiron 630m", STAC_REF),
454 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
455 "Dell Latitude D620", STAC_REF),
456 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
457 "Dell Latitude 120L", STAC_REF),
877b866d
CT
458 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
459 "Dell Latitude D820", STAC_REF),
46f02ca3
MN
460 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
461 "Dell Inspiron E1705/9400", STAC_REF),
462 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
463 "Dell XPS M1710", STAC_REF),
f0f96745
TI
464 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
465 "Dell Precision M90", STAC_REF),
403d1944
MP
466 {} /* terminator */
467};
468
8e21c34c
TD
469static unsigned int ref925x_pin_configs[8] = {
470 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
471 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
472};
473
474static unsigned int stac925x_MA6_pin_configs[8] = {
475 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
476 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
477};
478
479static unsigned int stac925xM2_2_pin_configs[8] = {
480 0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020,
481 0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e,
482};
483
484static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
485 [STAC_REF] = ref925x_pin_configs,
486 [STAC_M2_2] = stac925xM2_2_pin_configs,
487 [STAC_MA6] = stac925x_MA6_pin_configs,
488};
489
490static const char *stac925x_models[STAC_925x_MODELS] = {
491 [STAC_REF] = "ref",
492 [STAC_M2_2] = "m2-2",
493 [STAC_MA6] = "m6",
494};
495
496static struct snd_pci_quirk stac925x_cfg_tbl[] = {
497 /* SigmaTel reference board */
498 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
499 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
500 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
501 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
502 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
503 {} /* terminator */
504};
505
403d1944
MP
506static unsigned int ref922x_pin_configs[10] = {
507 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
508 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
2f2f4251
M
509 0x40000100, 0x40000100,
510};
511
403d1944 512static unsigned int d945gtp3_pin_configs[10] = {
869264c4 513 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
403d1944
MP
514 0x40000100, 0x40000100, 0x40000100, 0x40000100,
515 0x02a19120, 0x40000100,
516};
517
518static unsigned int d945gtp5_pin_configs[10] = {
869264c4
MP
519 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
520 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
403d1944
MP
521 0x02a19320, 0x40000100,
522};
523
19039bd0 524static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
f5fcc13c 525 [STAC_D945_REF] = ref922x_pin_configs,
19039bd0
TI
526 [STAC_D945GTP3] = d945gtp3_pin_configs,
527 [STAC_D945GTP5] = d945gtp5_pin_configs,
7c3dec06 528 [STAC_MACMINI] = d945gtp5_pin_configs,
403d1944
MP
529};
530
f5fcc13c
TI
531static const char *stac922x_models[STAC_922X_MODELS] = {
532 [STAC_D945_REF] = "ref",
533 [STAC_D945GTP5] = "5stack",
534 [STAC_D945GTP3] = "3stack",
535 [STAC_MACMINI] = "macmini",
536};
537
538static struct snd_pci_quirk stac922x_cfg_tbl[] = {
539 /* SigmaTel reference board */
540 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
541 "DFI LanParty", STAC_D945_REF),
542 /* Intel 945G based systems */
543 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
544 "Intel D945G", STAC_D945GTP3),
545 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
546 "Intel D945G", STAC_D945GTP3),
547 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
548 "Intel D945G", STAC_D945GTP3),
549 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
550 "Intel D945G", STAC_D945GTP3),
551 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
552 "Intel D945G", STAC_D945GTP3),
553 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
554 "Intel D945G", STAC_D945GTP3),
555 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
556 "Intel D945G", STAC_D945GTP3),
557 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
558 "Intel D945G", STAC_D945GTP3),
559 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
560 "Intel D945G", STAC_D945GTP3),
561 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
562 "Intel D945G", STAC_D945GTP3),
563 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
564 "Intel D945G", STAC_D945GTP3),
565 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
566 "Intel D945G", STAC_D945GTP3),
567 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
568 "Intel D945G", STAC_D945GTP3),
569 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
570 "Intel D945G", STAC_D945GTP3),
571 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
572 "Intel D945G", STAC_D945GTP3),
573 /* Intel D945G 5-stack systems */
574 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
575 "Intel D945G", STAC_D945GTP5),
576 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
577 "Intel D945G", STAC_D945GTP5),
578 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
579 "Intel D945G", STAC_D945GTP5),
580 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
581 "Intel D945G", STAC_D945GTP5),
582 /* Intel 945P based systems */
583 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
584 "Intel D945P", STAC_D945GTP3),
585 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
586 "Intel D945P", STAC_D945GTP3),
587 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
588 "Intel D945P", STAC_D945GTP3),
589 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
590 "Intel D945P", STAC_D945GTP3),
591 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
592 "Intel D945P", STAC_D945GTP3),
593 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
594 "Intel D945P", STAC_D945GTP5),
595 /* other systems */
596 /* Apple Mac Mini (early 2006) */
597 SND_PCI_QUIRK(0x8384, 0x7680,
598 "Mac Mini", STAC_MACMINI),
403d1944
MP
599 {} /* terminator */
600};
601
3cc08dc6 602static unsigned int ref927x_pin_configs[14] = {
93ed1503
TD
603 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
604 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
605 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
606 0x01c42190, 0x40000100,
3cc08dc6
MP
607};
608
93ed1503 609static unsigned int d965_3st_pin_configs[14] = {
81d3dbde
TD
610 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
611 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
612 0x40000100, 0x40000100, 0x40000100, 0x40000100,
613 0x40000100, 0x40000100
614};
615
93ed1503
TD
616static unsigned int d965_5st_pin_configs[14] = {
617 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
618 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
619 0x40000100, 0x40000100, 0x40000100, 0x01442070,
620 0x40000100, 0x40000100
621};
622
623static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
f5fcc13c 624 [STAC_D965_REF] = ref927x_pin_configs,
93ed1503
TD
625 [STAC_D965_3ST] = d965_3st_pin_configs,
626 [STAC_D965_5ST] = d965_5st_pin_configs,
3cc08dc6
MP
627};
628
f5fcc13c
TI
629static const char *stac927x_models[STAC_927X_MODELS] = {
630 [STAC_D965_REF] = "ref",
631 [STAC_D965_3ST] = "3stack",
632 [STAC_D965_5ST] = "5stack",
633};
634
635static struct snd_pci_quirk stac927x_cfg_tbl[] = {
636 /* SigmaTel reference board */
637 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
638 "DFI LanParty", STAC_D965_REF),
81d3dbde 639 /* Intel 946 based systems */
f5fcc13c
TI
640 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
641 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
93ed1503 642 /* 965 based 3 stack systems */
f5fcc13c
TI
643 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
644 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
645 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
646 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
647 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
648 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
649 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
650 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
652 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
653 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
654 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
656 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
657 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
658 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
93ed1503 659 /* 965 based 5 stack systems */
f5fcc13c
TI
660 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
661 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
662 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
663 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
664 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
665 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
666 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
667 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
668 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
3cc08dc6
MP
669 {} /* terminator */
670};
671
f3302a59
MP
672static unsigned int ref9205_pin_configs[12] = {
673 0x40000100, 0x40000100, 0x01016011, 0x01014010,
8b65727b
MP
674 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
675 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
f3302a59
MP
676};
677
f5fcc13c 678static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
f3302a59
MP
679 ref9205_pin_configs,
680};
681
f5fcc13c
TI
682static const char *stac9205_models[STAC_9205_MODELS] = {
683 [STAC_9205_REF] = "ref",
684};
685
686static struct snd_pci_quirk stac9205_cfg_tbl[] = {
687 /* SigmaTel reference board */
688 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
689 "DFI LanParty", STAC_9205_REF),
f3302a59
MP
690 {} /* terminator */
691};
692
11b44bbd
RF
693static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
694{
695 int i;
696 struct sigmatel_spec *spec = codec->spec;
697
698 if (! spec->bios_pin_configs) {
699 spec->bios_pin_configs = kcalloc(spec->num_pins,
700 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
701 if (! spec->bios_pin_configs)
702 return -ENOMEM;
703 }
704
705 for (i = 0; i < spec->num_pins; i++) {
706 hda_nid_t nid = spec->pin_nids[i];
707 unsigned int pin_cfg;
708
709 pin_cfg = snd_hda_codec_read(codec, nid, 0,
710 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
711 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
712 nid, pin_cfg);
713 spec->bios_pin_configs[i] = pin_cfg;
714 }
715
716 return 0;
717}
718
2f2f4251
M
719static void stac92xx_set_config_regs(struct hda_codec *codec)
720{
721 int i;
722 struct sigmatel_spec *spec = codec->spec;
723 unsigned int pin_cfg;
724
11b44bbd
RF
725 if (! spec->pin_nids || ! spec->pin_configs)
726 return;
727
728 for (i = 0; i < spec->num_pins; i++) {
2f2f4251
M
729 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
730 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
731 spec->pin_configs[i] & 0x000000ff);
732 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
733 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
734 (spec->pin_configs[i] & 0x0000ff00) >> 8);
735 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
736 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
737 (spec->pin_configs[i] & 0x00ff0000) >> 16);
738 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
739 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
740 spec->pin_configs[i] >> 24);
741 pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0,
742 AC_VERB_GET_CONFIG_DEFAULT,
743 0x00);
403d1944 744 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg);
2f2f4251
M
745 }
746}
2f2f4251 747
dabbed6f 748/*
c7d4b2fa 749 * Analog playback callbacks
dabbed6f 750 */
c7d4b2fa
M
751static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
752 struct hda_codec *codec,
c8b6bf9b 753 struct snd_pcm_substream *substream)
2f2f4251 754{
dabbed6f 755 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa 756 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2f2f4251
M
757}
758
2f2f4251
M
759static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
760 struct hda_codec *codec,
761 unsigned int stream_tag,
762 unsigned int format,
c8b6bf9b 763 struct snd_pcm_substream *substream)
2f2f4251
M
764{
765 struct sigmatel_spec *spec = codec->spec;
403d1944 766 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
2f2f4251
M
767}
768
769static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
770 struct hda_codec *codec,
c8b6bf9b 771 struct snd_pcm_substream *substream)
2f2f4251
M
772{
773 struct sigmatel_spec *spec = codec->spec;
774 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
775}
776
dabbed6f
M
777/*
778 * Digital playback callbacks
779 */
780static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
781 struct hda_codec *codec,
c8b6bf9b 782 struct snd_pcm_substream *substream)
dabbed6f
M
783{
784 struct sigmatel_spec *spec = codec->spec;
785 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
786}
787
788static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
789 struct hda_codec *codec,
c8b6bf9b 790 struct snd_pcm_substream *substream)
dabbed6f
M
791{
792 struct sigmatel_spec *spec = codec->spec;
793 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
794}
795
796
2f2f4251
M
797/*
798 * Analog capture callbacks
799 */
800static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
801 struct hda_codec *codec,
802 unsigned int stream_tag,
803 unsigned int format,
c8b6bf9b 804 struct snd_pcm_substream *substream)
2f2f4251
M
805{
806 struct sigmatel_spec *spec = codec->spec;
807
808 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
809 stream_tag, 0, format);
810 return 0;
811}
812
813static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
814 struct hda_codec *codec,
c8b6bf9b 815 struct snd_pcm_substream *substream)
2f2f4251
M
816{
817 struct sigmatel_spec *spec = codec->spec;
818
819 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
820 return 0;
821}
822
dabbed6f
M
823static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
824 .substreams = 1,
825 .channels_min = 2,
826 .channels_max = 2,
827 /* NID is set in stac92xx_build_pcms */
828 .ops = {
829 .open = stac92xx_dig_playback_pcm_open,
830 .close = stac92xx_dig_playback_pcm_close
831 },
832};
833
834static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
835 .substreams = 1,
836 .channels_min = 2,
837 .channels_max = 2,
838 /* NID is set in stac92xx_build_pcms */
839};
840
2f2f4251
M
841static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
842 .substreams = 1,
843 .channels_min = 2,
c7d4b2fa 844 .channels_max = 8,
2f2f4251
M
845 .nid = 0x02, /* NID to query formats and rates */
846 .ops = {
847 .open = stac92xx_playback_pcm_open,
848 .prepare = stac92xx_playback_pcm_prepare,
849 .cleanup = stac92xx_playback_pcm_cleanup
850 },
851};
852
3cc08dc6
MP
853static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
854 .substreams = 1,
855 .channels_min = 2,
856 .channels_max = 2,
857 .nid = 0x06, /* NID to query formats and rates */
858 .ops = {
859 .open = stac92xx_playback_pcm_open,
860 .prepare = stac92xx_playback_pcm_prepare,
861 .cleanup = stac92xx_playback_pcm_cleanup
862 },
863};
864
2f2f4251
M
865static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
866 .substreams = 2,
867 .channels_min = 2,
868 .channels_max = 2,
3cc08dc6 869 /* NID is set in stac92xx_build_pcms */
2f2f4251
M
870 .ops = {
871 .prepare = stac92xx_capture_pcm_prepare,
872 .cleanup = stac92xx_capture_pcm_cleanup
873 },
874};
875
876static int stac92xx_build_pcms(struct hda_codec *codec)
877{
878 struct sigmatel_spec *spec = codec->spec;
879 struct hda_pcm *info = spec->pcm_rec;
880
881 codec->num_pcms = 1;
882 codec->pcm_info = info;
883
c7d4b2fa 884 info->name = "STAC92xx Analog";
2f2f4251 885 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
2f2f4251 886 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
3cc08dc6
MP
887 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
888
889 if (spec->alt_switch) {
890 codec->num_pcms++;
891 info++;
892 info->name = "STAC92xx Analog Alt";
893 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
894 }
2f2f4251 895
dabbed6f
M
896 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
897 codec->num_pcms++;
898 info++;
899 info->name = "STAC92xx Digital";
900 if (spec->multiout.dig_out_nid) {
901 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
902 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
903 }
904 if (spec->dig_in_nid) {
905 info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
906 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
907 }
908 }
909
2f2f4251
M
910 return 0;
911}
912
c960a03b
TI
913static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
914{
915 unsigned int pincap = snd_hda_param_read(codec, nid,
916 AC_PAR_PIN_CAP);
917 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
918 if (pincap & AC_PINCAP_VREF_100)
919 return AC_PINCTL_VREF_100;
920 if (pincap & AC_PINCAP_VREF_80)
921 return AC_PINCTL_VREF_80;
922 if (pincap & AC_PINCAP_VREF_50)
923 return AC_PINCTL_VREF_50;
924 if (pincap & AC_PINCAP_VREF_GRD)
925 return AC_PINCTL_VREF_GRD;
926 return 0;
927}
928
403d1944
MP
929static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
930
931{
932 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
933}
934
935static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
936{
937 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
938 uinfo->count = 1;
939 uinfo->value.integer.min = 0;
940 uinfo->value.integer.max = 1;
941 return 0;
942}
943
944static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
945{
946 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
947 struct sigmatel_spec *spec = codec->spec;
948 int io_idx = kcontrol-> private_value & 0xff;
949
950 ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
951 return 0;
952}
953
954static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
955{
956 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
957 struct sigmatel_spec *spec = codec->spec;
958 hda_nid_t nid = kcontrol->private_value >> 8;
959 int io_idx = kcontrol-> private_value & 0xff;
960 unsigned short val = ucontrol->value.integer.value[0];
961
962 spec->io_switch[io_idx] = val;
963
964 if (val)
965 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
c960a03b
TI
966 else {
967 unsigned int pinctl = AC_PINCTL_IN_EN;
968 if (io_idx) /* set VREF for mic */
969 pinctl |= stac92xx_get_vref(codec, nid);
970 stac92xx_auto_set_pinctl(codec, nid, pinctl);
971 }
403d1944
MP
972 return 1;
973}
974
975#define STAC_CODEC_IO_SWITCH(xname, xpval) \
976 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
977 .name = xname, \
978 .index = 0, \
979 .info = stac92xx_io_switch_info, \
980 .get = stac92xx_io_switch_get, \
981 .put = stac92xx_io_switch_put, \
982 .private_value = xpval, \
983 }
984
985
c7d4b2fa
M
986enum {
987 STAC_CTL_WIDGET_VOL,
988 STAC_CTL_WIDGET_MUTE,
403d1944 989 STAC_CTL_WIDGET_IO_SWITCH,
c7d4b2fa
M
990};
991
c8b6bf9b 992static struct snd_kcontrol_new stac92xx_control_templates[] = {
c7d4b2fa
M
993 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
994 HDA_CODEC_MUTE(NULL, 0, 0, 0),
403d1944 995 STAC_CODEC_IO_SWITCH(NULL, 0),
c7d4b2fa
M
996};
997
998/* add dynamic controls */
999static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
1000{
c8b6bf9b 1001 struct snd_kcontrol_new *knew;
c7d4b2fa
M
1002
1003 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
1004 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
1005
1006 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
1007 if (! knew)
1008 return -ENOMEM;
1009 if (spec->kctl_alloc) {
1010 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
1011 kfree(spec->kctl_alloc);
1012 }
1013 spec->kctl_alloc = knew;
1014 spec->num_kctl_alloc = num;
1015 }
1016
1017 knew = &spec->kctl_alloc[spec->num_kctl_used];
1018 *knew = stac92xx_control_templates[type];
82fe0c58 1019 knew->name = kstrdup(name, GFP_KERNEL);
c7d4b2fa
M
1020 if (! knew->name)
1021 return -ENOMEM;
1022 knew->private_value = val;
1023 spec->num_kctl_used++;
1024 return 0;
1025}
1026
403d1944
MP
1027/* flag inputs as additional dynamic lineouts */
1028static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1029{
1030 struct sigmatel_spec *spec = codec->spec;
1031
1032 switch (cfg->line_outs) {
1033 case 3:
1034 /* add line-in as side */
1035 if (cfg->input_pins[AUTO_PIN_LINE]) {
1036 cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
1037 spec->line_switch = 1;
1038 cfg->line_outs++;
1039 }
1040 break;
1041 case 2:
1042 /* add line-in as clfe and mic as side */
1043 if (cfg->input_pins[AUTO_PIN_LINE]) {
1044 cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
1045 spec->line_switch = 1;
1046 cfg->line_outs++;
1047 }
1048 if (cfg->input_pins[AUTO_PIN_MIC]) {
1049 cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
1050 spec->mic_switch = 1;
1051 cfg->line_outs++;
1052 }
1053 break;
1054 case 1:
1055 /* add line-in as surr and mic as clfe */
1056 if (cfg->input_pins[AUTO_PIN_LINE]) {
1057 cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
1058 spec->line_switch = 1;
1059 cfg->line_outs++;
1060 }
1061 if (cfg->input_pins[AUTO_PIN_MIC]) {
1062 cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
1063 spec->mic_switch = 1;
1064 cfg->line_outs++;
1065 }
1066 break;
1067 }
1068
1069 return 0;
1070}
1071
3cc08dc6
MP
1072/*
1073 * XXX The line_out pin widget connection list may not be set to the
1074 * desired DAC nid. This is the case on 927x where ports A and B can
1075 * be routed to several DACs.
1076 *
1077 * This requires an analysis of the line-out/hp pin configuration
1078 * to provide a best fit for pin/DAC configurations that are routable.
1079 * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
1080 * A and B is not supported.
1081 */
c7d4b2fa 1082/* fill in the dac_nids table from the parsed pin configuration */
19039bd0
TI
1083static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1084 const struct auto_pin_cfg *cfg)
c7d4b2fa
M
1085{
1086 struct sigmatel_spec *spec = codec->spec;
1087 hda_nid_t nid;
1088 int i;
1089
1090 /* check the pins hardwired to audio widget */
1091 for (i = 0; i < cfg->line_outs; i++) {
1092 nid = cfg->line_out_pins[i];
1093 spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
1094 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1095 }
1096
82bc955f 1097 spec->multiout.num_dacs = cfg->line_outs;
c7d4b2fa
M
1098
1099 return 0;
1100}
1101
eb06ed8f
TI
1102/* create volume control/switch for the given prefx type */
1103static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
1104{
1105 char name[32];
1106 int err;
1107
1108 sprintf(name, "%s Playback Volume", pfx);
1109 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
1110 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1111 if (err < 0)
1112 return err;
1113 sprintf(name, "%s Playback Switch", pfx);
1114 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
1115 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1116 if (err < 0)
1117 return err;
1118 return 0;
1119}
1120
c7d4b2fa 1121/* add playback controls from the parsed DAC table */
19039bd0
TI
1122static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
1123 const struct auto_pin_cfg *cfg)
c7d4b2fa 1124{
19039bd0
TI
1125 static const char *chname[4] = {
1126 "Front", "Surround", NULL /*CLFE*/, "Side"
1127 };
c7d4b2fa
M
1128 hda_nid_t nid;
1129 int i, err;
1130
1131 for (i = 0; i < cfg->line_outs; i++) {
403d1944 1132 if (!spec->multiout.dac_nids[i])
c7d4b2fa
M
1133 continue;
1134
1135 nid = spec->multiout.dac_nids[i];
1136
1137 if (i == 2) {
1138 /* Center/LFE */
eb06ed8f
TI
1139 err = create_controls(spec, "Center", nid, 1);
1140 if (err < 0)
c7d4b2fa 1141 return err;
eb06ed8f
TI
1142 err = create_controls(spec, "LFE", nid, 2);
1143 if (err < 0)
c7d4b2fa
M
1144 return err;
1145 } else {
eb06ed8f
TI
1146 err = create_controls(spec, chname[i], nid, 3);
1147 if (err < 0)
c7d4b2fa
M
1148 return err;
1149 }
1150 }
1151
403d1944
MP
1152 if (spec->line_switch)
1153 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
1154 return err;
1155
1156 if (spec->mic_switch)
1157 if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
1158 return err;
1159
c7d4b2fa
M
1160 return 0;
1161}
1162
eb06ed8f 1163static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
c7d4b2fa 1164{
eb06ed8f 1165 int i;
c7d4b2fa 1166
eb06ed8f
TI
1167 for (i = 0; i < spec->multiout.num_dacs; i++) {
1168 if (spec->multiout.dac_nids[i] == nid)
1169 return 1;
1170 }
1171 if (spec->multiout.hp_nid == nid)
1172 return 1;
1173 return 0;
1174}
c7d4b2fa 1175
eb06ed8f
TI
1176static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
1177{
1178 if (!spec->multiout.hp_nid)
1179 spec->multiout.hp_nid = nid;
1180 else if (spec->multiout.num_dacs > 4) {
1181 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
1182 return 1;
1183 } else {
1184 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid;
1185 spec->multiout.num_dacs++;
1186 }
1187 return 0;
1188}
4e55096e 1189
eb06ed8f
TI
1190/* add playback controls for Speaker and HP outputs */
1191static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1192 struct auto_pin_cfg *cfg)
1193{
1194 struct sigmatel_spec *spec = codec->spec;
1195 hda_nid_t nid;
1196 int i, old_num_dacs, err;
1197
1198 old_num_dacs = spec->multiout.num_dacs;
1199 for (i = 0; i < cfg->hp_outs; i++) {
1200 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
1201 if (wid_caps & AC_WCAP_UNSOL_CAP)
1202 spec->hp_detect = 1;
1203 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
1204 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1205 if (check_in_dac_nids(spec, nid))
1206 nid = 0;
1207 if (! nid)
c7d4b2fa 1208 continue;
eb06ed8f
TI
1209 add_spec_dacs(spec, nid);
1210 }
1211 for (i = 0; i < cfg->speaker_outs; i++) {
1212 nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0,
1213 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1214 if (check_in_dac_nids(spec, nid))
1215 nid = 0;
1216 if (check_in_dac_nids(spec, nid))
1217 nid = 0;
1218 if (! nid)
1219 continue;
1220 add_spec_dacs(spec, nid);
c7d4b2fa
M
1221 }
1222
eb06ed8f
TI
1223 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1224 static const char *pfxs[] = {
1225 "Speaker", "External Speaker", "Speaker2",
1226 };
1227 err = create_controls(spec, pfxs[i - old_num_dacs],
1228 spec->multiout.dac_nids[i], 3);
1229 if (err < 0)
1230 return err;
1231 }
1232 if (spec->multiout.hp_nid) {
1233 const char *pfx;
1234 if (old_num_dacs == spec->multiout.num_dacs)
1235 pfx = "Master";
1236 else
1237 pfx = "Headphone";
1238 err = create_controls(spec, pfx, spec->multiout.hp_nid, 3);
1239 if (err < 0)
1240 return err;
1241 }
c7d4b2fa
M
1242
1243 return 0;
1244}
1245
8b65727b 1246/* labels for dmic mux inputs */
ddc2cec4 1247static const char *stac92xx_dmic_labels[5] = {
8b65727b
MP
1248 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1249 "Digital Mic 3", "Digital Mic 4"
1250};
1251
1252/* create playback/capture controls for input pins on dmic capable codecs */
1253static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1254 const struct auto_pin_cfg *cfg)
1255{
1256 struct sigmatel_spec *spec = codec->spec;
1257 struct hda_input_mux *dimux = &spec->private_dimux;
1258 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1259 int i, j;
1260
1261 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1262 dimux->items[dimux->num_items].index = 0;
1263 dimux->num_items++;
1264
1265 for (i = 0; i < spec->num_dmics; i++) {
1266 int index;
1267 int num_cons;
1268 unsigned int def_conf;
1269
1270 def_conf = snd_hda_codec_read(codec,
1271 spec->dmic_nids[i],
1272 0,
1273 AC_VERB_GET_CONFIG_DEFAULT,
1274 0);
1275 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1276 continue;
1277
1278 num_cons = snd_hda_get_connections(codec,
1279 spec->dmux_nid,
1280 con_lst,
1281 HDA_MAX_NUM_INPUTS);
1282 for (j = 0; j < num_cons; j++)
1283 if (con_lst[j] == spec->dmic_nids[i]) {
1284 index = j;
1285 goto found;
1286 }
1287 continue;
1288found:
1289 dimux->items[dimux->num_items].label =
1290 stac92xx_dmic_labels[dimux->num_items];
1291 dimux->items[dimux->num_items].index = index;
1292 dimux->num_items++;
1293 }
1294
1295 return 0;
1296}
1297
c7d4b2fa
M
1298/* create playback/capture controls for input pins */
1299static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
1300{
1301 struct sigmatel_spec *spec = codec->spec;
c7d4b2fa
M
1302 struct hda_input_mux *imux = &spec->private_imux;
1303 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1304 int i, j, k;
1305
1306 for (i = 0; i < AUTO_PIN_LAST; i++) {
314634bc
TI
1307 int index;
1308
1309 if (!cfg->input_pins[i])
1310 continue;
1311 index = -1;
1312 for (j = 0; j < spec->num_muxes; j++) {
1313 int num_cons;
1314 num_cons = snd_hda_get_connections(codec,
1315 spec->mux_nids[j],
1316 con_lst,
1317 HDA_MAX_NUM_INPUTS);
1318 for (k = 0; k < num_cons; k++)
1319 if (con_lst[k] == cfg->input_pins[i]) {
1320 index = k;
1321 goto found;
1322 }
c7d4b2fa 1323 }
314634bc
TI
1324 continue;
1325 found:
1326 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
1327 imux->items[imux->num_items].index = index;
1328 imux->num_items++;
c7d4b2fa
M
1329 }
1330
62fe78e9
SR
1331 if (imux->num_items == 1) {
1332 /*
1333 * Set the current input for the muxes.
1334 * The STAC9221 has two input muxes with identical source
1335 * NID lists. Hopefully this won't get confused.
1336 */
1337 for (i = 0; i < spec->num_muxes; i++) {
1338 snd_hda_codec_write(codec, spec->mux_nids[i], 0,
1339 AC_VERB_SET_CONNECT_SEL,
1340 imux->items[0].index);
1341 }
1342 }
1343
c7d4b2fa
M
1344 return 0;
1345}
1346
c7d4b2fa
M
1347static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
1348{
1349 struct sigmatel_spec *spec = codec->spec;
1350 int i;
1351
1352 for (i = 0; i < spec->autocfg.line_outs; i++) {
1353 hda_nid_t nid = spec->autocfg.line_out_pins[i];
1354 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
1355 }
1356}
1357
1358static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
1359{
1360 struct sigmatel_spec *spec = codec->spec;
eb06ed8f 1361 int i;
c7d4b2fa 1362
eb06ed8f
TI
1363 for (i = 0; i < spec->autocfg.hp_outs; i++) {
1364 hda_nid_t pin;
1365 pin = spec->autocfg.hp_pins[i];
1366 if (pin) /* connect to front */
1367 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
1368 }
1369 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
1370 hda_nid_t pin;
1371 pin = spec->autocfg.speaker_pins[i];
1372 if (pin) /* connect to front */
1373 stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
1374 }
c7d4b2fa
M
1375}
1376
3cc08dc6 1377static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
c7d4b2fa
M
1378{
1379 struct sigmatel_spec *spec = codec->spec;
1380 int err;
1381
8b65727b
MP
1382 if ((err = snd_hda_parse_pin_def_config(codec,
1383 &spec->autocfg,
1384 spec->dmic_nids)) < 0)
c7d4b2fa 1385 return err;
82bc955f 1386 if (! spec->autocfg.line_outs)
869264c4 1387 return 0; /* can't find valid pin config */
19039bd0 1388
403d1944
MP
1389 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
1390 return err;
19039bd0
TI
1391 if (spec->multiout.num_dacs == 0)
1392 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
1393 return err;
c7d4b2fa
M
1394
1395 if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
1396 (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 ||
1397 (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
1398 return err;
1399
8b65727b
MP
1400 if (spec->num_dmics > 0)
1401 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
1402 &spec->autocfg)) < 0)
1403 return err;
1404
c7d4b2fa 1405 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
403d1944 1406 if (spec->multiout.max_channels > 2)
c7d4b2fa 1407 spec->surr_switch = 1;
c7d4b2fa 1408
82bc955f 1409 if (spec->autocfg.dig_out_pin)
3cc08dc6 1410 spec->multiout.dig_out_nid = dig_out;
82bc955f 1411 if (spec->autocfg.dig_in_pin)
3cc08dc6 1412 spec->dig_in_nid = dig_in;
c7d4b2fa
M
1413
1414 if (spec->kctl_alloc)
1415 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1416
1417 spec->input_mux = &spec->private_imux;
8b65727b 1418 spec->dinput_mux = &spec->private_dimux;
c7d4b2fa
M
1419
1420 return 1;
1421}
1422
82bc955f
TI
1423/* add playback controls for HP output */
1424static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
1425 struct auto_pin_cfg *cfg)
1426{
1427 struct sigmatel_spec *spec = codec->spec;
eb06ed8f 1428 hda_nid_t pin = cfg->hp_pins[0];
82bc955f
TI
1429 unsigned int wid_caps;
1430
1431 if (! pin)
1432 return 0;
1433
1434 wid_caps = get_wcaps(codec, pin);
505cb341 1435 if (wid_caps & AC_WCAP_UNSOL_CAP)
82bc955f 1436 spec->hp_detect = 1;
82bc955f
TI
1437
1438 return 0;
1439}
1440
160ea0dc
RF
1441/* add playback controls for LFE output */
1442static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
1443 struct auto_pin_cfg *cfg)
1444{
1445 struct sigmatel_spec *spec = codec->spec;
1446 int err;
1447 hda_nid_t lfe_pin = 0x0;
1448 int i;
1449
1450 /*
1451 * search speaker outs and line outs for a mono speaker pin
1452 * with an amp. If one is found, add LFE controls
1453 * for it.
1454 */
1455 for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
1456 hda_nid_t pin = spec->autocfg.speaker_pins[i];
1457 unsigned long wcaps = get_wcaps(codec, pin);
1458 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
1459 if (wcaps == AC_WCAP_OUT_AMP)
1460 /* found a mono speaker with an amp, must be lfe */
1461 lfe_pin = pin;
1462 }
1463
1464 /* if speaker_outs is 0, then speakers may be in line_outs */
1465 if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
1466 for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
1467 hda_nid_t pin = spec->autocfg.line_out_pins[i];
1468 unsigned long cfg;
1469 cfg = snd_hda_codec_read(codec, pin, 0,
1470 AC_VERB_GET_CONFIG_DEFAULT,
1471 0x00);
1472 if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) {
1473 unsigned long wcaps = get_wcaps(codec, pin);
1474 wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
1475 if (wcaps == AC_WCAP_OUT_AMP)
1476 /* found a mono speaker with an amp,
1477 must be lfe */
1478 lfe_pin = pin;
1479 }
1480 }
1481 }
1482
1483 if (lfe_pin) {
eb06ed8f 1484 err = create_controls(spec, "LFE", lfe_pin, 1);
160ea0dc
RF
1485 if (err < 0)
1486 return err;
1487 }
1488
1489 return 0;
1490}
1491
c7d4b2fa
M
1492static int stac9200_parse_auto_config(struct hda_codec *codec)
1493{
1494 struct sigmatel_spec *spec = codec->spec;
1495 int err;
1496
df694daa 1497 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
c7d4b2fa
M
1498 return err;
1499
1500 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
1501 return err;
1502
82bc955f
TI
1503 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
1504 return err;
1505
160ea0dc
RF
1506 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
1507 return err;
1508
82bc955f 1509 if (spec->autocfg.dig_out_pin)
c7d4b2fa 1510 spec->multiout.dig_out_nid = 0x05;
82bc955f 1511 if (spec->autocfg.dig_in_pin)
c7d4b2fa 1512 spec->dig_in_nid = 0x04;
c7d4b2fa
M
1513
1514 if (spec->kctl_alloc)
1515 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1516
1517 spec->input_mux = &spec->private_imux;
8b65727b 1518 spec->dinput_mux = &spec->private_dimux;
c7d4b2fa
M
1519
1520 return 1;
1521}
1522
62fe78e9
SR
1523/*
1524 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
1525 * funky external mute control using GPIO pins.
1526 */
1527
1528static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
1529{
1530 unsigned int gpiostate, gpiomask, gpiodir;
1531
1532 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1533 AC_VERB_GET_GPIO_DATA, 0);
1534
1535 if (!muted)
1536 gpiostate |= (1 << pin);
1537 else
1538 gpiostate &= ~(1 << pin);
1539
1540 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1541 AC_VERB_GET_GPIO_MASK, 0);
1542 gpiomask |= (1 << pin);
1543
1544 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1545 AC_VERB_GET_GPIO_DIRECTION, 0);
1546 gpiodir |= (1 << pin);
1547
1548 /* AppleHDA seems to do this -- WTF is this verb?? */
1549 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
1550
1551 snd_hda_codec_write(codec, codec->afg, 0,
1552 AC_VERB_SET_GPIO_MASK, gpiomask);
1553 snd_hda_codec_write(codec, codec->afg, 0,
1554 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1555
1556 msleep(1);
1557
1558 snd_hda_codec_write(codec, codec->afg, 0,
1559 AC_VERB_SET_GPIO_DATA, gpiostate);
1560}
1561
314634bc
TI
1562static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
1563 unsigned int event)
1564{
1565 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
1566 snd_hda_codec_write(codec, nid, 0,
1567 AC_VERB_SET_UNSOLICITED_ENABLE,
1568 (AC_USRSP_EN | event));
1569}
1570
c7d4b2fa
M
1571static int stac92xx_init(struct hda_codec *codec)
1572{
1573 struct sigmatel_spec *spec = codec->spec;
82bc955f
TI
1574 struct auto_pin_cfg *cfg = &spec->autocfg;
1575 int i;
c7d4b2fa 1576
c7d4b2fa
M
1577 snd_hda_sequence_write(codec, spec->init);
1578
82bc955f
TI
1579 /* set up pins */
1580 if (spec->hp_detect) {
505cb341 1581 /* Enable unsolicited responses on the HP widget */
eb06ed8f 1582 for (i = 0; i < cfg->hp_outs; i++)
314634bc
TI
1583 enable_pin_detect(codec, cfg->hp_pins[i],
1584 STAC_HP_EVENT);
eb995a8c 1585 stac92xx_auto_init_hp_out(codec);
82bc955f
TI
1586 /* fake event to set up pins */
1587 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
1588 } else {
1589 stac92xx_auto_init_multi_out(codec);
1590 stac92xx_auto_init_hp_out(codec);
1591 }
1592 for (i = 0; i < AUTO_PIN_LAST; i++) {
c960a03b
TI
1593 hda_nid_t nid = cfg->input_pins[i];
1594 if (nid) {
1595 unsigned int pinctl = AC_PINCTL_IN_EN;
1596 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
1597 pinctl |= stac92xx_get_vref(codec, nid);
1598 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1599 }
82bc955f 1600 }
8b65727b
MP
1601 if (spec->num_dmics > 0)
1602 for (i = 0; i < spec->num_dmics; i++)
1603 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
1604 AC_PINCTL_IN_EN);
1605
82bc955f
TI
1606 if (cfg->dig_out_pin)
1607 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
1608 AC_PINCTL_OUT_EN);
1609 if (cfg->dig_in_pin)
1610 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
1611 AC_PINCTL_IN_EN);
1612
62fe78e9
SR
1613 if (spec->gpio_mute) {
1614 stac922x_gpio_mute(codec, 0, 0);
1615 stac922x_gpio_mute(codec, 1, 0);
1616 }
1617
c7d4b2fa
M
1618 return 0;
1619}
1620
2f2f4251
M
1621static void stac92xx_free(struct hda_codec *codec)
1622{
c7d4b2fa
M
1623 struct sigmatel_spec *spec = codec->spec;
1624 int i;
1625
1626 if (! spec)
1627 return;
1628
1629 if (spec->kctl_alloc) {
1630 for (i = 0; i < spec->num_kctl_used; i++)
1631 kfree(spec->kctl_alloc[i].name);
1632 kfree(spec->kctl_alloc);
1633 }
1634
11b44bbd
RF
1635 if (spec->bios_pin_configs)
1636 kfree(spec->bios_pin_configs);
1637
c7d4b2fa 1638 kfree(spec);
2f2f4251
M
1639}
1640
4e55096e
M
1641static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
1642 unsigned int flag)
1643{
1644 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
1645 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
314634bc
TI
1646 if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN))
1647 return;
4e55096e
M
1648 snd_hda_codec_write(codec, nid, 0,
1649 AC_VERB_SET_PIN_WIDGET_CONTROL,
1650 pin_ctl | flag);
1651}
1652
1653static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
1654 unsigned int flag)
1655{
1656 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
1657 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
1658 snd_hda_codec_write(codec, nid, 0,
1659 AC_VERB_SET_PIN_WIDGET_CONTROL,
1660 pin_ctl & ~flag);
1661}
1662
314634bc
TI
1663static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
1664{
1665 if (!nid)
1666 return 0;
1667 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
1668 & (1 << 31))
1669 return 1;
1670 return 0;
1671}
1672
1673static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
4e55096e
M
1674{
1675 struct sigmatel_spec *spec = codec->spec;
1676 struct auto_pin_cfg *cfg = &spec->autocfg;
1677 int i, presence;
1678
eb06ed8f
TI
1679 presence = 0;
1680 for (i = 0; i < cfg->hp_outs; i++) {
314634bc
TI
1681 presence = get_pin_presence(codec, cfg->hp_pins[i]);
1682 if (presence)
1683 break;
eb06ed8f 1684 }
4e55096e
M
1685
1686 if (presence) {
1687 /* disable lineouts, enable hp */
1688 for (i = 0; i < cfg->line_outs; i++)
1689 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
1690 AC_PINCTL_OUT_EN);
eb06ed8f
TI
1691 for (i = 0; i < cfg->speaker_outs; i++)
1692 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
1693 AC_PINCTL_OUT_EN);
4e55096e
M
1694 } else {
1695 /* enable lineouts, disable hp */
1696 for (i = 0; i < cfg->line_outs; i++)
1697 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
1698 AC_PINCTL_OUT_EN);
eb06ed8f
TI
1699 for (i = 0; i < cfg->speaker_outs; i++)
1700 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
1701 AC_PINCTL_OUT_EN);
4e55096e
M
1702 }
1703}
1704
314634bc
TI
1705static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
1706{
1707 switch (res >> 26) {
1708 case STAC_HP_EVENT:
1709 stac92xx_hp_detect(codec, res);
1710 break;
1711 }
1712}
1713
ff6fdc37
M
1714#ifdef CONFIG_PM
1715static int stac92xx_resume(struct hda_codec *codec)
1716{
1717 struct sigmatel_spec *spec = codec->spec;
1718 int i;
1719
1720 stac92xx_init(codec);
11b44bbd 1721 stac92xx_set_config_regs(codec);
ff6fdc37
M
1722 for (i = 0; i < spec->num_mixers; i++)
1723 snd_hda_resume_ctls(codec, spec->mixers[i]);
1724 if (spec->multiout.dig_out_nid)
1725 snd_hda_resume_spdif_out(codec);
1726 if (spec->dig_in_nid)
1727 snd_hda_resume_spdif_in(codec);
1728
1729 return 0;
1730}
1731#endif
1732
2f2f4251
M
1733static struct hda_codec_ops stac92xx_patch_ops = {
1734 .build_controls = stac92xx_build_controls,
1735 .build_pcms = stac92xx_build_pcms,
1736 .init = stac92xx_init,
1737 .free = stac92xx_free,
4e55096e 1738 .unsol_event = stac92xx_unsol_event,
ff6fdc37
M
1739#ifdef CONFIG_PM
1740 .resume = stac92xx_resume,
1741#endif
2f2f4251
M
1742};
1743
1744static int patch_stac9200(struct hda_codec *codec)
1745{
1746 struct sigmatel_spec *spec;
c7d4b2fa 1747 int err;
2f2f4251 1748
e560d8d8 1749 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2f2f4251
M
1750 if (spec == NULL)
1751 return -ENOMEM;
1752
1753 codec->spec = spec;
11b44bbd
RF
1754 spec->num_pins = 8;
1755 spec->pin_nids = stac9200_pin_nids;
f5fcc13c
TI
1756 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
1757 stac9200_models,
1758 stac9200_cfg_tbl);
11b44bbd
RF
1759 if (spec->board_config < 0) {
1760 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
1761 err = stac92xx_save_bios_config_regs(codec);
1762 if (err < 0) {
1763 stac92xx_free(codec);
1764 return err;
1765 }
1766 spec->pin_configs = spec->bios_pin_configs;
1767 } else {
403d1944
MP
1768 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
1769 stac92xx_set_config_regs(codec);
1770 }
2f2f4251
M
1771
1772 spec->multiout.max_channels = 2;
1773 spec->multiout.num_dacs = 1;
1774 spec->multiout.dac_nids = stac9200_dac_nids;
1775 spec->adc_nids = stac9200_adc_nids;
1776 spec->mux_nids = stac9200_mux_nids;
dabbed6f 1777 spec->num_muxes = 1;
8b65727b 1778 spec->num_dmics = 0;
c7d4b2fa
M
1779
1780 spec->init = stac9200_core_init;
2f2f4251 1781 spec->mixer = stac9200_mixer;
c7d4b2fa
M
1782
1783 err = stac9200_parse_auto_config(codec);
1784 if (err < 0) {
1785 stac92xx_free(codec);
1786 return err;
1787 }
2f2f4251
M
1788
1789 codec->patch_ops = stac92xx_patch_ops;
1790
1791 return 0;
1792}
1793
8e21c34c
TD
1794static int patch_stac925x(struct hda_codec *codec)
1795{
1796 struct sigmatel_spec *spec;
1797 int err;
1798
1799 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1800 if (spec == NULL)
1801 return -ENOMEM;
1802
1803 codec->spec = spec;
1804 spec->num_pins = 8;
1805 spec->pin_nids = stac925x_pin_nids;
1806 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
1807 stac925x_models,
1808 stac925x_cfg_tbl);
9e507abd 1809 again:
8e21c34c
TD
1810 if (spec->board_config < 0) {
1811 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n");
1812 err = stac92xx_save_bios_config_regs(codec);
1813 if (err < 0) {
1814 stac92xx_free(codec);
1815 return err;
1816 }
1817 spec->pin_configs = spec->bios_pin_configs;
1818 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
1819 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
1820 stac92xx_set_config_regs(codec);
1821 }
1822
1823 spec->multiout.max_channels = 2;
1824 spec->multiout.num_dacs = 1;
1825 spec->multiout.dac_nids = stac925x_dac_nids;
1826 spec->adc_nids = stac925x_adc_nids;
1827 spec->mux_nids = stac925x_mux_nids;
1828 spec->num_muxes = 1;
1829 spec->num_dmics = 0;
1830
1831 spec->init = stac925x_core_init;
1832 spec->mixer = stac925x_mixer;
1833
1834 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
9e507abd
TI
1835 if (!err) {
1836 if (spec->board_config < 0) {
1837 printk(KERN_WARNING "hda_codec: No auto-config is "
1838 "available, default to model=ref\n");
1839 spec->board_config = STAC_925x_REF;
1840 goto again;
1841 }
1842 err = -EINVAL;
1843 }
8e21c34c
TD
1844 if (err < 0) {
1845 stac92xx_free(codec);
1846 return err;
1847 }
1848
1849 codec->patch_ops = stac92xx_patch_ops;
1850
1851 return 0;
1852}
1853
2f2f4251
M
1854static int patch_stac922x(struct hda_codec *codec)
1855{
1856 struct sigmatel_spec *spec;
c7d4b2fa 1857 int err;
2f2f4251 1858
e560d8d8 1859 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2f2f4251
M
1860 if (spec == NULL)
1861 return -ENOMEM;
1862
1863 codec->spec = spec;
11b44bbd
RF
1864 spec->num_pins = 10;
1865 spec->pin_nids = stac922x_pin_nids;
f5fcc13c
TI
1866 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
1867 stac922x_models,
1868 stac922x_cfg_tbl);
9e507abd 1869 again:
11b44bbd
RF
1870 if (spec->board_config < 0) {
1871 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
1872 "using BIOS defaults\n");
1873 err = stac92xx_save_bios_config_regs(codec);
1874 if (err < 0) {
1875 stac92xx_free(codec);
1876 return err;
1877 }
1878 spec->pin_configs = spec->bios_pin_configs;
1879 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
403d1944
MP
1880 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
1881 stac92xx_set_config_regs(codec);
1882 }
2f2f4251 1883
c7d4b2fa
M
1884 spec->adc_nids = stac922x_adc_nids;
1885 spec->mux_nids = stac922x_mux_nids;
1886 spec->num_muxes = 2;
8b65727b 1887 spec->num_dmics = 0;
c7d4b2fa
M
1888
1889 spec->init = stac922x_core_init;
2f2f4251 1890 spec->mixer = stac922x_mixer;
c7d4b2fa
M
1891
1892 spec->multiout.dac_nids = spec->dac_nids;
19039bd0 1893
3cc08dc6 1894 err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
9e507abd
TI
1895 if (!err) {
1896 if (spec->board_config < 0) {
1897 printk(KERN_WARNING "hda_codec: No auto-config is "
1898 "available, default to model=ref\n");
1899 spec->board_config = STAC_D945_REF;
1900 goto again;
1901 }
1902 err = -EINVAL;
1903 }
3cc08dc6
MP
1904 if (err < 0) {
1905 stac92xx_free(codec);
1906 return err;
1907 }
1908
62fe78e9
SR
1909 if (spec->board_config == STAC_MACMINI)
1910 spec->gpio_mute = 1;
1911
3cc08dc6
MP
1912 codec->patch_ops = stac92xx_patch_ops;
1913
1914 return 0;
1915}
1916
1917static int patch_stac927x(struct hda_codec *codec)
1918{
1919 struct sigmatel_spec *spec;
1920 int err;
1921
1922 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1923 if (spec == NULL)
1924 return -ENOMEM;
1925
1926 codec->spec = spec;
11b44bbd
RF
1927 spec->num_pins = 14;
1928 spec->pin_nids = stac927x_pin_nids;
f5fcc13c
TI
1929 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
1930 stac927x_models,
1931 stac927x_cfg_tbl);
9e507abd 1932 again:
11b44bbd 1933 if (spec->board_config < 0) {
3cc08dc6 1934 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
11b44bbd
RF
1935 err = stac92xx_save_bios_config_regs(codec);
1936 if (err < 0) {
1937 stac92xx_free(codec);
1938 return err;
1939 }
1940 spec->pin_configs = spec->bios_pin_configs;
1941 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
3cc08dc6
MP
1942 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
1943 stac92xx_set_config_regs(codec);
1944 }
1945
81d3dbde 1946 switch (spec->board_config) {
93ed1503 1947 case STAC_D965_3ST:
81d3dbde
TD
1948 spec->adc_nids = stac927x_adc_nids;
1949 spec->mux_nids = stac927x_mux_nids;
1950 spec->num_muxes = 3;
8b65727b 1951 spec->num_dmics = 0;
93ed1503 1952 spec->init = d965_core_init;
81d3dbde
TD
1953 spec->mixer = stac9227_mixer;
1954 break;
93ed1503
TD
1955 case STAC_D965_5ST:
1956 spec->adc_nids = stac927x_adc_nids;
1957 spec->mux_nids = stac927x_mux_nids;
1958 spec->num_muxes = 3;
8b65727b 1959 spec->num_dmics = 0;
93ed1503 1960 spec->init = d965_core_init;
81d3dbde
TD
1961 spec->mixer = stac9227_mixer;
1962 break;
1963 default:
1964 spec->adc_nids = stac927x_adc_nids;
1965 spec->mux_nids = stac927x_mux_nids;
1966 spec->num_muxes = 3;
8b65727b 1967 spec->num_dmics = 0;
81d3dbde
TD
1968 spec->init = stac927x_core_init;
1969 spec->mixer = stac927x_mixer;
1970 }
3cc08dc6
MP
1971
1972 spec->multiout.dac_nids = spec->dac_nids;
1973
1974 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
9e507abd
TI
1975 if (!err) {
1976 if (spec->board_config < 0) {
1977 printk(KERN_WARNING "hda_codec: No auto-config is "
1978 "available, default to model=ref\n");
1979 spec->board_config = STAC_D965_REF;
1980 goto again;
1981 }
1982 err = -EINVAL;
1983 }
c7d4b2fa
M
1984 if (err < 0) {
1985 stac92xx_free(codec);
1986 return err;
1987 }
2f2f4251
M
1988
1989 codec->patch_ops = stac92xx_patch_ops;
1990
1991 return 0;
1992}
1993
f3302a59
MP
1994static int patch_stac9205(struct hda_codec *codec)
1995{
1996 struct sigmatel_spec *spec;
1997 int err;
1998
1999 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2000 if (spec == NULL)
2001 return -ENOMEM;
2002
2003 codec->spec = spec;
11b44bbd
RF
2004 spec->num_pins = 14;
2005 spec->pin_nids = stac9205_pin_nids;
f5fcc13c
TI
2006 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2007 stac9205_models,
2008 stac9205_cfg_tbl);
9e507abd 2009 again:
11b44bbd
RF
2010 if (spec->board_config < 0) {
2011 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
2012 err = stac92xx_save_bios_config_regs(codec);
2013 if (err < 0) {
2014 stac92xx_free(codec);
2015 return err;
2016 }
2017 spec->pin_configs = spec->bios_pin_configs;
2018 } else {
f3302a59
MP
2019 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
2020 stac92xx_set_config_regs(codec);
2021 }
2022
2023 spec->adc_nids = stac9205_adc_nids;
2024 spec->mux_nids = stac9205_mux_nids;
8b65727b
MP
2025 spec->num_muxes = 2;
2026 spec->dmic_nids = stac9205_dmic_nids;
2027 spec->num_dmics = 2;
2028 spec->dmux_nid = 0x1d;
f3302a59
MP
2029
2030 spec->init = stac9205_core_init;
2031 spec->mixer = stac9205_mixer;
2032
2033 spec->multiout.dac_nids = spec->dac_nids;
2034
33382403
MP
2035 /* Configure GPIO0 as EAPD output */
2036 snd_hda_codec_write(codec, codec->afg, 0,
2037 AC_VERB_SET_GPIO_DIRECTION, 0x00000001);
2038 /* Configure GPIO0 as CMOS */
2039 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
2040 /* Assert GPIO0 high */
2041 snd_hda_codec_write(codec, codec->afg, 0,
2042 AC_VERB_SET_GPIO_DATA, 0x00000001);
2043 /* Enable GPIO0 */
2044 snd_hda_codec_write(codec, codec->afg, 0,
2045 AC_VERB_SET_GPIO_MASK, 0x00000001);
2046
f3302a59 2047 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
9e507abd
TI
2048 if (!err) {
2049 if (spec->board_config < 0) {
2050 printk(KERN_WARNING "hda_codec: No auto-config is "
2051 "available, default to model=ref\n");
2052 spec->board_config = STAC_9205_REF;
2053 goto again;
2054 }
2055 err = -EINVAL;
2056 }
f3302a59
MP
2057 if (err < 0) {
2058 stac92xx_free(codec);
2059 return err;
2060 }
2061
2062 codec->patch_ops = stac92xx_patch_ops;
2063
2064 return 0;
2065}
2066
db064e50 2067/*
6d859065 2068 * STAC9872 hack
db064e50
TI
2069 */
2070
99ccc560 2071/* static config for Sony VAIO FE550G and Sony VAIO AR */
db064e50
TI
2072static hda_nid_t vaio_dacs[] = { 0x2 };
2073#define VAIO_HP_DAC 0x5
2074static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
2075static hda_nid_t vaio_mux_nids[] = { 0x15 };
2076
2077static struct hda_input_mux vaio_mux = {
2078 .num_items = 2,
2079 .items = {
d773781c
TI
2080 /* { "HP", 0x0 }, */
2081 { "Line", 0x1 },
db064e50
TI
2082 { "Mic", 0x2 },
2083 { "PCM", 0x3 },
2084 }
2085};
2086
2087static struct hda_verb vaio_init[] = {
2088 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2089 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2090 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2091 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2092 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */
2094 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2095 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2096 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2097 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2099 {}
2100};
2101
6d859065
GM
2102static struct hda_verb vaio_ar_init[] = {
2103 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
2104 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
2105 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2106 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2107/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2109 {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */
2110 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2111 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2112/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
2113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
2114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
2115 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
2116 {}
2117};
2118
db064e50
TI
2119/* bind volumes of both NID 0x02 and 0x05 */
2120static int vaio_master_vol_put(struct snd_kcontrol *kcontrol,
2121 struct snd_ctl_elem_value *ucontrol)
2122{
2123 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2124 long *valp = ucontrol->value.integer.value;
2125 int change;
2126
2127 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
2128 0x7f, valp[0] & 0x7f);
2129 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
2130 0x7f, valp[1] & 0x7f);
2131 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
2132 0x7f, valp[0] & 0x7f);
2133 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
2134 0x7f, valp[1] & 0x7f);
2135 return change;
2136}
2137
2138/* bind volumes of both NID 0x02 and 0x05 */
2139static int vaio_master_sw_put(struct snd_kcontrol *kcontrol,
2140 struct snd_ctl_elem_value *ucontrol)
2141{
2142 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2143 long *valp = ucontrol->value.integer.value;
2144 int change;
2145
2146 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
a9393d70 2147 0x80, (valp[0] ? 0 : 0x80));
db064e50 2148 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
a9393d70 2149 0x80, (valp[1] ? 0 : 0x80));
db064e50 2150 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
a9393d70 2151 0x80, (valp[0] ? 0 : 0x80));
db064e50 2152 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
a9393d70 2153 0x80, (valp[1] ? 0 : 0x80));
db064e50
TI
2154 return change;
2155}
2156
2157static struct snd_kcontrol_new vaio_mixer[] = {
2158 {
2159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2160 .name = "Master Playback Volume",
2161 .info = snd_hda_mixer_amp_volume_info,
2162 .get = snd_hda_mixer_amp_volume_get,
2163 .put = vaio_master_vol_put,
c2566524 2164 .tlv = { .c = snd_hda_mixer_amp_tlv },
db064e50
TI
2165 .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2166 },
2167 {
2168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2169 .name = "Master Playback Switch",
2170 .info = snd_hda_mixer_amp_switch_info,
2171 .get = snd_hda_mixer_amp_switch_get,
2172 .put = vaio_master_sw_put,
2173 .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2174 },
2175 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2176 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2177 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2178 {
2179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2180 .name = "Capture Source",
2181 .count = 1,
2182 .info = stac92xx_mux_enum_info,
2183 .get = stac92xx_mux_enum_get,
2184 .put = stac92xx_mux_enum_put,
2185 },
2186 {}
2187};
2188
6d859065
GM
2189static struct snd_kcontrol_new vaio_ar_mixer[] = {
2190 {
2191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2192 .name = "Master Playback Volume",
2193 .info = snd_hda_mixer_amp_volume_info,
2194 .get = snd_hda_mixer_amp_volume_get,
2195 .put = vaio_master_vol_put,
2196 .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2197 },
2198 {
2199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2200 .name = "Master Playback Switch",
2201 .info = snd_hda_mixer_amp_switch_info,
2202 .get = snd_hda_mixer_amp_switch_get,
2203 .put = vaio_master_sw_put,
2204 .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
2205 },
2206 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
2207 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
2208 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
2209 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
2210 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
2211 {
2212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2213 .name = "Capture Source",
2214 .count = 1,
2215 .info = stac92xx_mux_enum_info,
2216 .get = stac92xx_mux_enum_get,
2217 .put = stac92xx_mux_enum_put,
2218 },
2219 {}
2220};
2221
2222static struct hda_codec_ops stac9872_patch_ops = {
db064e50
TI
2223 .build_controls = stac92xx_build_controls,
2224 .build_pcms = stac92xx_build_pcms,
2225 .init = stac92xx_init,
2226 .free = stac92xx_free,
2227#ifdef CONFIG_PM
2228 .resume = stac92xx_resume,
2229#endif
2230};
2231
6d859065
GM
2232enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
2233 CXD9872RD_VAIO,
2234 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
2235 STAC9872AK_VAIO,
2236 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
2237 STAC9872K_VAIO,
2238 /* AR Series. id=0x83847664 and subsys=104D1300 */
f5fcc13c
TI
2239 CXD9872AKD_VAIO,
2240 STAC_9872_MODELS,
2241};
2242
2243static const char *stac9872_models[STAC_9872_MODELS] = {
2244 [CXD9872RD_VAIO] = "vaio",
2245 [CXD9872AKD_VAIO] = "vaio-ar",
2246};
2247
2248static struct snd_pci_quirk stac9872_cfg_tbl[] = {
2249 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
2250 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
2251 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
db064e50
TI
2252 {}
2253};
2254
6d859065 2255static int patch_stac9872(struct hda_codec *codec)
db064e50
TI
2256{
2257 struct sigmatel_spec *spec;
2258 int board_config;
2259
f5fcc13c
TI
2260 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
2261 stac9872_models,
2262 stac9872_cfg_tbl);
db064e50
TI
2263 if (board_config < 0)
2264 /* unknown config, let generic-parser do its job... */
2265 return snd_hda_parse_generic_codec(codec);
2266
2267 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2268 if (spec == NULL)
2269 return -ENOMEM;
2270
2271 codec->spec = spec;
2272 switch (board_config) {
6d859065
GM
2273 case CXD9872RD_VAIO:
2274 case STAC9872AK_VAIO:
2275 case STAC9872K_VAIO:
db064e50
TI
2276 spec->mixer = vaio_mixer;
2277 spec->init = vaio_init;
2278 spec->multiout.max_channels = 2;
2279 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
2280 spec->multiout.dac_nids = vaio_dacs;
2281 spec->multiout.hp_nid = VAIO_HP_DAC;
2282 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
2283 spec->adc_nids = vaio_adcs;
2284 spec->input_mux = &vaio_mux;
2285 spec->mux_nids = vaio_mux_nids;
2286 break;
6d859065
GM
2287
2288 case CXD9872AKD_VAIO:
2289 spec->mixer = vaio_ar_mixer;
2290 spec->init = vaio_ar_init;
2291 spec->multiout.max_channels = 2;
2292 spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
2293 spec->multiout.dac_nids = vaio_dacs;
2294 spec->multiout.hp_nid = VAIO_HP_DAC;
2295 spec->num_adcs = ARRAY_SIZE(vaio_adcs);
2296 spec->adc_nids = vaio_adcs;
2297 spec->input_mux = &vaio_mux;
2298 spec->mux_nids = vaio_mux_nids;
2299 break;
db064e50
TI
2300 }
2301
6d859065 2302 codec->patch_ops = stac9872_patch_ops;
db064e50
TI
2303 return 0;
2304}
2305
2306
2f2f4251
M
2307/*
2308 * patch entries
2309 */
2310struct hda_codec_preset snd_hda_preset_sigmatel[] = {
2311 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
2312 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
2313 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
2314 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
2315 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
2316 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
2317 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
22a27c7f
MP
2318 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
2319 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
2320 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
2321 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
2322 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
2323 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
3cc08dc6
MP
2324 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
2325 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
2326 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
2327 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
2328 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
2329 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
2330 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
2331 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
2332 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
2333 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
8e21c34c
TD
2334 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
2335 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
2336 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
2337 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
2338 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
2339 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
6d859065
GM
2340 /* The following does not take into account .id=0x83847661 when subsys =
2341 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
2342 * currently not fully supported.
2343 */
2344 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
2345 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
2346 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
f3302a59
MP
2347 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
2348 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
2349 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
2350 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
2351 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
2352 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
2353 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
2354 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
2f2f4251
M
2355 {} /* terminator */
2356};