changelog shortlog tags changeset manifest revisions annotate raw

pci/hda/patch_sigmatel.c

changeset 5086: 6ee58da0b892
parent:200fc3a7ef62
child:c0f8873b6fbf
author: tiwai
date: Tue May 29 19:01:37 2007 +0200 (4 years ago)
permissions: -rw-r--r--
description: hda-codec - Fix STAC922x capture boost level

STAC922x provides the capture boost level up to 4, but actually it
works only up to 2. Since the range of the mixer is automatically
defined from amp-capability bits, we need to override the value
beforehand. snd_hda_override_amp_caps() is introduced for this
purpose.

The function patch_stac922x() calls this for NID 0x12 (Mux Capture
Volume). This should fix another recording problem on Intel Macs.

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