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
44 #define STAC_MACMINI 3
45 #define STAC_D965_2112 4
46 #define STAC_D965_284B 5
47 #define STAC_922X_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
;
77 /* codec specific stuff */
78 struct hda_verb
*init
;
79 struct snd_kcontrol_new
*mixer
;
82 struct hda_input_mux
*input_mux
;
83 unsigned int cur_mux
[3];
86 unsigned int io_switch
[2];
88 struct hda_pcm pcm_rec
[2]; /* PCM information */
90 /* dynamic controls and input_mux */
91 struct auto_pin_cfg autocfg
;
92 unsigned int num_kctl_alloc
, num_kctl_used
;
93 struct snd_kcontrol_new
*kctl_alloc
;
94 struct hda_input_mux private_imux
;
97 static hda_nid_t stac9200_adc_nids
[1] = {
101 static hda_nid_t stac9200_mux_nids
[1] = {
105 static hda_nid_t stac9200_dac_nids
[1] = {
109 static hda_nid_t stac922x_adc_nids
[2] = {
113 static hda_nid_t stac9227_adc_nids
[2] = {
118 static hda_nid_t d965_2112_dac_nids
[3] = {
123 static hda_nid_t stac922x_mux_nids
[2] = {
127 static hda_nid_t stac9227_mux_nids
[2] = {
131 static hda_nid_t stac927x_adc_nids
[3] = {
135 static hda_nid_t stac927x_mux_nids
[3] = {
139 static hda_nid_t stac9200_pin_nids
[8] = {
140 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
143 static hda_nid_t stac922x_pin_nids
[10] = {
144 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
145 0x0f, 0x10, 0x11, 0x15, 0x1b,
148 static hda_nid_t stac927x_pin_nids
[14] = {
149 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
150 0x0f, 0x10, 0x11, 0x12, 0x13,
151 0x14, 0x21, 0x22, 0x23,
154 static int stac92xx_mux_enum_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
156 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
157 struct sigmatel_spec
*spec
= codec
->spec
;
158 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
161 static int stac92xx_mux_enum_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
163 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
164 struct sigmatel_spec
*spec
= codec
->spec
;
165 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
167 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
171 static int stac92xx_mux_enum_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
173 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
174 struct sigmatel_spec
*spec
= codec
->spec
;
175 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
177 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
178 spec
->mux_nids
[adc_idx
], &spec
->cur_mux
[adc_idx
]);
181 static struct hda_verb stac9200_core_init
[] = {
182 /* set dac0mux for dac converter */
183 { 0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
187 static struct hda_verb stac922x_core_init
[] = {
188 /* set master volume and direct control */
189 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
193 static struct hda_verb stac9227_core_init
[] = {
194 /* set master volume and direct control */
195 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
196 /* unmute node 0x1b */
197 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
201 static struct hda_verb d965_2112_core_init
[] = {
202 /* set master volume and direct control */
203 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
204 /* unmute node 0x1b */
205 { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
206 /* select node 0x03 as DAC */
207 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x01},
211 static struct hda_verb stac927x_core_init
[] = {
212 /* set master volume and direct control */
213 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
217 static struct snd_kcontrol_new stac9200_mixer
[] = {
218 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT
),
219 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT
),
221 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
222 .name
= "Input Source",
224 .info
= stac92xx_mux_enum_info
,
225 .get
= stac92xx_mux_enum_get
,
226 .put
= stac92xx_mux_enum_put
,
228 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT
),
229 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT
),
230 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT
),
234 /* This needs to be generated dynamically based on sequence */
235 static struct snd_kcontrol_new stac922x_mixer
[] = {
237 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
238 .name
= "Input Source",
240 .info
= stac92xx_mux_enum_info
,
241 .get
= stac92xx_mux_enum_get
,
242 .put
= stac92xx_mux_enum_put
,
244 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT
),
245 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT
),
246 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT
),
250 /* This needs to be generated dynamically based on sequence */
251 static struct snd_kcontrol_new stac9227_mixer
[] = {
253 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
254 .name
= "Input Source",
256 .info
= stac92xx_mux_enum_info
,
257 .get
= stac92xx_mux_enum_get
,
258 .put
= stac92xx_mux_enum_put
,
260 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT
),
261 HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT
),
265 static snd_kcontrol_new_t stac927x_mixer
[] = {
267 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
268 .name
= "Input Source",
270 .info
= stac92xx_mux_enum_info
,
271 .get
= stac92xx_mux_enum_get
,
272 .put
= stac92xx_mux_enum_put
,
274 HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT
),
275 HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT
),
276 HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT
),
280 static int stac92xx_build_controls(struct hda_codec
*codec
)
282 struct sigmatel_spec
*spec
= codec
->spec
;
286 err
= snd_hda_add_new_ctls(codec
, spec
->mixer
);
290 for (i
= 0; i
< spec
->num_mixers
; i
++) {
291 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
296 if (spec
->multiout
.dig_out_nid
) {
297 err
= snd_hda_create_spdif_out_ctls(codec
, spec
->multiout
.dig_out_nid
);
301 if (spec
->dig_in_nid
) {
302 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
309 static unsigned int ref9200_pin_configs
[8] = {
310 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
311 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
314 static unsigned int *stac9200_brd_tbl
[] = {
318 static struct hda_board_config stac9200_cfg_tbl
[] = {
319 { .modelname
= "ref",
320 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
321 .pci_subdevice
= 0x2668, /* DFI LanParty */
322 .config
= STAC_REF
},
326 static unsigned int ref922x_pin_configs
[10] = {
327 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
328 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
329 0x40000100, 0x40000100,
332 static unsigned int d945gtp3_pin_configs
[10] = {
333 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
334 0x40000100, 0x40000100, 0x40000100, 0x40000100,
335 0x02a19120, 0x40000100,
338 static unsigned int d945gtp5_pin_configs
[10] = {
339 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
340 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
341 0x02a19320, 0x40000100,
344 static unsigned int d965_2112_pin_configs
[10] = {
345 0x0221401f, 0x40000100, 0x40000100, 0x01014011,
346 0x01a19021, 0x01813024, 0x01452130, 0x40000100,
347 0x02a19320, 0x40000100,
350 static unsigned int *stac922x_brd_tbl
[STAC_922X_MODELS
] = {
351 [STAC_REF
] = ref922x_pin_configs
,
352 [STAC_D945GTP3
] = d945gtp3_pin_configs
,
353 [STAC_D945GTP5
] = d945gtp5_pin_configs
,
354 [STAC_MACMINI
] = d945gtp5_pin_configs
,
355 [STAC_D965_2112
] = d965_2112_pin_configs
,
358 static struct hda_board_config stac922x_cfg_tbl
[] = {
359 { .modelname
= "ref",
360 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
361 .pci_subdevice
= 0x2668, /* DFI LanParty */
362 .config
= STAC_REF
}, /* SigmaTel reference board */
363 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
364 .pci_subdevice
= 0x0101,
365 .config
= STAC_D945GTP3
}, /* Intel D945GTP - 3 Stack */
366 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
367 .pci_subdevice
= 0x0202,
368 .config
= STAC_D945GTP3
}, /* Intel D945GNT - 3 Stack, 9221 A1 */
369 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
370 .pci_subdevice
= 0x0b0b,
371 .config
= STAC_D945GTP3
}, /* Intel D945PSN - 3 Stack, 9221 A1 */
372 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
373 .pci_subdevice
= 0x0707,
374 .config
= STAC_D945GTP5
}, /* Intel D945PSV - 5 Stack */
375 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
376 .pci_subdevice
= 0x0404,
377 .config
= STAC_D945GTP5
}, /* Intel D945GTP - 5 Stack */
378 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
379 .pci_subdevice
= 0x0303,
380 .config
= STAC_D945GTP5
}, /* Intel D945GNT - 5 Stack */
381 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
382 .pci_subdevice
= 0x0013,
383 .config
= STAC_D945GTP5
}, /* Intel D955XBK - 5 Stack */
384 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
385 .pci_subdevice
= 0x0417,
386 .config
= STAC_D945GTP5
}, /* Intel D975XBK - 5 Stack */
387 { .pci_subvendor
= 0x8384,
388 .pci_subdevice
= 0x7680,
389 .config
= STAC_MACMINI
}, /* Apple Mac Mini (early 2006) */
390 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
391 .pci_subdevice
= 0x2112,
392 .config
= STAC_D965_2112
},
393 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
394 .pci_subdevice
= 0x284b,
395 .config
= STAC_D965_284B
},
399 static unsigned int ref927x_pin_configs
[14] = {
400 0x01813122, 0x01a19021, 0x01014010, 0x01016011,
401 0x01012012, 0x01011014, 0x40000100, 0x40000100,
402 0x40000100, 0x40000100, 0x40000100, 0x01441030,
403 0x01c41030, 0x40000100,
406 static unsigned int *stac927x_brd_tbl
[] = {
410 static struct hda_board_config stac927x_cfg_tbl
[] = {
411 { .modelname
= "ref",
412 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
413 .pci_subdevice
= 0x2668, /* DFI LanParty */
414 .config
= STAC_REF
}, /* SigmaTel reference board */
418 static void stac92xx_set_config_regs(struct hda_codec
*codec
)
421 struct sigmatel_spec
*spec
= codec
->spec
;
422 unsigned int pin_cfg
;
424 for (i
=0; i
< spec
->num_pins
; i
++) {
425 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
426 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
,
427 spec
->pin_configs
[i
] & 0x000000ff);
428 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
429 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1
,
430 (spec
->pin_configs
[i
] & 0x0000ff00) >> 8);
431 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
432 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2
,
433 (spec
->pin_configs
[i
] & 0x00ff0000) >> 16);
434 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
435 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3
,
436 spec
->pin_configs
[i
] >> 24);
437 pin_cfg
= snd_hda_codec_read(codec
, spec
->pin_nids
[i
], 0,
438 AC_VERB_GET_CONFIG_DEFAULT
,
440 snd_printdd(KERN_INFO
"hda_codec: pin nid %2.2x pin config %8.8x\n", spec
->pin_nids
[i
], pin_cfg
);
445 * Analog playback callbacks
447 static int stac92xx_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
448 struct hda_codec
*codec
,
449 struct snd_pcm_substream
*substream
)
451 struct sigmatel_spec
*spec
= codec
->spec
;
452 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
455 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
456 struct hda_codec
*codec
,
457 unsigned int stream_tag
,
459 struct snd_pcm_substream
*substream
)
461 struct sigmatel_spec
*spec
= codec
->spec
;
462 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
, stream_tag
, format
, substream
);
465 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
466 struct hda_codec
*codec
,
467 struct snd_pcm_substream
*substream
)
469 struct sigmatel_spec
*spec
= codec
->spec
;
470 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
474 * Digital playback callbacks
476 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
477 struct hda_codec
*codec
,
478 struct snd_pcm_substream
*substream
)
480 struct sigmatel_spec
*spec
= codec
->spec
;
481 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
484 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
485 struct hda_codec
*codec
,
486 struct snd_pcm_substream
*substream
)
488 struct sigmatel_spec
*spec
= codec
->spec
;
489 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
494 * Analog capture callbacks
496 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
497 struct hda_codec
*codec
,
498 unsigned int stream_tag
,
500 struct snd_pcm_substream
*substream
)
502 struct sigmatel_spec
*spec
= codec
->spec
;
504 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
505 stream_tag
, 0, format
);
509 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
510 struct hda_codec
*codec
,
511 struct snd_pcm_substream
*substream
)
513 struct sigmatel_spec
*spec
= codec
->spec
;
515 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
], 0, 0, 0);
519 static struct hda_pcm_stream stac92xx_pcm_digital_playback
= {
523 /* NID is set in stac92xx_build_pcms */
525 .open
= stac92xx_dig_playback_pcm_open
,
526 .close
= stac92xx_dig_playback_pcm_close
530 static struct hda_pcm_stream stac92xx_pcm_digital_capture
= {
534 /* NID is set in stac92xx_build_pcms */
537 static struct hda_pcm_stream stac92xx_pcm_analog_playback
= {
541 .nid
= 0x02, /* NID to query formats and rates */
543 .open
= stac92xx_playback_pcm_open
,
544 .prepare
= stac92xx_playback_pcm_prepare
,
545 .cleanup
= stac92xx_playback_pcm_cleanup
549 static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback
= {
553 .nid
= 0x06, /* NID to query formats and rates */
555 .open
= stac92xx_playback_pcm_open
,
556 .prepare
= stac92xx_playback_pcm_prepare
,
557 .cleanup
= stac92xx_playback_pcm_cleanup
561 static struct hda_pcm_stream stac92xx_pcm_analog_capture
= {
565 /* NID is set in stac92xx_build_pcms */
567 .prepare
= stac92xx_capture_pcm_prepare
,
568 .cleanup
= stac92xx_capture_pcm_cleanup
572 static int stac92xx_build_pcms(struct hda_codec
*codec
)
574 struct sigmatel_spec
*spec
= codec
->spec
;
575 struct hda_pcm
*info
= spec
->pcm_rec
;
578 codec
->pcm_info
= info
;
580 info
->name
= "STAC92xx Analog";
581 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_playback
;
582 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_analog_capture
;
583 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
585 if (spec
->alt_switch
) {
588 info
->name
= "STAC92xx Analog Alt";
589 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_alt_playback
;
592 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
595 info
->name
= "STAC92xx Digital";
596 if (spec
->multiout
.dig_out_nid
) {
597 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_digital_playback
;
598 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
600 if (spec
->dig_in_nid
) {
601 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_digital_capture
;
602 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
609 static unsigned int stac92xx_get_vref(struct hda_codec
*codec
, hda_nid_t nid
)
611 unsigned int pincap
= snd_hda_param_read(codec
, nid
,
613 pincap
= (pincap
& AC_PINCAP_VREF
) >> AC_PINCAP_VREF_SHIFT
;
614 if (pincap
& AC_PINCAP_VREF_100
)
615 return AC_PINCTL_VREF_100
;
616 if (pincap
& AC_PINCAP_VREF_80
)
617 return AC_PINCTL_VREF_80
;
618 if (pincap
& AC_PINCAP_VREF_50
)
619 return AC_PINCTL_VREF_50
;
620 if (pincap
& AC_PINCAP_VREF_GRD
)
621 return AC_PINCTL_VREF_GRD
;
625 static void stac92xx_auto_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
, int pin_type
)
628 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
631 static int stac92xx_io_switch_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
633 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
635 uinfo
->value
.integer
.min
= 0;
636 uinfo
->value
.integer
.max
= 1;
640 static int stac92xx_io_switch_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
642 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
643 struct sigmatel_spec
*spec
= codec
->spec
;
644 int io_idx
= kcontrol
-> private_value
& 0xff;
646 ucontrol
->value
.integer
.value
[0] = spec
->io_switch
[io_idx
];
650 static int stac92xx_io_switch_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
652 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
653 struct sigmatel_spec
*spec
= codec
->spec
;
654 hda_nid_t nid
= kcontrol
->private_value
>> 8;
655 int io_idx
= kcontrol
-> private_value
& 0xff;
656 unsigned short val
= ucontrol
->value
.integer
.value
[0];
658 spec
->io_switch
[io_idx
] = val
;
661 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
663 unsigned int pinctl
= AC_PINCTL_IN_EN
;
664 if (io_idx
) /* set VREF for mic */
665 pinctl
|= stac92xx_get_vref(codec
, nid
);
666 stac92xx_auto_set_pinctl(codec
, nid
, pinctl
);
671 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
672 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
675 .info = stac92xx_io_switch_info, \
676 .get = stac92xx_io_switch_get, \
677 .put = stac92xx_io_switch_put, \
678 .private_value = xpval, \
684 STAC_CTL_WIDGET_MUTE
,
685 STAC_CTL_WIDGET_IO_SWITCH
,
688 static struct snd_kcontrol_new stac92xx_control_templates
[] = {
689 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
690 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
691 STAC_CODEC_IO_SWITCH(NULL
, 0),
694 /* add dynamic controls */
695 static int stac92xx_add_control(struct sigmatel_spec
*spec
, int type
, const char *name
, unsigned long val
)
697 struct snd_kcontrol_new
*knew
;
699 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
700 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
702 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
); /* array + terminator */
705 if (spec
->kctl_alloc
) {
706 memcpy(knew
, spec
->kctl_alloc
, sizeof(*knew
) * spec
->num_kctl_alloc
);
707 kfree(spec
->kctl_alloc
);
709 spec
->kctl_alloc
= knew
;
710 spec
->num_kctl_alloc
= num
;
713 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
714 *knew
= stac92xx_control_templates
[type
];
715 knew
->name
= kstrdup(name
, GFP_KERNEL
);
718 knew
->private_value
= val
;
719 spec
->num_kctl_used
++;
723 /* flag inputs as additional dynamic lineouts */
724 static int stac92xx_add_dyn_out_pins(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
726 struct sigmatel_spec
*spec
= codec
->spec
;
728 switch (cfg
->line_outs
) {
730 /* add line-in as side */
731 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
732 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_LINE
];
733 spec
->line_switch
= 1;
738 /* add line-in as clfe and mic as side */
739 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
740 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_LINE
];
741 spec
->line_switch
= 1;
744 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
745 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_MIC
];
746 spec
->mic_switch
= 1;
751 /* add line-in as surr and mic as clfe */
752 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
753 cfg
->line_out_pins
[1] = cfg
->input_pins
[AUTO_PIN_LINE
];
754 spec
->line_switch
= 1;
757 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
758 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_MIC
];
759 spec
->mic_switch
= 1;
769 * XXX The line_out pin widget connection list may not be set to the
770 * desired DAC nid. This is the case on 927x where ports A and B can
771 * be routed to several DACs.
773 * This requires an analysis of the line-out/hp pin configuration
774 * to provide a best fit for pin/DAC configurations that are routable.
775 * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
776 * A and B is not supported.
778 /* fill in the dac_nids table from the parsed pin configuration */
779 static int stac92xx_auto_fill_dac_nids(struct hda_codec
*codec
,
780 const struct auto_pin_cfg
*cfg
)
782 struct sigmatel_spec
*spec
= codec
->spec
;
786 /* check the pins hardwired to audio widget */
787 for (i
= 0; i
< cfg
->line_outs
; i
++) {
788 nid
= cfg
->line_out_pins
[i
];
789 spec
->multiout
.dac_nids
[i
] = snd_hda_codec_read(codec
, nid
, 0,
790 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
793 spec
->multiout
.num_dacs
= cfg
->line_outs
;
798 /* add playback controls from the parsed DAC table */
799 static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec
*spec
,
800 const struct auto_pin_cfg
*cfg
)
803 static const char *chname
[4] = {
804 "Front", "Surround", NULL
/*CLFE*/, "Side"
809 for (i
= 0; i
< cfg
->line_outs
; i
++) {
810 if (!spec
->multiout
.dac_nids
[i
])
813 nid
= spec
->multiout
.dac_nids
[i
];
817 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Center Playback Volume",
818 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
820 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "LFE Playback Volume",
821 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
823 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Center Playback Switch",
824 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
826 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "LFE Playback Switch",
827 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
830 sprintf(name
, "%s Playback Volume", chname
[i
]);
831 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, name
,
832 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
834 sprintf(name
, "%s Playback Switch", chname
[i
]);
835 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, name
,
836 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
841 if (spec
->line_switch
)
842 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Line In as Output Switch", cfg
->input_pins
[AUTO_PIN_LINE
] << 8)) < 0)
845 if (spec
->mic_switch
)
846 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Mic as Output Switch", (cfg
->input_pins
[AUTO_PIN_MIC
] << 8) | 1)) < 0)
852 /* add playback controls for HP output */
853 static int stac92xx_auto_create_hp_ctls(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
855 struct sigmatel_spec
*spec
= codec
->spec
;
856 hda_nid_t pin
= cfg
->hp_pin
;
859 unsigned int wid_caps
;
864 wid_caps
= get_wcaps(codec
, pin
);
865 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
868 nid
= snd_hda_codec_read(codec
, pin
, 0, AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
869 for (i
= 0; i
< cfg
->line_outs
; i
++) {
870 if (! spec
->multiout
.dac_nids
[i
])
872 if (spec
->multiout
.dac_nids
[i
] == nid
)
876 spec
->multiout
.hp_nid
= nid
;
878 /* control HP volume/switch on the output mixer amp */
879 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Headphone Playback Volume",
880 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
882 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Headphone Playback Switch",
883 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
889 /* create playback/capture controls for input pins */
890 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
892 struct sigmatel_spec
*spec
= codec
->spec
;
893 struct hda_input_mux
*imux
= &spec
->private_imux
;
894 hda_nid_t con_lst
[HDA_MAX_NUM_INPUTS
];
897 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
899 if (cfg
->input_pins
[i
]) {
900 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
902 for (j
=0; j
<spec
->num_muxes
; j
++) {
903 int num_cons
= snd_hda_get_connections(codec
, spec
->mux_nids
[j
], con_lst
, HDA_MAX_NUM_INPUTS
);
904 for (k
=0; k
<num_cons
; k
++)
905 if (con_lst
[k
] == cfg
->input_pins
[i
]) {
912 imux
->items
[imux
->num_items
].index
= index
;
917 if (imux
->num_items
== 1) {
919 * Set the current input for the muxes.
920 * The STAC9221 has two input muxes with identical source
921 * NID lists. Hopefully this won't get confused.
923 for (i
= 0; i
< spec
->num_muxes
; i
++) {
924 snd_hda_codec_write(codec
, spec
->mux_nids
[i
], 0,
925 AC_VERB_SET_CONNECT_SEL
,
926 imux
->items
[0].index
);
933 static void stac92xx_auto_init_multi_out(struct hda_codec
*codec
)
935 struct sigmatel_spec
*spec
= codec
->spec
;
938 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
939 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
940 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
944 static void stac92xx_auto_init_hp_out(struct hda_codec
*codec
)
946 struct sigmatel_spec
*spec
= codec
->spec
;
949 pin
= spec
->autocfg
.hp_pin
;
950 if (pin
) /* connect to front */
951 stac92xx_auto_set_pinctl(codec
, pin
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
);
954 static int stac92xx_parse_auto_config(struct hda_codec
*codec
, hda_nid_t dig_out
, hda_nid_t dig_in
)
956 struct sigmatel_spec
*spec
= codec
->spec
;
959 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
961 if (! spec
->autocfg
.line_outs
)
962 return 0; /* can't find valid pin config */
964 if ((err
= stac92xx_add_dyn_out_pins(codec
, &spec
->autocfg
)) < 0)
966 if (spec
->multiout
.num_dacs
== 0)
967 if ((err
= stac92xx_auto_fill_dac_nids(codec
, &spec
->autocfg
)) < 0)
970 if ((err
= stac92xx_auto_create_multi_out_ctls(spec
, &spec
->autocfg
)) < 0 ||
971 (err
= stac92xx_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0 ||
972 (err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
975 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
976 if (spec
->multiout
.max_channels
> 2)
977 spec
->surr_switch
= 1;
979 if (spec
->autocfg
.dig_out_pin
)
980 spec
->multiout
.dig_out_nid
= dig_out
;
981 if (spec
->autocfg
.dig_in_pin
)
982 spec
->dig_in_nid
= dig_in
;
984 if (spec
->kctl_alloc
)
985 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
987 spec
->input_mux
= &spec
->private_imux
;
992 /* add playback controls for HP output */
993 static int stac9200_auto_create_hp_ctls(struct hda_codec
*codec
,
994 struct auto_pin_cfg
*cfg
)
996 struct sigmatel_spec
*spec
= codec
->spec
;
997 hda_nid_t pin
= cfg
->hp_pin
;
998 unsigned int wid_caps
;
1003 wid_caps
= get_wcaps(codec
, pin
);
1004 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
1005 spec
->hp_detect
= 1;
1010 static int stac9200_parse_auto_config(struct hda_codec
*codec
)
1012 struct sigmatel_spec
*spec
= codec
->spec
;
1015 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
1018 if ((err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
1021 if ((err
= stac9200_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0)
1024 if (spec
->autocfg
.dig_out_pin
)
1025 spec
->multiout
.dig_out_nid
= 0x05;
1026 if (spec
->autocfg
.dig_in_pin
)
1027 spec
->dig_in_nid
= 0x04;
1029 if (spec
->kctl_alloc
)
1030 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
1032 spec
->input_mux
= &spec
->private_imux
;
1038 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
1039 * funky external mute control using GPIO pins.
1042 static void stac922x_gpio_mute(struct hda_codec
*codec
, int pin
, int muted
)
1044 unsigned int gpiostate
, gpiomask
, gpiodir
;
1046 gpiostate
= snd_hda_codec_read(codec
, codec
->afg
, 0,
1047 AC_VERB_GET_GPIO_DATA
, 0);
1050 gpiostate
|= (1 << pin
);
1052 gpiostate
&= ~(1 << pin
);
1054 gpiomask
= snd_hda_codec_read(codec
, codec
->afg
, 0,
1055 AC_VERB_GET_GPIO_MASK
, 0);
1056 gpiomask
|= (1 << pin
);
1058 gpiodir
= snd_hda_codec_read(codec
, codec
->afg
, 0,
1059 AC_VERB_GET_GPIO_DIRECTION
, 0);
1060 gpiodir
|= (1 << pin
);
1062 /* AppleHDA seems to do this -- WTF is this verb?? */
1063 snd_hda_codec_write(codec
, codec
->afg
, 0, 0x7e7, 0);
1065 snd_hda_codec_write(codec
, codec
->afg
, 0,
1066 AC_VERB_SET_GPIO_MASK
, gpiomask
);
1067 snd_hda_codec_write(codec
, codec
->afg
, 0,
1068 AC_VERB_SET_GPIO_DIRECTION
, gpiodir
);
1072 snd_hda_codec_write(codec
, codec
->afg
, 0,
1073 AC_VERB_SET_GPIO_DATA
, gpiostate
);
1076 static int stac92xx_init(struct hda_codec
*codec
)
1078 struct sigmatel_spec
*spec
= codec
->spec
;
1079 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
1082 snd_hda_sequence_write(codec
, spec
->init
);
1085 if (spec
->hp_detect
) {
1086 /* Enable unsolicited responses on the HP widget */
1087 snd_hda_codec_write(codec
, cfg
->hp_pin
, 0,
1088 AC_VERB_SET_UNSOLICITED_ENABLE
,
1090 /* fake event to set up pins */
1091 codec
->patch_ops
.unsol_event(codec
, STAC_HP_EVENT
<< 26);
1093 stac92xx_auto_init_multi_out(codec
);
1094 stac92xx_auto_init_hp_out(codec
);
1096 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
1097 hda_nid_t nid
= cfg
->input_pins
[i
];
1099 unsigned int pinctl
= AC_PINCTL_IN_EN
;
1100 if (i
== AUTO_PIN_MIC
|| i
== AUTO_PIN_FRONT_MIC
)
1101 pinctl
|= stac92xx_get_vref(codec
, nid
);
1102 stac92xx_auto_set_pinctl(codec
, nid
, pinctl
);
1105 if (cfg
->dig_out_pin
)
1106 stac92xx_auto_set_pinctl(codec
, cfg
->dig_out_pin
,
1108 if (cfg
->dig_in_pin
)
1109 stac92xx_auto_set_pinctl(codec
, cfg
->dig_in_pin
,
1112 if (spec
->gpio_mute
) {
1113 stac922x_gpio_mute(codec
, 0, 0);
1114 stac922x_gpio_mute(codec
, 1, 0);
1120 static void stac92xx_free(struct hda_codec
*codec
)
1122 struct sigmatel_spec
*spec
= codec
->spec
;
1128 if (spec
->kctl_alloc
) {
1129 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
1130 kfree(spec
->kctl_alloc
[i
].name
);
1131 kfree(spec
->kctl_alloc
);
1137 static void stac92xx_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
1140 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
1141 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
1142 snd_hda_codec_write(codec
, nid
, 0,
1143 AC_VERB_SET_PIN_WIDGET_CONTROL
,
1147 static void stac92xx_reset_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
1150 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
1151 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
1152 snd_hda_codec_write(codec
, nid
, 0,
1153 AC_VERB_SET_PIN_WIDGET_CONTROL
,
1157 static void stac92xx_unsol_event(struct hda_codec
*codec
, unsigned int res
)
1159 struct sigmatel_spec
*spec
= codec
->spec
;
1160 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
1163 if ((res
>> 26) != STAC_HP_EVENT
)
1166 presence
= snd_hda_codec_read(codec
, cfg
->hp_pin
, 0,
1167 AC_VERB_GET_PIN_SENSE
, 0x00) >> 31;
1170 /* disable lineouts, enable hp */
1171 for (i
= 0; i
< cfg
->line_outs
; i
++)
1172 stac92xx_reset_pinctl(codec
, cfg
->line_out_pins
[i
],
1174 stac92xx_set_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
1176 /* enable lineouts, disable hp */
1177 for (i
= 0; i
< cfg
->line_outs
; i
++)
1178 stac92xx_set_pinctl(codec
, cfg
->line_out_pins
[i
],
1180 stac92xx_reset_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
1185 static int stac92xx_resume(struct hda_codec
*codec
)
1187 struct sigmatel_spec
*spec
= codec
->spec
;
1190 stac92xx_init(codec
);
1191 for (i
= 0; i
< spec
->num_mixers
; i
++)
1192 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
1193 if (spec
->multiout
.dig_out_nid
)
1194 snd_hda_resume_spdif_out(codec
);
1195 if (spec
->dig_in_nid
)
1196 snd_hda_resume_spdif_in(codec
);
1202 static struct hda_codec_ops stac92xx_patch_ops
= {
1203 .build_controls
= stac92xx_build_controls
,
1204 .build_pcms
= stac92xx_build_pcms
,
1205 .init
= stac92xx_init
,
1206 .free
= stac92xx_free
,
1207 .unsol_event
= stac92xx_unsol_event
,
1209 .resume
= stac92xx_resume
,
1213 static int patch_stac9200(struct hda_codec
*codec
)
1215 struct sigmatel_spec
*spec
;
1218 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1223 spec
->board_config
= snd_hda_check_board_config(codec
, stac9200_cfg_tbl
);
1224 if (spec
->board_config
< 0)
1225 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
1228 spec
->pin_nids
= stac9200_pin_nids
;
1229 spec
->pin_configs
= stac9200_brd_tbl
[spec
->board_config
];
1230 stac92xx_set_config_regs(codec
);
1233 spec
->multiout
.max_channels
= 2;
1234 spec
->multiout
.num_dacs
= 1;
1235 spec
->multiout
.dac_nids
= stac9200_dac_nids
;
1236 spec
->adc_nids
= stac9200_adc_nids
;
1237 spec
->mux_nids
= stac9200_mux_nids
;
1238 spec
->num_muxes
= 1;
1240 spec
->init
= stac9200_core_init
;
1241 spec
->mixer
= stac9200_mixer
;
1243 err
= stac9200_parse_auto_config(codec
);
1245 stac92xx_free(codec
);
1249 codec
->patch_ops
= stac92xx_patch_ops
;
1254 static int patch_stac922x(struct hda_codec
*codec
)
1256 struct sigmatel_spec
*spec
;
1259 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1264 spec
->board_config
= snd_hda_check_board_config(codec
, stac922x_cfg_tbl
);
1265 if (spec
->board_config
< 0)
1266 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC922x, "
1267 "using BIOS defaults\n");
1268 else if (stac922x_brd_tbl
[spec
->board_config
] != NULL
) {
1269 spec
->num_pins
= 10;
1270 spec
->pin_nids
= stac922x_pin_nids
;
1271 spec
->pin_configs
= stac922x_brd_tbl
[spec
->board_config
];
1272 stac92xx_set_config_regs(codec
);
1275 spec
->adc_nids
= stac922x_adc_nids
;
1276 spec
->mux_nids
= stac922x_mux_nids
;
1277 spec
->num_muxes
= 2;
1279 spec
->init
= stac922x_core_init
;
1280 spec
->mixer
= stac922x_mixer
;
1282 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1284 switch (spec
->board_config
) {
1285 case STAC_D965_2112
:
1286 spec
->adc_nids
= stac9227_adc_nids
;
1287 spec
->mux_nids
= stac9227_mux_nids
;
1289 spec
->multiout
.dac_nids
= d965_2112_dac_nids
;
1290 spec
->multiout
.num_dacs
= ARRAY_SIZE(d965_2112_dac_nids
);
1292 spec
->init
= d965_2112_core_init
;
1293 spec
->mixer
= stac9227_mixer
;
1295 case STAC_D965_284B
:
1296 spec
->adc_nids
= stac9227_adc_nids
;
1297 spec
->mux_nids
= stac9227_mux_nids
;
1298 spec
->init
= stac9227_core_init
;
1299 spec
->mixer
= stac9227_mixer
;
1303 err
= stac92xx_parse_auto_config(codec
, 0x08, 0x09);
1305 stac92xx_free(codec
);
1309 if (spec
->board_config
== STAC_MACMINI
)
1310 spec
->gpio_mute
= 1;
1312 codec
->patch_ops
= stac92xx_patch_ops
;
1317 static int patch_stac927x(struct hda_codec
*codec
)
1319 struct sigmatel_spec
*spec
;
1322 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1327 spec
->board_config
= snd_hda_check_board_config(codec
, stac927x_cfg_tbl
);
1328 if (spec
->board_config
< 0)
1329 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
1331 spec
->num_pins
= 14;
1332 spec
->pin_nids
= stac927x_pin_nids
;
1333 spec
->pin_configs
= stac927x_brd_tbl
[spec
->board_config
];
1334 stac92xx_set_config_regs(codec
);
1337 spec
->adc_nids
= stac927x_adc_nids
;
1338 spec
->mux_nids
= stac927x_mux_nids
;
1339 spec
->num_muxes
= 3;
1341 spec
->init
= stac927x_core_init
;
1342 spec
->mixer
= stac927x_mixer
;
1344 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1346 err
= stac92xx_parse_auto_config(codec
, 0x1e, 0x20);
1348 stac92xx_free(codec
);
1352 codec
->patch_ops
= stac92xx_patch_ops
;
1361 /* static config for Sony VAIO FE550G */
1362 static hda_nid_t vaio_dacs
[] = { 0x2 };
1363 #define VAIO_HP_DAC 0x5
1364 static hda_nid_t vaio_adcs
[] = { 0x8 /*,0x6*/ };
1365 static hda_nid_t vaio_mux_nids
[] = { 0x15 };
1367 static struct hda_input_mux vaio_mux
= {
1370 /* { "HP", 0x0 }, */
1377 static struct hda_verb vaio_init
[] = {
1378 {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP <- 0x2 */
1379 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Speaker <- 0x5 */
1380 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? (<- 0x2) */
1381 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* CD */
1382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Mic? */
1383 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x2}, /* mic-sel: 0a,0d,14,02 */
1384 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* HP */
1385 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
}, /* Speaker */
1386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
1387 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
1388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
}, /* Mic-in -> 0x9 */
1392 /* bind volumes of both NID 0x02 and 0x05 */
1393 static int vaio_master_vol_put(struct snd_kcontrol
*kcontrol
,
1394 struct snd_ctl_elem_value
*ucontrol
)
1396 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1397 long *valp
= ucontrol
->value
.integer
.value
;
1400 change
= snd_hda_codec_amp_update(codec
, 0x02, 0, HDA_OUTPUT
, 0,
1401 0x7f, valp
[0] & 0x7f);
1402 change
|= snd_hda_codec_amp_update(codec
, 0x02, 1, HDA_OUTPUT
, 0,
1403 0x7f, valp
[1] & 0x7f);
1404 snd_hda_codec_amp_update(codec
, 0x05, 0, HDA_OUTPUT
, 0,
1405 0x7f, valp
[0] & 0x7f);
1406 snd_hda_codec_amp_update(codec
, 0x05, 1, HDA_OUTPUT
, 0,
1407 0x7f, valp
[1] & 0x7f);
1411 /* bind volumes of both NID 0x02 and 0x05 */
1412 static int vaio_master_sw_put(struct snd_kcontrol
*kcontrol
,
1413 struct snd_ctl_elem_value
*ucontrol
)
1415 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1416 long *valp
= ucontrol
->value
.integer
.value
;
1419 change
= snd_hda_codec_amp_update(codec
, 0x02, 0, HDA_OUTPUT
, 0,
1420 0x80, (valp
[0] ? 0 : 0x80));
1421 change
|= snd_hda_codec_amp_update(codec
, 0x02, 1, HDA_OUTPUT
, 0,
1422 0x80, (valp
[1] ? 0 : 0x80));
1423 snd_hda_codec_amp_update(codec
, 0x05, 0, HDA_OUTPUT
, 0,
1424 0x80, (valp
[0] ? 0 : 0x80));
1425 snd_hda_codec_amp_update(codec
, 0x05, 1, HDA_OUTPUT
, 0,
1426 0x80, (valp
[1] ? 0 : 0x80));
1430 static struct snd_kcontrol_new vaio_mixer
[] = {
1432 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1433 .name
= "Master Playback Volume",
1434 .info
= snd_hda_mixer_amp_volume_info
,
1435 .get
= snd_hda_mixer_amp_volume_get
,
1436 .put
= vaio_master_vol_put
,
1437 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1440 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1441 .name
= "Master Playback Switch",
1442 .info
= snd_hda_mixer_amp_switch_info
,
1443 .get
= snd_hda_mixer_amp_switch_get
,
1444 .put
= vaio_master_sw_put
,
1445 .private_value
= HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
1447 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
1448 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT
),
1449 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT
),
1451 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1452 .name
= "Capture Source",
1454 .info
= stac92xx_mux_enum_info
,
1455 .get
= stac92xx_mux_enum_get
,
1456 .put
= stac92xx_mux_enum_put
,
1461 static struct hda_codec_ops stac7661_patch_ops
= {
1462 .build_controls
= stac92xx_build_controls
,
1463 .build_pcms
= stac92xx_build_pcms
,
1464 .init
= stac92xx_init
,
1465 .free
= stac92xx_free
,
1467 .resume
= stac92xx_resume
,
1471 enum { STAC7661_VAIO
};
1473 static struct hda_board_config stac7661_cfg_tbl
[] = {
1474 { .modelname
= "vaio", .config
= STAC7661_VAIO
},
1475 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81e6,
1476 .config
= STAC7661_VAIO
},
1477 { .pci_subvendor
= 0x104d, .pci_subdevice
= 0x81ef,
1478 .config
= STAC7661_VAIO
},
1482 static int patch_stac7661(struct hda_codec
*codec
)
1484 struct sigmatel_spec
*spec
;
1487 board_config
= snd_hda_check_board_config(codec
, stac7661_cfg_tbl
);
1488 if (board_config
< 0)
1489 /* unknown config, let generic-parser do its job... */
1490 return snd_hda_parse_generic_codec(codec
);
1492 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
1497 switch (board_config
) {
1499 spec
->mixer
= vaio_mixer
;
1500 spec
->init
= vaio_init
;
1501 spec
->multiout
.max_channels
= 2;
1502 spec
->multiout
.num_dacs
= ARRAY_SIZE(vaio_dacs
);
1503 spec
->multiout
.dac_nids
= vaio_dacs
;
1504 spec
->multiout
.hp_nid
= VAIO_HP_DAC
;
1505 spec
->num_adcs
= ARRAY_SIZE(vaio_adcs
);
1506 spec
->adc_nids
= vaio_adcs
;
1507 spec
->input_mux
= &vaio_mux
;
1508 spec
->mux_nids
= vaio_mux_nids
;
1512 codec
->patch_ops
= stac7661_patch_ops
;
1520 struct hda_codec_preset snd_hda_preset_sigmatel
[] = {
1521 { .id
= 0x83847690, .name
= "STAC9200", .patch
= patch_stac9200
},
1522 { .id
= 0x83847882, .name
= "STAC9220 A1", .patch
= patch_stac922x
},
1523 { .id
= 0x83847680, .name
= "STAC9221 A1", .patch
= patch_stac922x
},
1524 { .id
= 0x83847880, .name
= "STAC9220 A2", .patch
= patch_stac922x
},
1525 { .id
= 0x83847681, .name
= "STAC9220D/9223D A2", .patch
= patch_stac922x
},
1526 { .id
= 0x83847682, .name
= "STAC9221 A2", .patch
= patch_stac922x
},
1527 { .id
= 0x83847683, .name
= "STAC9221D A2", .patch
= patch_stac922x
},
1528 { .id
= 0x83847618, .name
= "STAC9227", .patch
= patch_stac927x
},
1529 { .id
= 0x83847619, .name
= "STAC9227", .patch
= patch_stac927x
},
1530 { .id
= 0x83847616, .name
= "STAC9228", .patch
= patch_stac927x
},
1531 { .id
= 0x83847617, .name
= "STAC9228", .patch
= patch_stac927x
},
1532 { .id
= 0x83847614, .name
= "STAC9229", .patch
= patch_stac927x
},
1533 { .id
= 0x83847615, .name
= "STAC9229", .patch
= patch_stac927x
},
1534 { .id
= 0x83847620, .name
= "STAC9274", .patch
= patch_stac927x
},
1535 { .id
= 0x83847621, .name
= "STAC9274D", .patch
= patch_stac927x
},
1536 { .id
= 0x83847622, .name
= "STAC9273X", .patch
= patch_stac927x
},
1537 { .id
= 0x83847623, .name
= "STAC9273D", .patch
= patch_stac927x
},
1538 { .id
= 0x83847624, .name
= "STAC9272X", .patch
= patch_stac927x
},
1539 { .id
= 0x83847625, .name
= "STAC9272D", .patch
= patch_stac927x
},
1540 { .id
= 0x83847626, .name
= "STAC9271X", .patch
= patch_stac927x
},
1541 { .id
= 0x83847627, .name
= "STAC9271D", .patch
= patch_stac927x
},
1542 { .id
= 0x83847628, .name
= "STAC9274X5NH", .patch
= patch_stac927x
},
1543 { .id
= 0x83847629, .name
= "STAC9274D5NH", .patch
= patch_stac927x
},
1544 { .id
= 0x83847661, .name
= "STAC7661", .patch
= patch_stac7661
},