2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for SigmaTel STAC92xx
6 * Copyright (c) 2005 Embedded Alley Solutions, Inc.
7 * Matt Porter <mporter@embeddedalley.com>
9 * Based on patch_cmedia.c and patch_realtek.c
10 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
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.
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.
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
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"
37 #define NUM_CONTROL_ALLOC 32
38 #define STAC_HP_EVENT 0x37
41 #define STAC_D945GTP3 1
42 #define STAC_D945GTP5 2
43 #define STAC_MACMINI 3
44 #define STAC_922X_MODELS 4 /* number of 922x models */
45 #define STAC_D965_3ST 4
46 #define STAC_D965_5ST 5
47 #define STAC_927X_MODELS 6 /* number of 922x models */
49 struct sigmatel_spec
{
50 struct snd_kcontrol_new
*mixers
[4];
51 unsigned int num_mixers
;
54 unsigned int surr_switch
: 1;
55 unsigned int line_switch
: 1;
56 unsigned int mic_switch
: 1;
57 unsigned int alt_switch
: 1;
58 unsigned int hp_detect
: 1;
59 unsigned int gpio_mute
: 1;
62 struct hda_multi_out multiout
;
63 hda_nid_t dac_nids
[5];
67 unsigned int num_adcs
;
69 unsigned int num_muxes
;
74 unsigned int num_pins
;
75 unsigned int *pin_configs
;
76 unsigned int *bios_pin_configs
;
78 /* codec specific stuff */
79 struct hda_verb
*init
;
80 struct snd_kcontrol_new
*mixer
;
83 struct hda_input_mux
*input_mux
;
84 unsigned int cur_mux
[3];
87 unsigned int io_switch
[2];
89 struct hda_pcm pcm_rec
[2]; /* PCM information */
91 /* dynamic controls and input_mux */
92 struct auto_pin_cfg autocfg
;
93 unsigned int num_kctl_alloc
, num_kctl_used
;
94 struct snd_kcontrol_new
*kctl_alloc
;
95 struct hda_input_mux private_imux
;
98 static hda_nid_t stac9200_adc_nids
[1] = {
102 static hda_nid_t stac9200_mux_nids
[1] = {
106 static hda_nid_t stac9200_dac_nids
[1] = {
110 static hda_nid_t stac922x_adc_nids
[2] = {
114 static hda_nid_t stac922x_mux_nids
[2] = {
118 static hda_nid_t stac927x_adc_nids
[3] = {
122 static hda_nid_t stac927x_mux_nids
[3] = {
126 static hda_nid_t stac9205_adc_nids
[2] = {
130 static hda_nid_t stac9205_mux_nids
[2] = {
134 static hda_nid_t stac9200_pin_nids
[8] = {
135 0x08, 0x09, 0x0d, 0x0e,
136 0x0f, 0x10, 0x11, 0x12,
139 static hda_nid_t stac922x_pin_nids
[10] = {
140 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
141 0x0f, 0x10, 0x11, 0x15, 0x1b,
144 static hda_nid_t stac927x_pin_nids
[14] = {
145 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
146 0x0f, 0x10, 0x11, 0x12, 0x13,
147 0x14, 0x21, 0x22, 0x23,
150 static hda_nid_t stac9205_pin_nids
[12] = {
151 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
152 0x0f, 0x14, 0x16, 0x17, 0x18,
157 static int stac92xx_mux_enum_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
159 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
160 struct sigmatel_spec
*spec
= codec
->spec
;
161 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
164 static int stac92xx_mux_enum_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
166 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
167 struct sigmatel_spec
*spec
= codec
->spec
;
168 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
170 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
174 static int stac92xx_mux_enum_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
176 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
177 struct sigmatel_spec
*spec
= codec
->spec
;
178 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
180 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
181 spec
->mux_nids
[adc_idx
], &spec
->cur_mux
[adc_idx
]);
184 static struct hda_verb stac9200_core_init
[] = {
185 /* set dac0mux for dac converter */
186 { 0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
190 static struct hda_verb stac922x_core_init
[] = {
191 /* set master volume and direct control */
192 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
196 static struct hda_verb d965_core_init
[] = {
197 /* set master volume and direct control */
198 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
199 /* unmute node 0x1b */
200 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
201 /* select node 0x03 as DAC */
202 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x01},
206 static struct hda_verb stac927x_core_init
[] = {
207 /* set master volume and direct control */
208 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
212 static struct hda_verb stac9205_core_init
[] = {
213 /* set master volume and direct control */
214 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
218 static struct snd_kcontrol_new stac9200_mixer
[] = {
219 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT
),
220 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT
),
222 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
223 .name
= "Input Source",
225 .info
= stac92xx_mux_enum_info
,
226 .get
= stac92xx_mux_enum_get
,
227 .put
= stac92xx_mux_enum_put
,
229 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT
),
230 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT
),
231 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT
),
235 /* This needs to be generated dynamically based on sequence */
236 static struct snd_kcontrol_new stac922x_mixer
[] = {
238 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
239 .name
= "Input Source",
241 .info
= stac92xx_mux_enum_info
,
242 .get
= stac92xx_mux_enum_get
,
243 .put
= stac92xx_mux_enum_put
,
245 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT
),
246 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT
),
247 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT
),
251 /* This needs to be generated dynamically based on sequence */
252 static struct snd_kcontrol_new stac9227_mixer
[] = {
254 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
255 .name
= "Input Source",
257 .info
= stac92xx_mux_enum_info
,
258 .get
= stac92xx_mux_enum_get
,
259 .put
= stac92xx_mux_enum_put
,
261 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT
),
262 HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT
),
266 static snd_kcontrol_new_t stac927x_mixer
[] = {
268 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
269 .name
= "Input Source",
271 .info
= stac92xx_mux_enum_info
,
272 .get
= stac92xx_mux_enum_get
,
273 .put
= stac92xx_mux_enum_put
,
275 HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT
),
276 HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT
),
277 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT
),
281 static snd_kcontrol_new_t stac9205_mixer
[] = {
283 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
284 .name
= "Input Source",
286 .info
= stac92xx_mux_enum_info
,
287 .get
= stac92xx_mux_enum_get
,
288 .put
= stac92xx_mux_enum_put
,
290 HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT
),
291 HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT
),
292 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT
),
296 static int stac92xx_build_controls(struct hda_codec
*codec
)
298 struct sigmatel_spec
*spec
= codec
->spec
;
302 err
= snd_hda_add_new_ctls(codec
, spec
->mixer
);
306 for (i
= 0; i
< spec
->num_mixers
; i
++) {
307 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
312 if (spec
->multiout
.dig_out_nid
) {
313 err
= snd_hda_create_spdif_out_ctls(codec
, spec
->multiout
.dig_out_nid
);
317 if (spec
->dig_in_nid
) {
318 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
325 static unsigned int ref9200_pin_configs
[8] = {
326 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
327 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
330 static unsigned int *stac9200_brd_tbl
[] = {
334 static struct hda_board_config stac9200_cfg_tbl
[] = {
335 { .modelname
= "ref",
336 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
337 .pci_subdevice
= 0x2668, /* DFI LanParty */
338 .config
= STAC_REF
},
342 static unsigned int ref922x_pin_configs
[10] = {
343 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
344 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
345 0x40000100, 0x40000100,
348 static unsigned int d945gtp3_pin_configs
[10] = {
349 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
350 0x40000100, 0x40000100, 0x40000100, 0x40000100,
351 0x02a19120, 0x40000100,
354 static unsigned int d945gtp5_pin_configs
[10] = {
355 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
356 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
357 0x02a19320, 0x40000100,
360 static unsigned int *stac922x_brd_tbl
[STAC_922X_MODELS
] = {
361 [STAC_REF
] = ref922x_pin_configs
,
362 [STAC_D945GTP3
] = d945gtp3_pin_configs
,
363 [STAC_D945GTP5
] = d945gtp5_pin_configs
,
364 [STAC_MACMINI
] = d945gtp5_pin_configs
,
367 static struct hda_board_config stac922x_cfg_tbl
[] = {
368 { .modelname
= "5stack", .config
= STAC_D945GTP5
},
369 { .modelname
= "3stack", .config
= STAC_D945GTP3
},
370 { .modelname
= "ref",
371 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
372 .pci_subdevice
= 0x2668, /* DFI LanParty */
373 .config
= STAC_REF
}, /* SigmaTel reference board */
374 /* Intel 945G based systems */
375 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
376 .pci_subdevice
= 0x0101,
377 .config
= STAC_D945GTP3
}, /* Intel D945GTP - 3 Stack */
378 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
379 .pci_subdevice
= 0x0202,
380 .config
= STAC_D945GTP3
}, /* Intel D945GNT - 3 Stack */
381 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
382 .pci_subdevice
= 0x0606,
383 .config
= STAC_D945GTP3
}, /* Intel D945GTP - 3 Stack */
384 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
385 .pci_subdevice
= 0x0601,
386 .config
= STAC_D945GTP3
}, /* Intel D945GTP - 3 Stack */
387 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
388 .pci_subdevice
= 0x0111,
389 .config
= STAC_D945GTP3
}, /* Intel D945GZP - 3 Stack */
390 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
391 .pci_subdevice
= 0x1115,
392 .config
= STAC_D945GTP3
}, /* Intel D945GPM - 3 Stack */
393 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
394 .pci_subdevice
= 0x1116,
395 .config
= STAC_D945GTP3
}, /* Intel D945GBO - 3 Stack */
396 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
397 .pci_subdevice
= 0x1117,
398 .config
= STAC_D945GTP3
}, /* Intel D945GPM - 3 Stack */
399 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
400 .pci_subdevice
= 0x1118,
401 .config
= STAC_D945GTP3
}, /* Intel D945GPM - 3 Stack */
402 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
403 .pci_subdevice
= 0x1119,
404 .config
= STAC_D945GTP3
}, /* Intel D945GPM - 3 Stack */
405 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
406 .pci_subdevice
= 0x8826,
407 .config
= STAC_D945GTP3
}, /* Intel D945GPM - 3 Stack */
408 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
409 .pci_subdevice
= 0x5049,
410 .config
= STAC_D945GTP3
}, /* Intel D945GCZ - 3 Stack */
411 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
412 .pci_subdevice
= 0x5055,
413 .config
= STAC_D945GTP3
}, /* Intel D945GCZ - 3 Stack */
414 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
415 .pci_subdevice
= 0x5048,
416 .config
= STAC_D945GTP3
}, /* Intel D945GPB - 3 Stack */
417 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
418 .pci_subdevice
= 0x0110,
419 .config
= STAC_D945GTP3
}, /* Intel D945GLR - 3 Stack */
420 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
421 .pci_subdevice
= 0x0404,
422 .config
= STAC_D945GTP5
}, /* Intel D945GTP - 5 Stack */
423 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
424 .pci_subdevice
= 0x0303,
425 .config
= STAC_D945GTP5
}, /* Intel D945GNT - 5 Stack */
426 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
427 .pci_subdevice
= 0x0013,
428 .config
= STAC_D945GTP5
}, /* Intel D955XBK - 5 Stack */
429 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
430 .pci_subdevice
= 0x0417,
431 .config
= STAC_D945GTP5
}, /* Intel D975XBK - 5 Stack */
432 /* Intel 945P based systems */
433 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
434 .pci_subdevice
= 0x0b0b,
435 .config
= STAC_D945GTP3
}, /* Intel D945PSN - 3 Stack */
436 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
437 .pci_subdevice
= 0x0112,
438 .config
= STAC_D945GTP3
}, /* Intel D945PLN - 3 Stack */
439 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
440 .pci_subdevice
= 0x0d0d,
441 .config
= STAC_D945GTP3
}, /* Intel D945PLM - 3 Stack */
442 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
443 .pci_subdevice
= 0x0909,
444 .config
= STAC_D945GTP3
}, /* Intel D945PAW - 3 Stack */
445 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
446 .pci_subdevice
= 0x0505,
447 .config
= STAC_D945GTP3
}, /* Intel D945PLM - 3 Stack */
448 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
449 .pci_subdevice
= 0x0707,
450 .config
= STAC_D945GTP5
}, /* Intel D945PSV - 5 Stack */
452 { .pci_subvendor
= 0x8384,
453 .pci_subdevice
= 0x7680,
454 .config
= STAC_MACMINI
}, /* Apple Mac Mini (early 2006) */
458 static unsigned int ref927x_pin_configs
[14] = {
459 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
460 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
461 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
462 0x01c42190, 0x40000100,
465 static unsigned int d965_3st_pin_configs
[14] = {
466 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
467 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
468 0x40000100, 0x40000100, 0x40000100, 0x40000100,
469 0x40000100, 0x40000100
472 static unsigned int d965_5st_pin_configs
[14] = {
473 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
474 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
475 0x40000100, 0x40000100, 0x40000100, 0x01442070,
476 0x40000100, 0x40000100
479 static unsigned int *stac927x_brd_tbl
[STAC_927X_MODELS
] = {
480 [STAC_REF
] = ref927x_pin_configs
,
481 [STAC_D965_3ST
] = d965_3st_pin_configs
,
482 [STAC_D965_5ST
] = d965_5st_pin_configs
,
485 static struct hda_board_config stac927x_cfg_tbl
[] = {
486 { .modelname
= "5stack", .config
= STAC_D965_5ST
},
487 { .modelname
= "3stack", .config
= STAC_D965_3ST
},
488 { .modelname
= "ref",
489 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
490 .pci_subdevice
= 0x2668, /* DFI LanParty */
491 .config
= STAC_REF
}, /* SigmaTel reference board */
492 /* Intel 946 based systems */
493 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
494 .pci_subdevice
= 0x3d01,
495 .config
= STAC_D965_3ST
}, /* D946 configuration */
496 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
497 .pci_subdevice
= 0xa301,
498 .config
= STAC_D965_3ST
}, /* Intel D946GZT - 3 stack */
499 /* 965 based 3 stack systems */
500 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
501 .pci_subdevice
= 0x2116,
502 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
503 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
504 .pci_subdevice
= 0x2115,
505 .config
= STAC_D965_3ST
}, /* Intel DQ965WC - 3 Stack */
506 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
507 .pci_subdevice
= 0x2114,
508 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
509 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
510 .pci_subdevice
= 0x2113,
511 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
512 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
513 .pci_subdevice
= 0x2112,
514 .config
= STAC_D965_3ST
}, /* Intel DG965MS - 3 Stack */
515 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
516 .pci_subdevice
= 0x2111,
517 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
518 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
519 .pci_subdevice
= 0x2110,
520 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
521 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
522 .pci_subdevice
= 0x2009,
523 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
524 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
525 .pci_subdevice
= 0x2008,
526 .config
= STAC_D965_3ST
}, /* Intel DQ965GF - 3 Stack */
527 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
528 .pci_subdevice
= 0x2007,
529 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
530 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
531 .pci_subdevice
= 0x2006,
532 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
533 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
534 .pci_subdevice
= 0x2005,
535 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
536 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
537 .pci_subdevice
= 0x2004,
538 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
539 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
540 .pci_subdevice
= 0x2003,
541 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
542 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
543 .pci_subdevice
= 0x2002,
544 .config
= STAC_D965_3ST
}, /* Intel D965 3Stack config */
545 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
546 .pci_subdevice
= 0x2001,
547 .config
= STAC_D965_3ST
}, /* Intel DQ965GF - 3 Stack */
548 /* 965 based 5 stack systems */
549 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
550 .pci_subdevice
= 0x2301,
551 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
552 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
553 .pci_subdevice
= 0x2302,
554 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
555 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
556 .pci_subdevice
= 0x2303,
557 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
558 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
559 .pci_subdevice
= 0x2304,
560 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
561 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
562 .pci_subdevice
= 0x2305,
563 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
564 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
565 .pci_subdevice
= 0x2501,
566 .config
= STAC_D965_5ST
}, /* Intel DG965MQ - 5 Stack */
567 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
568 .pci_subdevice
= 0x2502,
569 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
570 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
571 .pci_subdevice
= 0x2503,
572 .config
= STAC_D965_5ST
}, /* Intel DG965 - 5 Stack */
573 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
574 .pci_subdevice
= 0x2504,
575 .config
= STAC_D965_5ST
}, /* Intel DQ965GF - 5 Stack */
579 static unsigned int ref9205_pin_configs
[12] = {
580 0x40000100, 0x40000100, 0x01016011, 0x01014010,
581 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
582 0x40000100, 0x40000100, 0x01441030, 0x01c41030
585 static unsigned int *stac9205_brd_tbl
[] = {
589 static struct hda_board_config stac9205_cfg_tbl
[] = {
590 { .modelname
= "ref",
591 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
592 .pci_subdevice
= 0x2668, /* DFI LanParty */
593 .config
= STAC_REF
}, /* SigmaTel reference board */
594 /* Dell laptops have BIOS problem */
595 { .pci_subvendor
= PCI_VENDOR_ID_DELL
, .pci_subdevice
= 0x01b5,
596 .config
= STAC_REF
}, /* Dell Inspiron 630m */
597 { .pci_subvendor
= PCI_VENDOR_ID_DELL
, .pci_subdevice
= 0x01c2,
598 .config
= STAC_REF
}, /* Dell Latitude D620 */
599 { .pci_subvendor
= PCI_VENDOR_ID_DELL
, .pci_subdevice
= 0x01cb,
600 .config
= STAC_REF
}, /* Dell Latitude 120L */
604 static int stac92xx_save_bios_config_regs(struct hda_codec
*codec
)
607 struct sigmatel_spec
*spec
= codec
->spec
;
609 if (! spec
->bios_pin_configs
) {
610 spec
->bios_pin_configs
= kcalloc(spec
->num_pins
,
611 sizeof(*spec
->bios_pin_configs
), GFP_KERNEL
);
612 if (! spec
->bios_pin_configs
)
616 for (i
= 0; i
< spec
->num_pins
; i
++) {
617 hda_nid_t nid
= spec
->pin_nids
[i
];
618 unsigned int pin_cfg
;
620 pin_cfg
= snd_hda_codec_read(codec
, nid
, 0,
621 AC_VERB_GET_CONFIG_DEFAULT
, 0x00);
622 snd_printdd(KERN_INFO
"hda_codec: pin nid %2.2x bios pin config %8.8x\n",
624 spec
->bios_pin_configs
[i
] = pin_cfg
;
630 static void stac92xx_set_config_regs(struct hda_codec
*codec
)
633 struct sigmatel_spec
*spec
= codec
->spec
;
634 unsigned int pin_cfg
;
636 if (! spec
->pin_nids
|| ! spec
->pin_configs
)
639 for (i
= 0; i
< spec
->num_pins
; i
++) {
640 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
641 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
,
642 spec
->pin_configs
[i
] & 0x000000ff);
643 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
644 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1
,
645 (spec
->pin_configs
[i
] & 0x0000ff00) >> 8);
646 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
647 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2
,
648 (spec
->pin_configs
[i
] & 0x00ff0000) >> 16);
649 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
650 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3
,
651 spec
->pin_configs
[i
] >> 24);
652 pin_cfg
= snd_hda_codec_read(codec
, spec
->pin_nids
[i
], 0,
653 AC_VERB_GET_CONFIG_DEFAULT
,
655 snd_printdd(KERN_INFO
"hda_codec: pin nid %2.2x pin config %8.8x\n", spec
->pin_nids
[i
], pin_cfg
);
660 * Analog playback callbacks
662 static int stac92xx_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
663 struct hda_codec
*codec
,
664 struct snd_pcm_substream
*substream
)
666 struct sigmatel_spec
*spec
= codec
->spec
;
667 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
670 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
671 struct hda_codec
*codec
,
672 unsigned int stream_tag
,
674 struct snd_pcm_substream
*substream
)
676 struct sigmatel_spec
*spec
= codec
->spec
;
677 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
, stream_tag
, format
, substream
);
680 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
681 struct hda_codec
*codec
,
682 struct snd_pcm_substream
*substream
)
684 struct sigmatel_spec
*spec
= codec
->spec
;
685 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
689 * Digital playback callbacks
691 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
692 struct hda_codec
*codec
,
693 struct snd_pcm_substream
*substream
)
695 struct sigmatel_spec
*spec
= codec
->spec
;
696 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
699 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
700 struct hda_codec
*codec
,
701 struct snd_pcm_substream
*substream
)
703 struct sigmatel_spec
*spec
= codec
->spec
;
704 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
709 * Analog capture callbacks
711 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
712 struct hda_codec
*codec
,
713 unsigned int stream_tag
,
715 struct snd_pcm_substream
*substream
)
717 struct sigmatel_spec
*spec
= codec
->spec
;
719 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
720 stream_tag
, 0, format
);
724 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
725 struct hda_codec
*codec
,
726 struct snd_pcm_substream
*substream
)
728 struct sigmatel_spec
*spec
= codec
->spec
;
730 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
], 0, 0, 0);
734 static struct hda_pcm_stream stac92xx_pcm_digital_playback
= {
738 /* NID is set in stac92xx_build_pcms */
740 .open
= stac92xx_dig_playback_pcm_open
,
741 .close
= stac92xx_dig_playback_pcm_close
745 static struct hda_pcm_stream stac92xx_pcm_digital_capture
= {
749 /* NID is set in stac92xx_build_pcms */
752 static struct hda_pcm_stream stac92xx_pcm_analog_playback
= {
756 .nid
= 0x02, /* NID to query formats and rates */
758 .open
= stac92xx_playback_pcm_open
,
759 .prepare
= stac92xx_playback_pcm_prepare
,
760 .cleanup
= stac92xx_playback_pcm_cleanup
764 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback
= {
768 .nid
= 0x06, /* NID to query formats and rates */
770 .open
= stac92xx_playback_pcm_open
,
771 .prepare
= stac92xx_playback_pcm_prepare
,
772 .cleanup
= stac92xx_playback_pcm_cleanup
776 static struct hda_pcm_stream stac92xx_pcm_analog_capture
= {
780 /* NID is set in stac92xx_build_pcms */
782 .prepare
= stac92xx_capture_pcm_prepare
,
783 .cleanup
= stac92xx_capture_pcm_cleanup
787 static int stac92xx_build_pcms(struct hda_codec
*codec
)
789 struct sigmatel_spec
*spec
= codec
->spec
;
790 struct hda_pcm
*info
= spec
->pcm_rec
;
793 codec
->pcm_info
= info
;
795 info
->name
= "STAC92xx Analog";
796 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_playback
;
797 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_analog_capture
;
798 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
800 if (spec
->alt_switch
) {
803 info
->name
= "STAC92xx Analog Alt";
804 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_alt_playback
;
807 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
810 info
->name
= "STAC92xx Digital";
811 if (spec
->multiout
.dig_out_nid
) {
812 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_digital_playback
;
813 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
815 if (spec
->dig_in_nid
) {
816 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_digital_capture
;
817 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
824 static unsigned int stac92xx_get_vref(struct hda_codec
*codec
, hda_nid_t nid
)
826 unsigned int pincap
= snd_hda_param_read(codec
, nid
,
828 pincap
= (pincap
& AC_PINCAP_VREF
) >> AC_PINCAP_VREF_SHIFT
;
829 if (pincap
& AC_PINCAP_VREF_100
)
830 return AC_PINCTL_VREF_100
;
831 if (pincap
& AC_PINCAP_VREF_80
)
832 return AC_PINCTL_VREF_80
;
833 if (pincap
& AC_PINCAP_VREF_50
)
834 return AC_PINCTL_VREF_50
;
835 if (pincap
& AC_PINCAP_VREF_GRD
)
836 return AC_PINCTL_VREF_GRD
;
840 static void stac92xx_auto_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
, int pin_type
)
843 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
846 static int stac92xx_io_switch_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
848 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
850 uinfo
->value
.integer
.min
= 0;
851 uinfo
->value
.integer
.max
= 1;
855 static int stac92xx_io_switch_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
857 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
858 struct sigmatel_spec
*spec
= codec
->spec
;
859 int io_idx
= kcontrol
-> private_value
& 0xff;
861 ucontrol
->value
.integer
.value
[0] = spec
->io_switch
[io_idx
];
865 static int stac92xx_io_switch_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
867 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
868 struct sigmatel_spec
*spec
= codec
->spec
;
869 hda_nid_t nid
= kcontrol
->private_value
>> 8;
870 int io_idx
= kcontrol
-> private_value
& 0xff;
871 unsigned short val
= ucontrol
->value
.integer
.value
[0];
873 spec
->io_switch
[io_idx
] = val
;
876 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
878 unsigned int pinctl
= AC_PINCTL_IN_EN
;
879 if (io_idx
) /* set VREF for mic */
880 pinctl
|= stac92xx_get_vref(codec
, nid
);
881 stac92xx_auto_set_pinctl(codec
, nid
, pinctl
);
886 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
887 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
890 .info = stac92xx_io_switch_info, \
891 .get = stac92xx_io_switch_get, \
892 .put = stac92xx_io_switch_put, \
893 .private_value = xpval, \
899 STAC_CTL_WIDGET_MUTE
,
900 STAC_CTL_WIDGET_IO_SWITCH
,
903 static struct snd_kcontrol_new stac92xx_control_templates
[] = {
904 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
905 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
906 STAC_CODEC_IO_SWITCH(NULL
, 0),
909 /* add dynamic controls */
910 static int stac92xx_add_control(struct sigmatel_spec
*spec
, int type
, const char *name
, unsigned long val
)
912 struct snd_kcontrol_new
*knew
;
914 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
915 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
917 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
); /* array + terminator */
920 if (spec
->kctl_alloc
) {
921 memcpy(knew
, spec
->kctl_alloc
, sizeof(*knew
) * spec
->num_kctl_alloc
);
922 kfree(spec
->kctl_alloc
);
924 spec
->kctl_alloc
= knew
;
925 spec
->num_kctl_alloc
= num
;
928 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
929 *knew
= stac92xx_control_templates
[type
];
930 knew
->name
= kstrdup(name
, GFP_KERNEL
);
933 knew
->private_value
= val
;
934 spec
->num_kctl_used
++;
938 /* flag inputs as additional dynamic lineouts */
939 static int stac92xx_add_dyn_out_pins(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
941 struct sigmatel_spec
*spec
= codec
->spec
;
943 switch (cfg
->line_outs
) {
945 /* add line-in as side */
946 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
947 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_LINE
];
948 spec
->line_switch
= 1;
953 /* add line-in as clfe and mic as side */
954 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
955 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_LINE
];
956 spec
->line_switch
= 1;
959 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
960 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_MIC
];
961 spec
->mic_switch
= 1;
966 /* add line-in as surr and mic as clfe */
967 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
968 cfg
->line_out_pins
[1] = cfg
->input_pins
[AUTO_PIN_LINE
];
969 spec
->line_switch
= 1;
972 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
973 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_MIC
];
974 spec
->mic_switch
= 1;
984 * XXX The line_out pin widget connection list may not be set to the
985 * desired DAC nid. This is the case on 927x where ports A and B can
986 * be routed to several DACs.
988 * This requires an analysis of the line-out/hp pin configuration
989 * to provide a best fit for pin/DAC configurations that are routable.
990 * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
991 * A and B is not supported.
993 /* fill in the dac_nids table from the parsed pin configuration */
994 static int stac92xx_auto_fill_dac_nids(struct hda_codec
*codec
,
995 const struct auto_pin_cfg
*cfg
)
997 struct sigmatel_spec
*spec
= codec
->spec
;
1001 /* check the pins hardwired to audio widget */
1002 for (i
= 0; i
< cfg
->line_outs
; i
++) {
1003 nid
= cfg
->line_out_pins
[i
];
1004 spec
->multiout
.dac_nids
[i
] = snd_hda_codec_read(codec
, nid
, 0,
1005 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
1008 spec
->multiout
.num_dacs
= cfg
->line_outs
;
1013 /* create volume control/switch for the given prefx type */
1014 static int create_controls(struct sigmatel_spec
*spec
, const char *pfx
, hda_nid_t nid
, int chs
)
1019 sprintf(name
, "%s Playback Volume", pfx
);
1020 err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, name
,
1021 HDA_COMPOSE_AMP_VAL(nid
, chs
, 0, HDA_OUTPUT
));
1024 sprintf(name
, "%s Playback Switch", pfx
);
1025 err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, name
,
1026 HDA_COMPOSE_AMP_VAL(nid
, chs
, 0, HDA_OUTPUT
));
1032 /* add playback controls from the parsed DAC table */
1033 static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec
*spec
,
1034 const struct auto_pin_cfg
*cfg
)
1036 static const char *chname
[4] = {
1037 "Front", "Surround", NULL
/*CLFE*/, "Side"
1042 for (i
= 0; i
< cfg
->line_outs
; i
++) {
1043 if (!spec
->multiout
.dac_nids
[i
])
1046 nid
= spec
->multiout
.dac_nids
[i
];
1050 err
= create_controls(spec
, "Center", nid
, 1);
1053 err
= create_controls(spec
, "LFE", nid
, 2);
1057 err
= create_controls(spec
, chname
[i
], nid
, 3);
1063 if (spec
->line_switch
)
1064 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Line In as Output Switch", cfg
->input_pins
[AUTO_PIN_LINE
] << 8)) < 0)
1067 if (spec
->mic_switch
)
1068 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Mic as Output Switch", (cfg
->input_pins
[AUTO_PIN_MIC
] << 8) | 1)) < 0)
1074 static int check_in_dac_nids(struct sigmatel_spec
*spec
, hda_nid_t nid
)
1078 for (i
= 0; i
< spec
->multiout
.num_dacs
; i
++) {
1079 if (spec
->multiout
.dac_nids
[i
] == nid
)
1082 if (spec
->multiout
.hp_nid
== nid
)
1087 static int add_spec_dacs(struct sigmatel_spec
*spec
, hda_nid_t nid
)
1089 if (!spec
->multiout
.hp_nid
)
1090 spec
->multiout
.hp_nid
= nid
;
1091 else if (spec
->multiout
.num_dacs
> 4) {
1092 printk(KERN_WARNING
"stac92xx: No space for DAC 0x%x\n", nid
);
1095 spec
->multiout
.dac_nids
[spec
->multiout
.num_dacs
] = nid
;
1096 spec
->multiout
.num_dacs
++;
1101 /* add playback controls for Speaker and HP outputs */
1102 static int stac92xx_auto_create_hp_ctls(struct hda_codec
*codec
,
1103 struct auto_pin_cfg
*cfg
)
1105 struct sigmatel_spec
*spec
= codec
->spec
;
1107 int i
, old_num_dacs
, err
;
1109 old_num_dacs
= spec
->multiout
.num_dacs
;
1110 for (i
= 0; i
< cfg
->hp_outs
; i
++) {
1111 unsigned int wid_caps
= get_wcaps(codec
, cfg
->hp_pins
[i
]);
1112 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
1113 spec
->hp_detect
= 1;
1114 nid
= snd_hda_codec_read(codec
, cfg
->hp_pins
[i
], 0,
1115 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
1116 if (check_in_dac_nids(spec
, nid
))
1120 add_spec_dacs(spec
, nid
);
1122 for (i
= 0; i
< cfg
->speaker_outs
; i
++) {
1123 nid
= snd_hda_codec_read(codec
, cfg
->speaker_pins
[0], 0,
1124 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
1125 if (check_in_dac_nids(spec
, nid
))
1127 if (check_in_dac_nids(spec
, nid
))
1131 add_spec_dacs(spec
, nid
);
1134 for (i
= old_num_dacs
; i
< spec
->multiout
.num_dacs
; i
++) {
1135 static const char *pfxs
[] = {
1136 "Speaker", "External Speaker", "Speaker2",
1138 err
= create_controls(spec
, pfxs
[i
- old_num_dacs
],
1139 spec
->multiout
.dac_nids
[i
], 3);
1143 if (spec
->multiout
.hp_nid
) {
1145 if (old_num_dacs
== spec
->multiout
.num_dacs
)
1149 err
= create_controls(spec
, pfx
, spec
->multiout
.hp_nid
, 3);
1157 /* create playback/capture controls for input pins */
1158 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
1160 struct sigmatel_spec
*spec
= codec
->spec
;
1161 struct hda_input_mux
*imux
= &spec
->private_imux
;
1162 hda_nid_t con_lst
[HDA_MAX_NUM_INPUTS
];
1165 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
1168 if (!cfg
->input_pins
[i
])
1171 for (j
= 0; j
< spec
->num_muxes
; j
++) {
1173 num_cons
= snd_hda_get_connections(codec
,
1176 HDA_MAX_NUM_INPUTS
);
1177 for (k
= 0; k
< num_cons
; k
++)
1178 if (con_lst
[k
] == cfg
->input_pins
[i
]) {
1185 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
1186 imux
->items
[imux
->num_items
].index
= index
;
1190 if (imux
->num_items
== 1) {
1192 * Set the current input for the muxes.
1193 * The STAC9221 has two input muxes with identical source
1194 * NID lists. Hopefully this won't get confused.
1196 for (i
= 0; i
< spec
->num_muxes
; i
++) {
1197 snd_hda_codec_write(codec
, spec
->mux_nids
[i
], 0,
1198 AC_VERB_SET_CONNECT_SEL
,
1199 imux
->items
[0].index
);
1206 static void stac92xx_auto_init_multi_out(struct hda_codec
*codec
)
1208 struct sigmatel_spec
*spec
= codec
->spec
;
1211 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
1212 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
1213 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
1217 static void stac92xx_auto_init_hp_out(struct hda_codec
*codec
)
1219 struct sigmatel_spec
*spec
= codec
->spec
;
1222 for (i
= 0; i
< spec
->autocfg
.hp_outs
; i
++) {
1224 pin
= spec
->autocfg
.hp_pins
[i
];
1225 if (pin
) /* connect to front */
1226 stac92xx_auto_set_pinctl(codec
, pin
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
);
1228 for (i
= 0; i
< spec
->autocfg
.speaker_outs
; i
++) {
1230 pin
= spec
->autocfg
.speaker_pins
[i
];
1231 if (pin
) /* connect to front */
1232 stac92xx_auto_set_pinctl(codec
, pin
, AC_PINCTL_OUT_EN
);
1236 static int stac92xx_parse_auto_config(struct hda_codec
*codec
, hda_nid_t dig_out
, hda_nid_t dig_in
)
1238 struct sigmatel_spec
*spec
= codec
->spec
;
1241 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
1243 if (! spec
->autocfg
.line_outs
)
1244 return 0; /* can't find valid pin config */
1246 if ((err
= stac92xx_add_dyn_out_pins(codec
, &spec
->autocfg
)) < 0)
1248 if (spec
->multiout
.num_dacs
== 0)
1249 if ((err
= stac92xx_auto_fill_dac_nids(codec
, &spec
->autocfg
)) < 0)
1252 if ((err
= stac92xx_auto_create_multi_out_ctls(spec
, &spec
->autocfg
)) < 0 ||
1253 (err
= stac92xx_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0 ||
1254 (err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
1257 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
1258 if (spec
->multiout
.max_channels
> 2)
1259 spec
->surr_switch
= 1;
1261 if (spec
->autocfg
.dig_out_pin
)
1262 spec
->multiout
.dig_out_nid
= dig_out
;
1263 if (spec
->autocfg
.dig_in_pin
)
1264 spec
->dig_in_nid
= dig_in
;
1266 if (spec
->kctl_alloc
)
1267 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
1269 spec
->input_mux
= &spec
->private_imux
;
1274 /* add playback controls for HP output */
1275 static int stac9200_auto_create_hp_ctls(struct hda_codec
*codec
,
1276 struct auto_pin_cfg
*cfg
)
1278 struct sigmatel_spec
*spec
= codec
->spec
;
1279 hda_nid_t pin
= cfg
->hp_pins
[0];
1280 unsigned int wid_caps
;
1285 wid_caps
= get_wcaps(codec
, pin
);
1286 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
1287 spec
->hp_detect
= 1;
1292 /* add playback controls for LFE output */
1293 static int stac9200_auto_create_lfe_ctls(struct hda_codec
*codec
,
1294 struct auto_pin_cfg
*cfg
)
1296 struct sigmatel_spec
*spec
= codec
->spec
;
1298 hda_nid_t lfe_pin
= 0x0;
1302 * search speaker outs and line outs for a mono speaker pin
1303 * with an amp. If one is found, add LFE controls
1306 for (i
= 0; i
< spec
->autocfg
.speaker_outs
&& lfe_pin
== 0x0; i
++) {
1307 hda_nid_t pin
= spec
->autocfg
.speaker_pins
[i
];
1308 unsigned long wcaps
= get_wcaps(codec
, pin
);
1309 wcaps
&= (AC_WCAP_STEREO
| AC_WCAP_OUT_AMP
);
1310 if (wcaps
== AC_WCAP_OUT_AMP
)
1311 /* found a mono speaker with an amp, must be lfe */
1315 /* if speaker_outs is 0, then speakers may be in line_outs */
1316 if (lfe_pin
== 0 && spec
->autocfg
.speaker_outs
== 0) {
1317 for (i
= 0; i
< spec
->autocfg
.line_outs
&& lfe_pin
== 0x0; i
++) {
1318 hda_nid_t pin
= spec
->autocfg
.line_out_pins
[i
];
1320 cfg
= snd_hda_codec_read(codec
, pin
, 0,
1321 AC_VERB_GET_CONFIG_DEFAULT
,
1323 if (get_defcfg_device(cfg
) == AC_JACK_SPEAKER
) {
1324 unsigned long wcaps
= get_wcaps(codec
, pin
);
1325 wcaps
&= (AC_WCAP_STEREO
| AC_WCAP_OUT_AMP
);
1326 if (wcaps
== AC_WCAP_OUT_AMP
)
1327 /* found a mono speaker with an amp,
1335 err
= create_controls(spec
, "LFE", lfe_pin
, 1);
1343 static int stac9200_parse_auto_config(struct hda_codec
*codec
)
1345 struct sigmatel_spec
*spec
= codec
->spec
;
1348 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
1351 if ((err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
1354 if ((err
= stac9200_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0)
1357 if ((err
= stac9200_auto_create_lfe_ctls(codec
, &spec
->autocfg
)) < 0)
1360 if (spec
->autocfg
.dig_out_pin
)
1361 spec
->multiout
.dig_out_nid
= 0x05;
1362 if (spec
->autocfg
.dig_in_pin
)
1363 spec
->dig_in_nid
= 0x04;
1365 if (spec
->kctl_alloc
)
1366 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
1368 spec
->input_mux
= &spec
->private_imux
;
1374 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
1375 * funky external mute control using GPIO pins.
1378 static void stac922x_gpio_mute(struct hda_codec
*codec
, int pin
, int muted
)
1380 unsigned int gpiostate
, gpiomask
, gpiodir
;
1382 gpiostate
= snd_hda_codec_read(codec
, codec
->afg
, 0,
1383 AC_VERB_GET_GPIO_DATA
, 0);
1386 gpiostate
|= (1 << pin
);
1388 gpiostate
&= ~(1 << pin
);
1390 gpiomask
= snd_hda_codec_read(codec
, codec
->afg
, 0,
1391 AC_VERB_GET_GPIO_MASK
, 0);
1392 gpiomask
|= (1 << pin
);
1394 gpiodir
= snd_hda_codec_read(codec
, codec
->afg
, 0,
1395 AC_VERB_GET_GPIO_DIRECTION
, 0);
1396 gpiodir
|= (1 << pin
);
1398 /* AppleHDA seems to do this -- WTF is this verb?? */
1399 snd_hda_codec_write(codec
, codec
->afg
, 0, 0x7e7, 0);
1401 snd_hda_codec_write(codec
, codec
->afg
, 0,
1402 AC_VERB_SET_GPIO_MASK
, gpiomask
);
1403 snd_hda_codec_write(codec
, codec
->afg
, 0,
1404 AC_VERB_SET_GPIO_DIRECTION
, gpiodir
);
1408 snd_hda_codec_write(codec
, codec
->afg
, 0,
1409 AC_VERB_SET_GPIO_DATA
, gpiostate
);
1412 static void enable_pin_detect(struct hda_codec
*codec
, hda_nid_t nid
,
1415 if (get_wcaps(codec
, nid
) & AC_WCAP_UNSOL_CAP
)
1416 snd_hda_codec_write(codec
, nid
, 0,
1417 AC_VERB_SET_UNSOLICITED_ENABLE
,
1418 (AC_USRSP_EN
| event
));
1421 static int stac92xx_init(struct hda_codec
*codec
)
1423 struct sigmatel_spec
*spec
= codec
->spec
;
1424 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
1427 snd_hda_sequence_write(codec
, spec
->init
);
1430 if (spec
->hp_detect
) {
1431 /* Enable unsolicited responses on the HP widget */
1432 for (i
= 0; i
< cfg
->hp_outs
; i
++)
1433 enable_pin_detect(codec
, cfg
->hp_pins
[i
],
1435 /* fake event to set up pins */
1436 codec
->patch_ops
.unsol_event(codec
, STAC_HP_EVENT
<< 26);
1437 /* enable the headphones by default.
1438 * If/when unsol_event detection works, this will be ignored
1440 stac92xx_auto_init_hp_out(codec
);
1442 stac92xx_auto_init_multi_out(codec
);
1443 stac92xx_auto_init_hp_out(codec
);
1445 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
1446 hda_nid_t nid
= cfg
->input_pins
[i
];
1448 unsigned int pinctl
= AC_PINCTL_IN_EN
;
1449 if (i
== AUTO_PIN_MIC
|| i
== AUTO_PIN_FRONT_MIC
)
1450 pinctl
|= stac92xx_get_vref(codec
, nid
);
1451 stac92xx_auto_set_pinctl(codec
, nid
, pinctl
);
1454 if (cfg
->dig_out_pin
)
1455 stac92xx_auto_set_pinctl(codec
, cfg
->dig_out_pin
,
1457 if (cfg
->dig_in_pin
)
1458 stac92xx_auto_set_pinctl(codec
, cfg
->dig_in_pin
,
1461 if (spec
->gpio_mute
) {
1462 stac922x_gpio_mute(codec
, 0, 0);
1463 stac922x_gpio_mute(codec
, 1, 0);
1469 static void stac92xx_free(struct hda_codec
*codec
)
1471 struct sigmatel_spec
*spec
= codec
->spec
;
1477 if (spec
->kctl_alloc
) {
1478 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
1479 kfree(spec
->kctl_alloc
[i
].name
);
1480 kfree(spec
->kctl_alloc
);
1483 if (spec
->bios_pin_configs
)
1484 kfree(spec
->bios_pin_configs
);
1489 static void stac92xx_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
1492 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
1493 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
1494 if (flag
== AC_PINCTL_OUT_EN
&& (pin_ctl
& AC_PINCTL_IN_EN
))
1496 snd_hda_codec_write(codec
, nid
, 0,
1497 AC_VERB_SET_PIN_WIDGET_CONTROL
,
1501 static void stac92xx_reset_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
1504 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
1505 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
1506 snd_hda_codec_write(codec
, nid
, 0,
1507 AC_VERB_SET_PIN_WIDGET_CONTROL
,
1511 static int get_pin_presence(struct hda_codec
*codec
, hda_nid_t nid
)
1515 if (snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_PIN_SENSE
, 0x00)
1521 static void stac92xx_hp_detect(struct hda_codec
*codec
, unsigned int res
)
1523 struct sigmatel_spec
*spec
= codec
->spec
;
1524 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
1528 for (i
= 0; i
< cfg
->hp_outs
; i
++) {
1529 presence
= get_pin_presence(codec
, cfg
->hp_pins
[i
]);
1535 /* disable lineouts, enable hp */
1536 for (i
= 0; i
< cfg
->line_outs
; i
++)
1537 stac92xx_reset_pinctl(codec
, cfg
->line_out_pins
[i
],
1539 for (i
= 0; i
< cfg
->speaker_outs
; i
++)
1540 stac92xx_reset_pinctl(codec
, cfg
->speaker_pins
[i
],
1542 for (i
= 0; i
< cfg
->hp_outs
; i
++)
1543 stac92xx_set_pinctl(codec
, cfg
->hp_pins
[i
],
1546 /* enable lineouts, disable hp */
1547 for (i
= 0; i
< cfg
->line_outs
; i
++)
1548 stac92xx_set_pinctl(codec
, cfg
->line_out_pins
[i
],
1550 for (i
= 0; i
< cfg
->speaker_outs
; i
++)
1551 stac92xx_set_pinctl(codec
, cfg
->speaker_pins
[i
],
1553 for (i
= 0; i
< cfg
->hp_outs
; i
++)
1554 stac92xx_reset_pinctl(codec
, cfg
->hp_pins
[i
],
1559 static void stac92xx_unsol_event(struct hda_codec
*codec
, unsigned int res
)
1561 switch (res
>> 26) {
1563 stac92xx_hp_detect(codec
, res
);
1569 static int stac92xx_resume(struct hda_codec
*codec
)
1571 struct sigmatel_spec
*spec
= codec
->spec
;
1574 stac92xx_init(codec
);
1575 stac92xx_set_config_regs(codec
);
1576 for (i
= 0; i
< spec
->num_mixers
; i
++)
1577 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
1578 if (spec
->multiout
.dig_out_nid
)
1579 snd_hda_resume_spdif_out(codec
);
1580 if (spec
->dig_in_nid
)
1581 snd_hda_resume_spdif_in(codec
);
1587 static struct hda_codec_ops stac92xx_patch_ops
= {
1588 .build_controls
= stac92xx_build_controls
,
1589 .build_pcms
= stac92xx_build_pcms
,
1590 .init
= stac92xx_init
,
1591 .free
= stac92xx_free
,
1592 .unsol_event
= stac92xx_unsol_event
,
1594 .resume
= stac92xx_resume
,
1598 static int patch_stac9200(struct hda_codec
*codec
)
1600 struct sigmatel_spec
*spec
;
1603 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1609 spec
->pin_nids
= stac9200_pin_nids
;
1610 spec
->board_config
= snd_hda_check_board_config(codec
, stac9200_cfg_tbl
);
1611 if (spec
->board_config
< 0) {
1612 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
1613 err
= stac92xx_save_bios_config_regs(codec
);
1615 stac92xx_free(codec
);
1618 spec
->pin_configs
= spec
->bios_pin_configs
;
1620 spec
->pin_configs
= stac9200_brd_tbl
[spec
->board_config
];
1621 stac92xx_set_config_regs(codec
);
1624 spec
->multiout
.max_channels
= 2;
1625 spec
->multiout
.num_dacs
= 1;
1626 spec
->multiout
.dac_nids
= stac9200_dac_nids
;
1627 spec
->adc_nids
= stac9200_adc_nids
;
1628 spec
->mux_nids
= stac9200_mux_nids
;
1629 spec
->num_muxes
= 1;
1631 spec
->init
= stac9200_core_init
;
1632 spec
->mixer
= stac9200_mixer
;
1634 err
= stac9200_parse_auto_config(codec
);
1636 stac92xx_free(codec
);
1640 codec
->patch_ops
= stac92xx_patch_ops
;
1645 static int patch_stac922x(struct hda_codec
*codec
)
1647 struct sigmatel_spec
*spec
;
1650 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1655 spec
->num_pins
= 10;
1656 spec
->pin_nids
= stac922x_pin_nids
;
1657 spec
->board_config
= snd_hda_check_board_config(codec
, stac922x_cfg_tbl
);
1658 if (spec
->board_config
< 0) {
1659 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC922x, "
1660 "using BIOS defaults\n");
1661 err
= stac92xx_save_bios_config_regs(codec
);
1663 stac92xx_free(codec
);
1666 spec
->pin_configs
= spec
->bios_pin_configs
;
1667 } else if (stac922x_brd_tbl
[spec
->board_config
] != NULL
) {
1668 spec
->pin_configs
= stac922x_brd_tbl
[spec
->board_config
];
1669 stac92xx_set_config_regs(codec
);
1672 spec
->adc_nids
= stac922x_adc_nids
;
1673 spec
->mux_nids
= stac922x_mux_nids
;
1674 spec
->num_muxes
= 2;
1676 spec
->init
= stac922x_core_init
;
1677 spec
->mixer
= stac922x_mixer
;
1679 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1681 err
= stac92xx_parse_auto_config(codec
, 0x08, 0x09);
1683 stac92xx_free(codec
);
1687 if (spec
->board_config
== STAC_MACMINI
)
1688 spec
->gpio_mute
= 1;
1690 codec
->patch_ops
= stac92xx_patch_ops
;
1695 static int patch_stac927x(struct hda_codec
*codec
)
1697 struct sigmatel_spec
*spec
;
1700 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1705 spec
->num_pins
= 14;
1706 spec
->pin_nids
= stac927x_pin_nids
;
1707 spec
->board_config
= snd_hda_check_board_config(codec
, stac927x_cfg_tbl
);
1708 if (spec
->board_config
< 0) {
1709 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
1710 err
= stac92xx_save_bios_config_regs(codec
);
1712 stac92xx_free(codec
);
1715 spec
->pin_configs
= spec
->bios_pin_configs
;
1716 } else if (stac927x_brd_tbl
[spec
->board_config
] != NULL
) {
1717 spec
->pin_configs
= stac927x_brd_tbl
[spec
->board_config
];
1718 stac92xx_set_config_regs(codec
);
1721 switch (spec
->board_config
) {
1723 spec
->adc_nids
= stac927x_adc_nids
;
1724 spec
->mux_nids
= stac927x_mux_nids
;
1725 spec
->num_muxes
= 3;
1726 spec
->init
= d965_core_init
;
1727 spec
->mixer
= stac9227_mixer
;
1730 spec
->adc_nids
= stac927x_adc_nids
;
1731 spec
->mux_nids
= stac927x_mux_nids
;
1732 spec
->num_muxes
= 3;
1733 spec
->init
= d965_core_init
;
1734 spec
->mixer
= stac9227_mixer
;
1737 spec
->adc_nids
= stac927x_adc_nids
;
1738 spec
->mux_nids
= stac927x_mux_nids
;
1739 spec
->num_muxes
= 3;
1740 spec
->init
= stac927x_core_init
;
1741 spec
->mixer
= stac927x_mixer
;
1744 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1746 err
= stac92xx_parse_auto_config(codec
, 0x1e, 0x20);
1748 stac92xx_free(codec
);
1752 codec
->patch_ops
= stac92xx_patch_ops
;
1757 static int patch_stac9205(struct hda_codec
*codec
)
1759 struct sigmatel_spec
*spec
;
1762 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1767 spec
->num_pins
= 14;
1768 spec
->pin_nids
= stac9205_pin_nids
;
1769 spec
->board_config
= snd_hda_check_board_config(codec
, stac9205_cfg_tbl
);
1770 if (spec
->board_config
< 0) {
1771 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
1772 err
= stac92xx_save_bios_config_regs(codec
);
1774 stac92xx_free(codec
);
1777 spec
->pin_configs
= spec
->bios_pin_configs
;
1779 spec
->pin_configs
= stac9205_brd_tbl
[spec
->board_config
];
1780 stac92xx_set_config_regs(codec
);
1783 spec
->adc_nids
= stac9205_adc_nids
;
1784 spec
->mux_nids
= stac9205_mux_nids
;
1785 spec
->num_muxes
= 3;
1787 spec
->init
= stac9205_core_init
;
1788 spec
->mixer
= stac9205_mixer
;
1790 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1792 err
= stac92xx_parse_auto_config(codec
, 0x1f, 0x20);
1794 stac92xx_free(codec
);
1798 codec
->patch_ops
= stac92xx_patch_ops
;
1807 /* static config for Sony VAIO FE550G and Sony VAIO AR */
1808 static hda_nid_t vaio_dacs
[] = { 0x2 };
1809 #define VAIO_HP_DAC 0x5
1810 static hda_nid_t vaio_adcs
[] = { 0x8 /*,0x6*/ };
1811 static hda_nid_t vaio_mux_nids
[] = { 0x15 };
1813 static struct hda_input_mux vaio_mux
= {
1816 /* { "HP", 0x0 }, */
1823 static struct hda_verb vaio_init
[] = {
1824 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP <- 0x2 */
1825 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Speaker <- 0x5 */
1826 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? (<- 0x2) */
1827 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* CD */
1828 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? */
1829 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x2}, /* mic-sel: 0a,0d,14,02 */
1830 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* HP */
1831 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* Speaker */
1832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
1833 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
1834 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
}, /* Mic-in -> 0x9 */
1838 static struct hda_verb vaio_ar_init
[] = {
1839 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP <- 0x2 */
1840 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Speaker <- 0x5 */
1841 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? (<- 0x2) */
1842 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* CD */
1843 /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
1844 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? */
1845 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x2}, /* mic-sel: 0a,0d,14,02 */
1846 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* HP */
1847 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* Speaker */
1848 /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
1849 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
1850 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
1851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
}, /* Mic-in -> 0x9 */
1855 /* bind volumes of both NID 0x02 and 0x05 */
1856 static int vaio_master_vol_put(struct snd_kcontrol
*kcontrol
,
1857 struct snd_ctl_elem_value
*ucontrol
)
1859 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1860 long *valp
= ucontrol
->value
.integer
.value
;
1863 change
= snd_hda_codec_amp_update(codec
, 0x02, 0, HDA_OUTPUT
, 0,
1864 0x7f, valp
[0] & 0x7f);
1865 change
|= snd_hda_codec_amp_update(codec
, 0x02, 1, HDA_OUTPUT
, 0,
1866 0x7f, valp
[1] & 0x7f);
1867 snd_hda_codec_amp_update(codec
, 0x05, 0, HDA_OUTPUT
, 0,
1868 0x7f, valp
[0] & 0x7f);
1869 snd_hda_codec_amp_update(codec
, 0x05, 1, HDA_OUTPUT
, 0,
1870 0x7f, valp
[1] & 0x7f);
1874 /* bind volumes of both NID 0x02 and 0x05 */
1875 static int vaio_master_sw_put(struct snd_kcontrol
*kcontrol
,
1876 struct snd_ctl_elem_value
*ucontrol
)
1878 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1879 long *valp
= ucontrol
->value
.integer
.value
;
1882 change
= snd_hda_codec_amp_update(codec
, 0x02, 0, HDA_OUTPUT
, 0,
1883 0x80, (valp
[0] ? 0 : 0x80));
1884 change
|= snd_hda_codec_amp_update(codec
, 0x02, 1, HDA_OUTPUT
, 0,
1885 0x80, (valp
[1] ? 0 : 0x80));
1886 snd_hda_codec_amp_update(codec
, 0x05, 0, HDA_OUTPUT
, 0,
1887 0x80, (valp
[0] ? 0 : 0x80));
1888 snd_hda_codec_amp_update(codec
, 0x05, 1, HDA_OUTPUT
, 0,
1889 0x80, (valp
[1] ? 0 : 0x80));
1893 static struct snd_kcontrol_new vaio_mixer
[] = {
1895 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1896 .name
= "Master Playback Volume",
1897 .info
= snd_hda_mixer_amp_volume_info
,
1898 .get
= snd_hda_mixer_amp_volume_get
,
1899 .put
= vaio_master_vol_put
,
1900 .tlv
= { .c
= snd_hda_mixer_amp_tlv
},
1901 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1904 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1905 .name
= "Master Playback Switch",
1906 .info
= snd_hda_mixer_amp_switch_info
,
1907 .get
= snd_hda_mixer_amp_switch_get
,
1908 .put
= vaio_master_sw_put
,
1909 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1911 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
1912 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT
),
1913 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT
),
1915 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1916 .name
= "Capture Source",
1918 .info
= stac92xx_mux_enum_info
,
1919 .get
= stac92xx_mux_enum_get
,
1920 .put
= stac92xx_mux_enum_put
,
1925 static struct snd_kcontrol_new vaio_ar_mixer
[] = {
1927 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1928 .name
= "Master Playback Volume",
1929 .info
= snd_hda_mixer_amp_volume_info
,
1930 .get
= snd_hda_mixer_amp_volume_get
,
1931 .put
= vaio_master_vol_put
,
1932 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1935 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1936 .name
= "Master Playback Switch",
1937 .info
= snd_hda_mixer_amp_switch_info
,
1938 .get
= snd_hda_mixer_amp_switch_get
,
1939 .put
= vaio_master_sw_put
,
1940 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1942 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
1943 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT
),
1944 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT
),
1945 /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
1946 HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
1948 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1949 .name
= "Capture Source",
1951 .info
= stac92xx_mux_enum_info
,
1952 .get
= stac92xx_mux_enum_get
,
1953 .put
= stac92xx_mux_enum_put
,
1958 static struct hda_codec_ops stac9872_patch_ops
= {
1959 .build_controls
= stac92xx_build_controls
,
1960 .build_pcms
= stac92xx_build_pcms
,
1961 .init
= stac92xx_init
,
1962 .free
= stac92xx_free
,
1964 .resume
= stac92xx_resume
,
1968 enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
1970 /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
1972 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
1974 /* AR Series. id=0x83847664 and subsys=104D1300 */
1978 static struct hda_board_config stac9872_cfg_tbl
[] = {
1979 { .modelname
= "vaio", .config
= CXD9872RD_VAIO
},
1980 { .modelname
= "vaio-ar", .config
= CXD9872AKD_VAIO
},
1981 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81e6,
1982 .config
= CXD9872RD_VAIO
},
1983 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81ef,
1984 .config
= CXD9872RD_VAIO
},
1985 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81fd,
1986 .config
= CXD9872AKD_VAIO
},
1990 static int patch_stac9872(struct hda_codec
*codec
)
1992 struct sigmatel_spec
*spec
;
1995 board_config
= snd_hda_check_board_config(codec
, stac9872_cfg_tbl
);
1996 if (board_config
< 0)
1997 /* unknown config, let generic-parser do its job... */
1998 return snd_hda_parse_generic_codec(codec
);
2000 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
2005 switch (board_config
) {
2006 case CXD9872RD_VAIO
:
2007 case STAC9872AK_VAIO
:
2008 case STAC9872K_VAIO
:
2009 spec
->mixer
= vaio_mixer
;
2010 spec
->init
= vaio_init
;
2011 spec
->multiout
.max_channels
= 2;
2012 spec
->multiout
.num_dacs
= ARRAY_SIZE(vaio_dacs
);
2013 spec
->multiout
.dac_nids
= vaio_dacs
;
2014 spec
->multiout
.hp_nid
= VAIO_HP_DAC
;
2015 spec
->num_adcs
= ARRAY_SIZE(vaio_adcs
);
2016 spec
->adc_nids
= vaio_adcs
;
2017 spec
->input_mux
= &vaio_mux
;
2018 spec
->mux_nids
= vaio_mux_nids
;
2021 case CXD9872AKD_VAIO
:
2022 spec
->mixer
= vaio_ar_mixer
;
2023 spec
->init
= vaio_ar_init
;
2024 spec
->multiout
.max_channels
= 2;
2025 spec
->multiout
.num_dacs
= ARRAY_SIZE(vaio_dacs
);
2026 spec
->multiout
.dac_nids
= vaio_dacs
;
2027 spec
->multiout
.hp_nid
= VAIO_HP_DAC
;
2028 spec
->num_adcs
= ARRAY_SIZE(vaio_adcs
);
2029 spec
->adc_nids
= vaio_adcs
;
2030 spec
->input_mux
= &vaio_mux
;
2031 spec
->mux_nids
= vaio_mux_nids
;
2035 codec
->patch_ops
= stac9872_patch_ops
;
2043 struct hda_codec_preset snd_hda_preset_sigmatel
[] = {
2044 { .id
= 0x83847690, .name
= "STAC9200", .patch
= patch_stac9200
},
2045 { .id
= 0x83847882, .name
= "STAC9220 A1", .patch
= patch_stac922x
},
2046 { .id
= 0x83847680, .name
= "STAC9221 A1", .patch
= patch_stac922x
},
2047 { .id
= 0x83847880, .name
= "STAC9220 A2", .patch
= patch_stac922x
},
2048 { .id
= 0x83847681, .name
= "STAC9220D/9223D A2", .patch
= patch_stac922x
},
2049 { .id
= 0x83847682, .name
= "STAC9221 A2", .patch
= patch_stac922x
},
2050 { .id
= 0x83847683, .name
= "STAC9221D A2", .patch
= patch_stac922x
},
2051 { .id
= 0x83847618, .name
= "STAC9227", .patch
= patch_stac927x
},
2052 { .id
= 0x83847619, .name
= "STAC9227", .patch
= patch_stac927x
},
2053 { .id
= 0x83847616, .name
= "STAC9228", .patch
= patch_stac927x
},
2054 { .id
= 0x83847617, .name
= "STAC9228", .patch
= patch_stac927x
},
2055 { .id
= 0x83847614, .name
= "STAC9229", .patch
= patch_stac927x
},
2056 { .id
= 0x83847615, .name
= "STAC9229", .patch
= patch_stac927x
},
2057 { .id
= 0x83847620, .name
= "STAC9274", .patch
= patch_stac927x
},
2058 { .id
= 0x83847621, .name
= "STAC9274D", .patch
= patch_stac927x
},
2059 { .id
= 0x83847622, .name
= "STAC9273X", .patch
= patch_stac927x
},
2060 { .id
= 0x83847623, .name
= "STAC9273D", .patch
= patch_stac927x
},
2061 { .id
= 0x83847624, .name
= "STAC9272X", .patch
= patch_stac927x
},
2062 { .id
= 0x83847625, .name
= "STAC9272D", .patch
= patch_stac927x
},
2063 { .id
= 0x83847626, .name
= "STAC9271X", .patch
= patch_stac927x
},
2064 { .id
= 0x83847627, .name
= "STAC9271D", .patch
= patch_stac927x
},
2065 { .id
= 0x83847628, .name
= "STAC9274X5NH", .patch
= patch_stac927x
},
2066 { .id
= 0x83847629, .name
= "STAC9274D5NH", .patch
= patch_stac927x
},
2067 /* The following does not take into account .id=0x83847661 when subsys =
2068 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
2069 * currently not fully supported.
2071 { .id
= 0x83847661, .name
= "CXD9872RD/K", .patch
= patch_stac9872
},
2072 { .id
= 0x83847662, .name
= "STAC9872AK", .patch
= patch_stac9872
},
2073 { .id
= 0x83847664, .name
= "CXD9872AKD", .patch
= patch_stac9872
},
2074 { .id
= 0x838476a0, .name
= "STAC9205", .patch
= patch_stac9205
},
2075 { .id
= 0x838476a1, .name
= "STAC9205D", .patch
= patch_stac9205
},
2076 { .id
= 0x838476a2, .name
= "STAC9204", .patch
= patch_stac9205
},
2077 { .id
= 0x838476a3, .name
= "STAC9204D", .patch
= patch_stac9205
},
2078 { .id
= 0x838476a4, .name
= "STAC9255", .patch
= patch_stac9205
},
2079 { .id
= 0x838476a5, .name
= "STAC9255D", .patch
= patch_stac9205
},
2080 { .id
= 0x838476a6, .name
= "STAC9254", .patch
= patch_stac9205
},
2081 { .id
= 0x838476a7, .name
= "STAC9254D", .patch
= patch_stac9205
},