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
39 #define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT)
42 #define STAC_D945GTP3 1
43 #define STAC_D945GTP5 2
45 struct sigmatel_spec
{
46 struct snd_kcontrol_new
*mixers
[4];
47 unsigned int num_mixers
;
50 unsigned int surr_switch
: 1;
51 unsigned int line_switch
: 1;
52 unsigned int mic_switch
: 1;
53 unsigned int alt_switch
: 1;
54 unsigned int hp_detect
: 1;
57 struct hda_multi_out multiout
;
58 hda_nid_t dac_nids
[5];
62 unsigned int num_adcs
;
64 unsigned int num_muxes
;
69 unsigned int num_pins
;
70 unsigned int *pin_configs
;
72 /* codec specific stuff */
73 struct hda_verb
*init
;
74 struct snd_kcontrol_new
*mixer
;
77 struct hda_input_mux
*input_mux
;
78 unsigned int cur_mux
[3];
81 unsigned int io_switch
[2];
83 struct hda_pcm pcm_rec
[2]; /* PCM information */
85 /* dynamic controls and input_mux */
86 struct auto_pin_cfg autocfg
;
87 unsigned int num_kctl_alloc
, num_kctl_used
;
88 struct snd_kcontrol_new
*kctl_alloc
;
89 struct hda_input_mux private_imux
;
92 static hda_nid_t stac9200_adc_nids
[1] = {
96 static hda_nid_t stac9200_mux_nids
[1] = {
100 static hda_nid_t stac9200_dac_nids
[1] = {
104 static hda_nid_t stac922x_adc_nids
[2] = {
108 static hda_nid_t stac922x_mux_nids
[2] = {
112 static hda_nid_t stac927x_adc_nids
[3] = {
116 static hda_nid_t stac927x_mux_nids
[3] = {
120 static hda_nid_t stac9200_pin_nids
[8] = {
121 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
124 static hda_nid_t stac922x_pin_nids
[10] = {
125 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
126 0x0f, 0x10, 0x11, 0x15, 0x1b,
129 static hda_nid_t stac927x_pin_nids
[14] = {
130 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
131 0x0f, 0x10, 0x11, 0x12, 0x13,
132 0x14, 0x21, 0x22, 0x23,
135 static int stac92xx_mux_enum_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
137 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
138 struct sigmatel_spec
*spec
= codec
->spec
;
139 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
142 static int stac92xx_mux_enum_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
144 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
145 struct sigmatel_spec
*spec
= codec
->spec
;
146 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
148 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
152 static int stac92xx_mux_enum_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
154 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
155 struct sigmatel_spec
*spec
= codec
->spec
;
156 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
158 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
159 spec
->mux_nids
[adc_idx
], &spec
->cur_mux
[adc_idx
]);
162 static struct hda_verb stac9200_core_init
[] = {
163 /* set dac0mux for dac converter */
164 { 0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
168 static struct hda_verb stac922x_core_init
[] = {
169 /* set master volume and direct control */
170 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
174 static struct hda_verb stac927x_core_init
[] = {
175 /* set master volume and direct control */
176 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
180 static struct snd_kcontrol_new stac9200_mixer
[] = {
181 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT
),
182 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT
),
184 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
185 .name
= "Input Source",
187 .info
= stac92xx_mux_enum_info
,
188 .get
= stac92xx_mux_enum_get
,
189 .put
= stac92xx_mux_enum_put
,
191 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT
),
192 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT
),
193 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT
),
197 /* This needs to be generated dynamically based on sequence */
198 static struct snd_kcontrol_new stac922x_mixer
[] = {
200 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
201 .name
= "Input Source",
203 .info
= stac92xx_mux_enum_info
,
204 .get
= stac92xx_mux_enum_get
,
205 .put
= stac92xx_mux_enum_put
,
207 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT
),
208 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT
),
209 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT
),
213 static snd_kcontrol_new_t stac927x_mixer
[] = {
215 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
216 .name
= "Input Source",
218 .info
= stac92xx_mux_enum_info
,
219 .get
= stac92xx_mux_enum_get
,
220 .put
= stac92xx_mux_enum_put
,
222 HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT
),
223 HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT
),
224 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT
),
228 static int stac92xx_build_controls(struct hda_codec
*codec
)
230 struct sigmatel_spec
*spec
= codec
->spec
;
234 err
= snd_hda_add_new_ctls(codec
, spec
->mixer
);
238 for (i
= 0; i
< spec
->num_mixers
; i
++) {
239 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
244 if (spec
->multiout
.dig_out_nid
) {
245 err
= snd_hda_create_spdif_out_ctls(codec
, spec
->multiout
.dig_out_nid
);
249 if (spec
->dig_in_nid
) {
250 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
257 static unsigned int ref9200_pin_configs
[8] = {
258 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
259 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
262 static unsigned int *stac9200_brd_tbl
[] = {
266 static struct hda_board_config stac9200_cfg_tbl
[] = {
267 { .modelname
= "ref",
268 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
269 .pci_subdevice
= 0x2668, /* DFI LanParty */
270 .config
= STAC_REF
},
274 static unsigned int ref922x_pin_configs
[10] = {
275 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
276 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
277 0x40000100, 0x40000100,
280 static unsigned int d945gtp3_pin_configs
[10] = {
281 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
282 0x40000100, 0x40000100, 0x40000100, 0x40000100,
283 0x02a19120, 0x40000100,
286 static unsigned int d945gtp5_pin_configs
[10] = {
287 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
288 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
289 0x02a19320, 0x40000100,
292 static unsigned int *stac922x_brd_tbl
[] = {
294 d945gtp3_pin_configs
,
295 d945gtp5_pin_configs
,
298 static struct hda_board_config stac922x_cfg_tbl
[] = {
299 { .modelname
= "ref",
300 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
301 .pci_subdevice
= 0x2668, /* DFI LanParty */
302 .config
= STAC_REF
}, /* SigmaTel reference board */
303 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
304 .pci_subdevice
= 0x0101,
305 .config
= STAC_D945GTP3
}, /* Intel D945GTP - 3 Stack */
306 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
307 .pci_subdevice
= 0x0202,
308 .config
= STAC_D945GTP3
}, /* Intel D945GNT - 3 Stack, 9221 A1 */
309 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
310 .pci_subdevice
= 0x0b0b,
311 .config
= STAC_D945GTP3
}, /* Intel D945PSN - 3 Stack, 9221 A1 */
312 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
313 .pci_subdevice
= 0x0707,
314 .config
= STAC_D945GTP5
}, /* Intel D945PSV - 5 Stack */
315 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
316 .pci_subdevice
= 0x0404,
317 .config
= STAC_D945GTP5
}, /* Intel D945GTP - 5 Stack */
318 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
319 .pci_subdevice
= 0x0303,
320 .config
= STAC_D945GTP5
}, /* Intel D945GNT - 5 Stack */
321 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
322 .pci_subdevice
= 0x0013,
323 .config
= STAC_D945GTP5
}, /* Intel D955XBK - 5 Stack */
324 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
325 .pci_subdevice
= 0x0417,
326 .config
= STAC_D945GTP5
}, /* Intel D975XBK - 5 Stack */
330 static unsigned int ref927x_pin_configs
[14] = {
331 0x01813122, 0x01a19021, 0x01014010, 0x01016011,
332 0x01012012, 0x01011014, 0x40000100, 0x40000100,
333 0x40000100, 0x40000100, 0x40000100, 0x01441030,
334 0x01c41030, 0x40000100,
337 static unsigned int *stac927x_brd_tbl
[] = {
341 static struct hda_board_config stac927x_cfg_tbl
[] = {
342 { .modelname
= "ref",
343 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
344 .pci_subdevice
= 0x2668, /* DFI LanParty */
345 .config
= STAC_REF
}, /* SigmaTel reference board */
349 static void stac92xx_set_config_regs(struct hda_codec
*codec
)
352 struct sigmatel_spec
*spec
= codec
->spec
;
353 unsigned int pin_cfg
;
355 for (i
=0; i
< spec
->num_pins
; i
++) {
356 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
357 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
,
358 spec
->pin_configs
[i
] & 0x000000ff);
359 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
360 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1
,
361 (spec
->pin_configs
[i
] & 0x0000ff00) >> 8);
362 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
363 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2
,
364 (spec
->pin_configs
[i
] & 0x00ff0000) >> 16);
365 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
366 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3
,
367 spec
->pin_configs
[i
] >> 24);
368 pin_cfg
= snd_hda_codec_read(codec
, spec
->pin_nids
[i
], 0,
369 AC_VERB_GET_CONFIG_DEFAULT
,
371 snd_printdd(KERN_INFO
"hda_codec: pin nid %2.2x pin config %8.8x\n", spec
->pin_nids
[i
], pin_cfg
);
376 * Analog playback callbacks
378 static int stac92xx_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
379 struct hda_codec
*codec
,
380 struct snd_pcm_substream
*substream
)
382 struct sigmatel_spec
*spec
= codec
->spec
;
383 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
386 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
387 struct hda_codec
*codec
,
388 unsigned int stream_tag
,
390 struct snd_pcm_substream
*substream
)
392 struct sigmatel_spec
*spec
= codec
->spec
;
393 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
, stream_tag
, format
, substream
);
396 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
397 struct hda_codec
*codec
,
398 struct snd_pcm_substream
*substream
)
400 struct sigmatel_spec
*spec
= codec
->spec
;
401 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
405 * Digital playback callbacks
407 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
408 struct hda_codec
*codec
,
409 struct snd_pcm_substream
*substream
)
411 struct sigmatel_spec
*spec
= codec
->spec
;
412 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
415 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
416 struct hda_codec
*codec
,
417 struct snd_pcm_substream
*substream
)
419 struct sigmatel_spec
*spec
= codec
->spec
;
420 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
425 * Analog capture callbacks
427 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
428 struct hda_codec
*codec
,
429 unsigned int stream_tag
,
431 struct snd_pcm_substream
*substream
)
433 struct sigmatel_spec
*spec
= codec
->spec
;
435 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
436 stream_tag
, 0, format
);
440 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
441 struct hda_codec
*codec
,
442 struct snd_pcm_substream
*substream
)
444 struct sigmatel_spec
*spec
= codec
->spec
;
446 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
], 0, 0, 0);
450 static struct hda_pcm_stream stac92xx_pcm_digital_playback
= {
454 /* NID is set in stac92xx_build_pcms */
456 .open
= stac92xx_dig_playback_pcm_open
,
457 .close
= stac92xx_dig_playback_pcm_close
461 static struct hda_pcm_stream stac92xx_pcm_digital_capture
= {
465 /* NID is set in stac92xx_build_pcms */
468 static struct hda_pcm_stream stac92xx_pcm_analog_playback
= {
472 .nid
= 0x02, /* NID to query formats and rates */
474 .open
= stac92xx_playback_pcm_open
,
475 .prepare
= stac92xx_playback_pcm_prepare
,
476 .cleanup
= stac92xx_playback_pcm_cleanup
480 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback
= {
484 .nid
= 0x06, /* NID to query formats and rates */
486 .open
= stac92xx_playback_pcm_open
,
487 .prepare
= stac92xx_playback_pcm_prepare
,
488 .cleanup
= stac92xx_playback_pcm_cleanup
492 static struct hda_pcm_stream stac92xx_pcm_analog_capture
= {
496 /* NID is set in stac92xx_build_pcms */
498 .prepare
= stac92xx_capture_pcm_prepare
,
499 .cleanup
= stac92xx_capture_pcm_cleanup
503 static int stac92xx_build_pcms(struct hda_codec
*codec
)
505 struct sigmatel_spec
*spec
= codec
->spec
;
506 struct hda_pcm
*info
= spec
->pcm_rec
;
509 codec
->pcm_info
= info
;
511 info
->name
= "STAC92xx Analog";
512 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_playback
;
513 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_analog_capture
;
514 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
516 if (spec
->alt_switch
) {
519 info
->name
= "STAC92xx Analog Alt";
520 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_alt_playback
;
523 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
526 info
->name
= "STAC92xx Digital";
527 if (spec
->multiout
.dig_out_nid
) {
528 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_digital_playback
;
529 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
531 if (spec
->dig_in_nid
) {
532 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_digital_capture
;
533 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
540 static unsigned int stac92xx_get_vref(struct hda_codec
*codec
, hda_nid_t nid
)
542 unsigned int pincap
= snd_hda_param_read(codec
, nid
,
544 pincap
= (pincap
& AC_PINCAP_VREF
) >> AC_PINCAP_VREF_SHIFT
;
545 if (pincap
& AC_PINCAP_VREF_100
)
546 return AC_PINCTL_VREF_100
;
547 if (pincap
& AC_PINCAP_VREF_80
)
548 return AC_PINCTL_VREF_80
;
549 if (pincap
& AC_PINCAP_VREF_50
)
550 return AC_PINCTL_VREF_50
;
551 if (pincap
& AC_PINCAP_VREF_GRD
)
552 return AC_PINCTL_VREF_GRD
;
556 static void stac92xx_auto_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
, int pin_type
)
559 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
562 static int stac92xx_io_switch_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
564 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
566 uinfo
->value
.integer
.min
= 0;
567 uinfo
->value
.integer
.max
= 1;
571 static int stac92xx_io_switch_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
573 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
574 struct sigmatel_spec
*spec
= codec
->spec
;
575 int io_idx
= kcontrol
-> private_value
& 0xff;
577 ucontrol
->value
.integer
.value
[0] = spec
->io_switch
[io_idx
];
581 static int stac92xx_io_switch_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
583 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
584 struct sigmatel_spec
*spec
= codec
->spec
;
585 hda_nid_t nid
= kcontrol
->private_value
>> 8;
586 int io_idx
= kcontrol
-> private_value
& 0xff;
587 unsigned short val
= ucontrol
->value
.integer
.value
[0];
589 spec
->io_switch
[io_idx
] = val
;
592 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
594 unsigned int pinctl
= AC_PINCTL_IN_EN
;
595 if (io_idx
) /* set VREF for mic */
596 pinctl
|= stac92xx_get_vref(codec
, nid
);
597 stac92xx_auto_set_pinctl(codec
, nid
, pinctl
);
602 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
603 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
606 .info = stac92xx_io_switch_info, \
607 .get = stac92xx_io_switch_get, \
608 .put = stac92xx_io_switch_put, \
609 .private_value = xpval, \
615 STAC_CTL_WIDGET_MUTE
,
616 STAC_CTL_WIDGET_IO_SWITCH
,
619 static struct snd_kcontrol_new stac92xx_control_templates
[] = {
620 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
621 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
622 STAC_CODEC_IO_SWITCH(NULL
, 0),
625 /* add dynamic controls */
626 static int stac92xx_add_control(struct sigmatel_spec
*spec
, int type
, const char *name
, unsigned long val
)
628 struct snd_kcontrol_new
*knew
;
630 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
631 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
633 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
); /* array + terminator */
636 if (spec
->kctl_alloc
) {
637 memcpy(knew
, spec
->kctl_alloc
, sizeof(*knew
) * spec
->num_kctl_alloc
);
638 kfree(spec
->kctl_alloc
);
640 spec
->kctl_alloc
= knew
;
641 spec
->num_kctl_alloc
= num
;
644 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
645 *knew
= stac92xx_control_templates
[type
];
646 knew
->name
= kstrdup(name
, GFP_KERNEL
);
649 knew
->private_value
= val
;
650 spec
->num_kctl_used
++;
654 /* flag inputs as additional dynamic lineouts */
655 static int stac92xx_add_dyn_out_pins(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
657 struct sigmatel_spec
*spec
= codec
->spec
;
659 switch (cfg
->line_outs
) {
661 /* add line-in as side */
662 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
663 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_LINE
];
664 spec
->line_switch
= 1;
669 /* add line-in as clfe and mic as side */
670 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
671 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_LINE
];
672 spec
->line_switch
= 1;
675 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
676 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_MIC
];
677 spec
->mic_switch
= 1;
682 /* add line-in as surr and mic as clfe */
683 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
684 cfg
->line_out_pins
[1] = cfg
->input_pins
[AUTO_PIN_LINE
];
685 spec
->line_switch
= 1;
688 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
689 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_MIC
];
690 spec
->mic_switch
= 1;
700 * XXX The line_out pin widget connection list may not be set to the
701 * desired DAC nid. This is the case on 927x where ports A and B can
702 * be routed to several DACs.
704 * This requires an analysis of the line-out/hp pin configuration
705 * to provide a best fit for pin/DAC configurations that are routable.
706 * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
707 * A and B is not supported.
709 /* fill in the dac_nids table from the parsed pin configuration */
710 static int stac92xx_auto_fill_dac_nids(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
712 struct sigmatel_spec
*spec
= codec
->spec
;
716 /* check the pins hardwired to audio widget */
717 for (i
= 0; i
< cfg
->line_outs
; i
++) {
718 nid
= cfg
->line_out_pins
[i
];
719 spec
->multiout
.dac_nids
[i
] = snd_hda_codec_read(codec
, nid
, 0,
720 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
723 spec
->multiout
.num_dacs
= cfg
->line_outs
;
728 /* add playback controls from the parsed DAC table */
729 static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec
*spec
, const struct auto_pin_cfg
*cfg
)
732 static const char *chname
[4] = { "Front", "Surround", NULL
/*CLFE*/, "Side" };
736 for (i
= 0; i
< cfg
->line_outs
; i
++) {
737 if (!spec
->multiout
.dac_nids
[i
])
740 nid
= spec
->multiout
.dac_nids
[i
];
744 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Center Playback Volume",
745 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
747 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "LFE Playback Volume",
748 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
750 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Center Playback Switch",
751 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
753 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "LFE Playback Switch",
754 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
757 sprintf(name
, "%s Playback Volume", chname
[i
]);
758 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, name
,
759 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
761 sprintf(name
, "%s Playback Switch", chname
[i
]);
762 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, name
,
763 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
768 if (spec
->line_switch
)
769 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Line In as Output Switch", cfg
->input_pins
[AUTO_PIN_LINE
] << 8)) < 0)
772 if (spec
->mic_switch
)
773 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Mic as Output Switch", (cfg
->input_pins
[AUTO_PIN_MIC
] << 8) | 1)) < 0)
779 /* add playback controls for HP output */
780 static int stac92xx_auto_create_hp_ctls(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
782 struct sigmatel_spec
*spec
= codec
->spec
;
783 hda_nid_t pin
= cfg
->hp_pin
;
786 unsigned int wid_caps
;
791 wid_caps
= get_wcaps(codec
, pin
);
792 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
795 nid
= snd_hda_codec_read(codec
, pin
, 0, AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
796 for (i
= 0; i
< cfg
->line_outs
; i
++) {
797 if (! spec
->multiout
.dac_nids
[i
])
799 if (spec
->multiout
.dac_nids
[i
] == nid
)
803 spec
->multiout
.hp_nid
= nid
;
805 /* control HP volume/switch on the output mixer amp */
806 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Headphone Playback Volume",
807 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
809 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Headphone Playback Switch",
810 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
816 /* create playback/capture controls for input pins */
817 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
819 struct sigmatel_spec
*spec
= codec
->spec
;
820 struct hda_input_mux
*imux
= &spec
->private_imux
;
821 hda_nid_t con_lst
[HDA_MAX_NUM_INPUTS
];
824 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
826 if (cfg
->input_pins
[i
]) {
827 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
829 for (j
=0; j
<spec
->num_muxes
; j
++) {
830 int num_cons
= snd_hda_get_connections(codec
, spec
->mux_nids
[j
], con_lst
, HDA_MAX_NUM_INPUTS
);
831 for (k
=0; k
<num_cons
; k
++)
832 if (con_lst
[k
] == cfg
->input_pins
[i
]) {
839 imux
->items
[imux
->num_items
].index
= index
;
847 static void stac92xx_auto_init_multi_out(struct hda_codec
*codec
)
849 struct sigmatel_spec
*spec
= codec
->spec
;
852 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
853 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
854 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
858 static void stac92xx_auto_init_hp_out(struct hda_codec
*codec
)
860 struct sigmatel_spec
*spec
= codec
->spec
;
863 pin
= spec
->autocfg
.hp_pin
;
864 if (pin
) /* connect to front */
865 stac92xx_auto_set_pinctl(codec
, pin
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
);
868 static int stac92xx_parse_auto_config(struct hda_codec
*codec
, hda_nid_t dig_out
, hda_nid_t dig_in
)
870 struct sigmatel_spec
*spec
= codec
->spec
;
873 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
875 if (! spec
->autocfg
.line_outs
)
876 return 0; /* can't find valid pin config */
877 if ((err
= stac92xx_add_dyn_out_pins(codec
, &spec
->autocfg
)) < 0)
879 if ((err
= stac92xx_auto_fill_dac_nids(codec
, &spec
->autocfg
)) < 0)
882 if ((err
= stac92xx_auto_create_multi_out_ctls(spec
, &spec
->autocfg
)) < 0 ||
883 (err
= stac92xx_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0 ||
884 (err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
887 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
888 if (spec
->multiout
.max_channels
> 2)
889 spec
->surr_switch
= 1;
891 if (spec
->autocfg
.dig_out_pin
)
892 spec
->multiout
.dig_out_nid
= dig_out
;
893 if (spec
->autocfg
.dig_in_pin
)
894 spec
->dig_in_nid
= dig_in
;
896 if (spec
->kctl_alloc
)
897 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
899 spec
->input_mux
= &spec
->private_imux
;
904 /* add playback controls for HP output */
905 static int stac9200_auto_create_hp_ctls(struct hda_codec
*codec
,
906 struct auto_pin_cfg
*cfg
)
908 struct sigmatel_spec
*spec
= codec
->spec
;
909 hda_nid_t pin
= cfg
->hp_pin
;
910 unsigned int wid_caps
;
915 wid_caps
= get_wcaps(codec
, pin
);
916 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
922 static int stac9200_parse_auto_config(struct hda_codec
*codec
)
924 struct sigmatel_spec
*spec
= codec
->spec
;
927 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
930 if ((err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
933 if ((err
= stac9200_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0)
936 if (spec
->autocfg
.dig_out_pin
)
937 spec
->multiout
.dig_out_nid
= 0x05;
938 if (spec
->autocfg
.dig_in_pin
)
939 spec
->dig_in_nid
= 0x04;
941 if (spec
->kctl_alloc
)
942 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
944 spec
->input_mux
= &spec
->private_imux
;
949 static int stac92xx_init(struct hda_codec
*codec
)
951 struct sigmatel_spec
*spec
= codec
->spec
;
952 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
955 snd_hda_sequence_write(codec
, spec
->init
);
958 if (spec
->hp_detect
) {
959 /* Enable unsolicited responses on the HP widget */
960 snd_hda_codec_write(codec
, cfg
->hp_pin
, 0,
961 AC_VERB_SET_UNSOLICITED_ENABLE
,
963 /* fake event to set up pins */
964 codec
->patch_ops
.unsol_event(codec
, STAC_HP_EVENT
<< 26);
966 stac92xx_auto_init_multi_out(codec
);
967 stac92xx_auto_init_hp_out(codec
);
969 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
970 hda_nid_t nid
= cfg
->input_pins
[i
];
972 unsigned int pinctl
= AC_PINCTL_IN_EN
;
973 if (i
== AUTO_PIN_MIC
|| i
== AUTO_PIN_FRONT_MIC
)
974 pinctl
|= stac92xx_get_vref(codec
, nid
);
975 stac92xx_auto_set_pinctl(codec
, nid
, pinctl
);
978 if (cfg
->dig_out_pin
)
979 stac92xx_auto_set_pinctl(codec
, cfg
->dig_out_pin
,
982 stac92xx_auto_set_pinctl(codec
, cfg
->dig_in_pin
,
988 static void stac92xx_free(struct hda_codec
*codec
)
990 struct sigmatel_spec
*spec
= codec
->spec
;
996 if (spec
->kctl_alloc
) {
997 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
998 kfree(spec
->kctl_alloc
[i
].name
);
999 kfree(spec
->kctl_alloc
);
1005 static void stac92xx_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
1008 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
1009 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
1010 snd_hda_codec_write(codec
, nid
, 0,
1011 AC_VERB_SET_PIN_WIDGET_CONTROL
,
1015 static void stac92xx_reset_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
1018 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
1019 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
1020 snd_hda_codec_write(codec
, nid
, 0,
1021 AC_VERB_SET_PIN_WIDGET_CONTROL
,
1025 static void stac92xx_unsol_event(struct hda_codec
*codec
, unsigned int res
)
1027 struct sigmatel_spec
*spec
= codec
->spec
;
1028 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
1031 if ((res
>> 26) != STAC_HP_EVENT
)
1034 presence
= snd_hda_codec_read(codec
, cfg
->hp_pin
, 0,
1035 AC_VERB_GET_PIN_SENSE
, 0x00) >> 31;
1038 /* disable lineouts, enable hp */
1039 for (i
= 0; i
< cfg
->line_outs
; i
++)
1040 stac92xx_reset_pinctl(codec
, cfg
->line_out_pins
[i
],
1042 stac92xx_set_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
1044 /* enable lineouts, disable hp */
1045 for (i
= 0; i
< cfg
->line_outs
; i
++)
1046 stac92xx_set_pinctl(codec
, cfg
->line_out_pins
[i
],
1048 stac92xx_reset_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
1053 static int stac92xx_resume(struct hda_codec
*codec
)
1055 struct sigmatel_spec
*spec
= codec
->spec
;
1058 stac92xx_init(codec
);
1059 for (i
= 0; i
< spec
->num_mixers
; i
++)
1060 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
1061 if (spec
->multiout
.dig_out_nid
)
1062 snd_hda_resume_spdif_out(codec
);
1063 if (spec
->dig_in_nid
)
1064 snd_hda_resume_spdif_in(codec
);
1070 static struct hda_codec_ops stac92xx_patch_ops
= {
1071 .build_controls
= stac92xx_build_controls
,
1072 .build_pcms
= stac92xx_build_pcms
,
1073 .init
= stac92xx_init
,
1074 .free
= stac92xx_free
,
1075 .unsol_event
= stac92xx_unsol_event
,
1077 .resume
= stac92xx_resume
,
1081 static int patch_stac9200(struct hda_codec
*codec
)
1083 struct sigmatel_spec
*spec
;
1086 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1091 spec
->board_config
= snd_hda_check_board_config(codec
, stac9200_cfg_tbl
);
1092 if (spec
->board_config
< 0)
1093 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
1096 spec
->pin_nids
= stac9200_pin_nids
;
1097 spec
->pin_configs
= stac9200_brd_tbl
[spec
->board_config
];
1098 stac92xx_set_config_regs(codec
);
1101 spec
->multiout
.max_channels
= 2;
1102 spec
->multiout
.num_dacs
= 1;
1103 spec
->multiout
.dac_nids
= stac9200_dac_nids
;
1104 spec
->adc_nids
= stac9200_adc_nids
;
1105 spec
->mux_nids
= stac9200_mux_nids
;
1106 spec
->num_muxes
= 1;
1108 spec
->init
= stac9200_core_init
;
1109 spec
->mixer
= stac9200_mixer
;
1111 err
= stac9200_parse_auto_config(codec
);
1113 stac92xx_free(codec
);
1117 codec
->patch_ops
= stac92xx_patch_ops
;
1122 static int patch_stac922x(struct hda_codec
*codec
)
1124 struct sigmatel_spec
*spec
;
1127 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1132 spec
->board_config
= snd_hda_check_board_config(codec
, stac922x_cfg_tbl
);
1133 if (spec
->board_config
< 0)
1134 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC922x, using BIOS defaults\n");
1136 spec
->num_pins
= 10;
1137 spec
->pin_nids
= stac922x_pin_nids
;
1138 spec
->pin_configs
= stac922x_brd_tbl
[spec
->board_config
];
1139 stac92xx_set_config_regs(codec
);
1142 spec
->adc_nids
= stac922x_adc_nids
;
1143 spec
->mux_nids
= stac922x_mux_nids
;
1144 spec
->num_muxes
= 2;
1146 spec
->init
= stac922x_core_init
;
1147 spec
->mixer
= stac922x_mixer
;
1149 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1151 err
= stac92xx_parse_auto_config(codec
, 0x08, 0x09);
1153 stac92xx_free(codec
);
1157 codec
->patch_ops
= stac92xx_patch_ops
;
1162 static int patch_stac927x(struct hda_codec
*codec
)
1164 struct sigmatel_spec
*spec
;
1167 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1172 spec
->board_config
= snd_hda_check_board_config(codec
, stac927x_cfg_tbl
);
1173 if (spec
->board_config
< 0)
1174 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
1176 spec
->num_pins
= 14;
1177 spec
->pin_nids
= stac927x_pin_nids
;
1178 spec
->pin_configs
= stac927x_brd_tbl
[spec
->board_config
];
1179 stac92xx_set_config_regs(codec
);
1182 spec
->adc_nids
= stac927x_adc_nids
;
1183 spec
->mux_nids
= stac927x_mux_nids
;
1184 spec
->num_muxes
= 3;
1186 spec
->init
= stac927x_core_init
;
1187 spec
->mixer
= stac927x_mixer
;
1189 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1191 err
= stac92xx_parse_auto_config(codec
, 0x1e, 0x20);
1193 stac92xx_free(codec
);
1197 codec
->patch_ops
= stac92xx_patch_ops
;
1206 /* static config for Sony VAIO FE550G */
1207 static hda_nid_t vaio_dacs
[] = { 0x2 };
1208 #define VAIO_HP_DAC 0x5
1209 static hda_nid_t vaio_adcs
[] = { 0x8 /*,0x6*/ };
1210 static hda_nid_t vaio_mux_nids
[] = { 0x15 };
1212 static struct hda_input_mux vaio_mux
= {
1216 { "Unknown", 0x1 }, */
1222 static struct hda_verb vaio_init
[] = {
1223 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP <- 0x2 */
1224 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Speaker <- 0x5 */
1225 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? (<- 0x2) */
1226 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* CD */
1227 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? */
1228 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x2}, /* mic-sel: 0a,0d,14,02 */
1229 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* HP */
1230 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* Speaker */
1231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
1232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
1233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
}, /* Mic-in -> 0x9 */
1237 /* bind volumes of both NID 0x02 and 0x05 */
1238 static int vaio_master_vol_put(struct snd_kcontrol
*kcontrol
,
1239 struct snd_ctl_elem_value
*ucontrol
)
1241 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1242 long *valp
= ucontrol
->value
.integer
.value
;
1245 change
= snd_hda_codec_amp_update(codec
, 0x02, 0, HDA_OUTPUT
, 0,
1246 0x7f, valp
[0] & 0x7f);
1247 change
|= snd_hda_codec_amp_update(codec
, 0x02, 1, HDA_OUTPUT
, 0,
1248 0x7f, valp
[1] & 0x7f);
1249 snd_hda_codec_amp_update(codec
, 0x05, 0, HDA_OUTPUT
, 0,
1250 0x7f, valp
[0] & 0x7f);
1251 snd_hda_codec_amp_update(codec
, 0x05, 1, HDA_OUTPUT
, 0,
1252 0x7f, valp
[1] & 0x7f);
1256 /* bind volumes of both NID 0x02 and 0x05 */
1257 static int vaio_master_sw_put(struct snd_kcontrol
*kcontrol
,
1258 struct snd_ctl_elem_value
*ucontrol
)
1260 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1261 long *valp
= ucontrol
->value
.integer
.value
;
1264 change
= snd_hda_codec_amp_update(codec
, 0x02, 0, HDA_OUTPUT
, 0,
1265 0x80, valp
[0] & 0x80);
1266 change
|= snd_hda_codec_amp_update(codec
, 0x02, 1, HDA_OUTPUT
, 0,
1267 0x80, valp
[1] & 0x80);
1268 snd_hda_codec_amp_update(codec
, 0x05, 0, HDA_OUTPUT
, 0,
1269 0x80, valp
[0] & 0x80);
1270 snd_hda_codec_amp_update(codec
, 0x05, 1, HDA_OUTPUT
, 0,
1271 0x80, valp
[1] & 0x80);
1275 static struct snd_kcontrol_new vaio_mixer
[] = {
1277 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1278 .name
= "Master Playback Volume",
1279 .info
= snd_hda_mixer_amp_volume_info
,
1280 .get
= snd_hda_mixer_amp_volume_get
,
1281 .put
= vaio_master_vol_put
,
1282 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1285 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1286 .name
= "Master Playback Switch",
1287 .info
= snd_hda_mixer_amp_switch_info
,
1288 .get
= snd_hda_mixer_amp_switch_get
,
1289 .put
= vaio_master_sw_put
,
1290 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1292 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
1293 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT
),
1294 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT
),
1296 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1297 .name
= "Capture Source",
1299 .info
= stac92xx_mux_enum_info
,
1300 .get
= stac92xx_mux_enum_get
,
1301 .put
= stac92xx_mux_enum_put
,
1306 static struct hda_codec_ops stac7661_patch_ops
= {
1307 .build_controls
= stac92xx_build_controls
,
1308 .build_pcms
= stac92xx_build_pcms
,
1309 .init
= stac92xx_init
,
1310 .free
= stac92xx_free
,
1312 .resume
= stac92xx_resume
,
1316 enum { STAC7661_VAIO
};
1318 static struct hda_board_config stac7661_cfg_tbl
[] = {
1319 { .modelname
= "vaio", .config
= STAC7661_VAIO
},
1320 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81e6,
1321 .config
= STAC7661_VAIO
},
1322 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81ef,
1323 .config
= STAC7661_VAIO
},
1327 static int patch_stac7661(struct hda_codec
*codec
)
1329 struct sigmatel_spec
*spec
;
1332 board_config
= snd_hda_check_board_config(codec
, stac7661_cfg_tbl
);
1333 if (board_config
< 0)
1334 /* unknown config, let generic-parser do its job... */
1335 return snd_hda_parse_generic_codec(codec
);
1337 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1342 switch (board_config
) {
1344 spec
->mixer
= vaio_mixer
;
1345 spec
->init
= vaio_init
;
1346 spec
->multiout
.max_channels
= 2;
1347 spec
->multiout
.num_dacs
= ARRAY_SIZE(vaio_dacs
);
1348 spec
->multiout
.dac_nids
= vaio_dacs
;
1349 spec
->multiout
.hp_nid
= VAIO_HP_DAC
;
1350 spec
->num_adcs
= ARRAY_SIZE(vaio_adcs
);
1351 spec
->adc_nids
= vaio_adcs
;
1352 spec
->input_mux
= &vaio_mux
;
1353 spec
->mux_nids
= vaio_mux_nids
;
1357 codec
->patch_ops
= stac7661_patch_ops
;
1365 struct hda_codec_preset snd_hda_preset_sigmatel
[] = {
1366 { .id
= 0x83847690, .name
= "STAC9200", .patch
= patch_stac9200
},
1367 { .id
= 0x83847882, .name
= "STAC9220 A1", .patch
= patch_stac922x
},
1368 { .id
= 0x83847680, .name
= "STAC9221 A1", .patch
= patch_stac922x
},
1369 { .id
= 0x83847880, .name
= "STAC9220 A2", .patch
= patch_stac922x
},
1370 { .id
= 0x83847681, .name
= "STAC9220D/9223D A2", .patch
= patch_stac922x
},
1371 { .id
= 0x83847682, .name
= "STAC9221 A2", .patch
= patch_stac922x
},
1372 { .id
= 0x83847683, .name
= "STAC9221D A2", .patch
= patch_stac922x
},
1373 { .id
= 0x83847620, .name
= "STAC9274", .patch
= patch_stac927x
},
1374 { .id
= 0x83847621, .name
= "STAC9274D", .patch
= patch_stac927x
},
1375 { .id
= 0x83847622, .name
= "STAC9273X", .patch
= patch_stac927x
},
1376 { .id
= 0x83847623, .name
= "STAC9273D", .patch
= patch_stac927x
},
1377 { .id
= 0x83847624, .name
= "STAC9272X", .patch
= patch_stac927x
},
1378 { .id
= 0x83847625, .name
= "STAC9272D", .patch
= patch_stac927x
},
1379 { .id
= 0x83847626, .name
= "STAC9271X", .patch
= patch_stac927x
},
1380 { .id
= 0x83847627, .name
= "STAC9271D", .patch
= patch_stac927x
},
1381 { .id
= 0x83847628, .name
= "STAC9274X5NH", .patch
= patch_stac927x
},
1382 { .id
= 0x83847629, .name
= "STAC9274D5NH", .patch
= patch_stac927x
},
1383 { .id
= 0x83847661, .name
= "STAC7661", .patch
= patch_stac7661
},