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;
55 struct hda_multi_out multiout
;
56 hda_nid_t dac_nids
[4];
60 unsigned int num_adcs
;
62 unsigned int num_muxes
;
67 unsigned int num_pins
;
68 unsigned int *pin_configs
;
70 /* codec specific stuff */
71 struct hda_verb
*init
;
72 struct snd_kcontrol_new
*mixer
;
75 struct hda_input_mux
*input_mux
;
76 unsigned int cur_mux
[2];
79 unsigned int io_switch
[2];
81 struct hda_pcm pcm_rec
[2]; /* PCM information */
83 /* dynamic controls and input_mux */
84 struct auto_pin_cfg autocfg
;
85 unsigned int num_kctl_alloc
, num_kctl_used
;
86 struct snd_kcontrol_new
*kctl_alloc
;
87 struct hda_input_mux private_imux
;
90 static hda_nid_t stac9200_adc_nids
[1] = {
94 static hda_nid_t stac9200_mux_nids
[1] = {
98 static hda_nid_t stac9200_dac_nids
[1] = {
102 static hda_nid_t stac922x_adc_nids
[2] = {
106 static hda_nid_t stac922x_mux_nids
[2] = {
110 static hda_nid_t stac9200_pin_nids
[8] = {
111 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
114 static hda_nid_t stac922x_pin_nids
[10] = {
115 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
116 0x0f, 0x10, 0x11, 0x15, 0x1b,
119 static int stac92xx_mux_enum_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
121 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
122 struct sigmatel_spec
*spec
= codec
->spec
;
123 return snd_hda_input_mux_info(spec
->input_mux
, uinfo
);
126 static int stac92xx_mux_enum_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
128 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
129 struct sigmatel_spec
*spec
= codec
->spec
;
130 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
132 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
136 static int stac92xx_mux_enum_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
138 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
139 struct sigmatel_spec
*spec
= codec
->spec
;
140 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
142 return snd_hda_input_mux_put(codec
, spec
->input_mux
, ucontrol
,
143 spec
->mux_nids
[adc_idx
], &spec
->cur_mux
[adc_idx
]);
146 static struct hda_verb stac9200_core_init
[] = {
147 /* set dac0mux for dac converter */
148 { 0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
152 static struct hda_verb stac922x_core_init
[] = {
153 /* set master volume and direct control */
154 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL
, 0xff},
158 static struct snd_kcontrol_new stac9200_mixer
[] = {
159 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT
),
160 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT
),
162 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
163 .name
= "Input Source",
165 .info
= stac92xx_mux_enum_info
,
166 .get
= stac92xx_mux_enum_get
,
167 .put
= stac92xx_mux_enum_put
,
169 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT
),
170 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT
),
171 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT
),
175 /* This needs to be generated dynamically based on sequence */
176 static struct snd_kcontrol_new stac922x_mixer
[] = {
178 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
179 .name
= "Input Source",
181 .info
= stac92xx_mux_enum_info
,
182 .get
= stac92xx_mux_enum_get
,
183 .put
= stac92xx_mux_enum_put
,
185 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT
),
186 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT
),
190 static int stac92xx_build_controls(struct hda_codec
*codec
)
192 struct sigmatel_spec
*spec
= codec
->spec
;
196 err
= snd_hda_add_new_ctls(codec
, spec
->mixer
);
200 for (i
= 0; i
< spec
->num_mixers
; i
++) {
201 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
206 if (spec
->multiout
.dig_out_nid
) {
207 err
= snd_hda_create_spdif_out_ctls(codec
, spec
->multiout
.dig_out_nid
);
211 if (spec
->dig_in_nid
) {
212 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
219 static unsigned int ref9200_pin_configs
[8] = {
220 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
221 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
224 static unsigned int *stac9200_brd_tbl
[] = {
228 static struct hda_board_config stac9200_cfg_tbl
[] = {
229 { .modelname
= "ref",
230 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
231 .pci_subdevice
= 0x2668, /* DFI LanParty */
232 .config
= STAC_REF
},
236 static unsigned int ref922x_pin_configs
[10] = {
237 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
238 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
239 0x40000100, 0x40000100,
242 static unsigned int d945gtp3_pin_configs
[10] = {
243 0x0221401f, 0x01a19022, 0x01813021, 0x01114010,
244 0x40000100, 0x40000100, 0x40000100, 0x40000100,
245 0x02a19120, 0x40000100,
248 static unsigned int d945gtp5_pin_configs
[10] = {
249 0x0221401f, 0x01111012, 0x01813024, 0x01114010,
250 0x01a19021, 0x01116011, 0x01452130, 0x40000100,
251 0x02a19320, 0x40000100,
254 static unsigned int *stac922x_brd_tbl
[] = {
256 d945gtp3_pin_configs
,
257 d945gtp5_pin_configs
,
260 static struct hda_board_config stac922x_cfg_tbl
[] = {
261 { .modelname
= "ref",
262 .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
263 .pci_subdevice
= 0x2668, /* DFI LanParty */
264 .config
= STAC_REF
}, /* SigmaTel reference board */
265 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
266 .pci_subdevice
= 0x0101,
267 .config
= STAC_D945GTP3
}, /* Intel D945GTP - 3 Stack */
268 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
269 .pci_subdevice
= 0x0404,
270 .config
= STAC_D945GTP5
}, /* Intel D945GTP - 5 Stack */
271 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
272 .pci_subdevice
= 0x0303,
273 .config
= STAC_D945GTP5
}, /* Intel D945GNT - 5 Stack */
274 { .pci_subvendor
= PCI_VENDOR_ID_INTEL
,
275 .pci_subdevice
= 0x0013,
276 .config
= STAC_D945GTP5
}, /* Intel D955XBK - 5 Stack */
280 static void stac92xx_set_config_regs(struct hda_codec
*codec
)
283 struct sigmatel_spec
*spec
= codec
->spec
;
284 unsigned int pin_cfg
;
286 for (i
=0; i
< spec
->num_pins
; i
++) {
287 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
288 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
,
289 spec
->pin_configs
[i
] & 0x000000ff);
290 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
291 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1
,
292 (spec
->pin_configs
[i
] & 0x0000ff00) >> 8);
293 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
294 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2
,
295 (spec
->pin_configs
[i
] & 0x00ff0000) >> 16);
296 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
297 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3
,
298 spec
->pin_configs
[i
] >> 24);
299 pin_cfg
= snd_hda_codec_read(codec
, spec
->pin_nids
[i
], 0,
300 AC_VERB_GET_CONFIG_DEFAULT
,
302 snd_printdd(KERN_INFO
"hda_codec: pin nid %2.2x pin config %8.8x\n", spec
->pin_nids
[i
], pin_cfg
);
307 * Analog playback callbacks
309 static int stac92xx_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
310 struct hda_codec
*codec
,
311 struct snd_pcm_substream
*substream
)
313 struct sigmatel_spec
*spec
= codec
->spec
;
314 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
317 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
318 struct hda_codec
*codec
,
319 unsigned int stream_tag
,
321 struct snd_pcm_substream
*substream
)
323 struct sigmatel_spec
*spec
= codec
->spec
;
324 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
, stream_tag
, format
, substream
);
327 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
328 struct hda_codec
*codec
,
329 struct snd_pcm_substream
*substream
)
331 struct sigmatel_spec
*spec
= codec
->spec
;
332 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
336 * Digital playback callbacks
338 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
339 struct hda_codec
*codec
,
340 struct snd_pcm_substream
*substream
)
342 struct sigmatel_spec
*spec
= codec
->spec
;
343 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
346 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
347 struct hda_codec
*codec
,
348 struct snd_pcm_substream
*substream
)
350 struct sigmatel_spec
*spec
= codec
->spec
;
351 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
356 * Analog capture callbacks
358 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
359 struct hda_codec
*codec
,
360 unsigned int stream_tag
,
362 struct snd_pcm_substream
*substream
)
364 struct sigmatel_spec
*spec
= codec
->spec
;
366 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
367 stream_tag
, 0, format
);
371 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
372 struct hda_codec
*codec
,
373 struct snd_pcm_substream
*substream
)
375 struct sigmatel_spec
*spec
= codec
->spec
;
377 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
], 0, 0, 0);
381 static struct hda_pcm_stream stac92xx_pcm_digital_playback
= {
385 /* NID is set in stac92xx_build_pcms */
387 .open
= stac92xx_dig_playback_pcm_open
,
388 .close
= stac92xx_dig_playback_pcm_close
392 static struct hda_pcm_stream stac92xx_pcm_digital_capture
= {
396 /* NID is set in stac92xx_build_pcms */
399 static struct hda_pcm_stream stac92xx_pcm_analog_playback
= {
403 .nid
= 0x02, /* NID to query formats and rates */
405 .open
= stac92xx_playback_pcm_open
,
406 .prepare
= stac92xx_playback_pcm_prepare
,
407 .cleanup
= stac92xx_playback_pcm_cleanup
411 static struct hda_pcm_stream stac92xx_pcm_analog_capture
= {
415 .nid
= 0x06, /* NID to query formats and rates */
417 .prepare
= stac92xx_capture_pcm_prepare
,
418 .cleanup
= stac92xx_capture_pcm_cleanup
422 static int stac92xx_build_pcms(struct hda_codec
*codec
)
424 struct sigmatel_spec
*spec
= codec
->spec
;
425 struct hda_pcm
*info
= spec
->pcm_rec
;
428 codec
->pcm_info
= info
;
430 info
->name
= "STAC92xx Analog";
431 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_playback
;
432 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_analog_capture
;
434 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
437 info
->name
= "STAC92xx Digital";
438 if (spec
->multiout
.dig_out_nid
) {
439 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_digital_playback
;
440 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
442 if (spec
->dig_in_nid
) {
443 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_digital_capture
;
444 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
451 static void stac92xx_auto_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
, int pin_type
)
454 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
457 static int stac92xx_io_switch_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
459 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
461 uinfo
->value
.integer
.min
= 0;
462 uinfo
->value
.integer
.max
= 1;
466 static int stac92xx_io_switch_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
468 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
469 struct sigmatel_spec
*spec
= codec
->spec
;
470 int io_idx
= kcontrol
-> private_value
& 0xff;
472 ucontrol
->value
.integer
.value
[0] = spec
->io_switch
[io_idx
];
476 static int stac92xx_io_switch_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
478 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
479 struct sigmatel_spec
*spec
= codec
->spec
;
480 hda_nid_t nid
= kcontrol
->private_value
>> 8;
481 int io_idx
= kcontrol
-> private_value
& 0xff;
482 unsigned short val
= ucontrol
->value
.integer
.value
[0];
484 spec
->io_switch
[io_idx
] = val
;
487 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
489 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_IN_EN
);
494 #define STAC_CODEC_IO_SWITCH(xname, xpval) \
495 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
498 .info = stac92xx_io_switch_info, \
499 .get = stac92xx_io_switch_get, \
500 .put = stac92xx_io_switch_put, \
501 .private_value = xpval, \
507 STAC_CTL_WIDGET_MUTE
,
508 STAC_CTL_WIDGET_IO_SWITCH
,
511 static struct snd_kcontrol_new stac92xx_control_templates
[] = {
512 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
513 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
514 STAC_CODEC_IO_SWITCH(NULL
, 0),
517 /* add dynamic controls */
518 static int stac92xx_add_control(struct sigmatel_spec
*spec
, int type
, const char *name
, unsigned long val
)
520 struct snd_kcontrol_new
*knew
;
522 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
523 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
525 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
); /* array + terminator */
528 if (spec
->kctl_alloc
) {
529 memcpy(knew
, spec
->kctl_alloc
, sizeof(*knew
) * spec
->num_kctl_alloc
);
530 kfree(spec
->kctl_alloc
);
532 spec
->kctl_alloc
= knew
;
533 spec
->num_kctl_alloc
= num
;
536 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
537 *knew
= stac92xx_control_templates
[type
];
538 knew
->name
= kstrdup(name
, GFP_KERNEL
);
541 knew
->private_value
= val
;
542 spec
->num_kctl_used
++;
546 /* flag inputs as additional dynamic lineouts */
547 static int stac92xx_add_dyn_out_pins(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
549 struct sigmatel_spec
*spec
= codec
->spec
;
551 switch (cfg
->line_outs
) {
553 /* add line-in as side */
554 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
555 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_LINE
];
556 spec
->line_switch
= 1;
561 /* add line-in as clfe and mic as side */
562 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
563 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_LINE
];
564 spec
->line_switch
= 1;
567 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
568 cfg
->line_out_pins
[3] = cfg
->input_pins
[AUTO_PIN_MIC
];
569 spec
->mic_switch
= 1;
574 /* add line-in as surr and mic as clfe */
575 if (cfg
->input_pins
[AUTO_PIN_LINE
]) {
576 cfg
->line_out_pins
[1] = cfg
->input_pins
[AUTO_PIN_LINE
];
577 spec
->line_switch
= 1;
580 if (cfg
->input_pins
[AUTO_PIN_MIC
]) {
581 cfg
->line_out_pins
[2] = cfg
->input_pins
[AUTO_PIN_MIC
];
582 spec
->mic_switch
= 1;
591 /* fill in the dac_nids table from the parsed pin configuration */
592 static int stac92xx_auto_fill_dac_nids(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
594 struct sigmatel_spec
*spec
= codec
->spec
;
598 /* check the pins hardwired to audio widget */
599 for (i
= 0; i
< cfg
->line_outs
; i
++) {
600 nid
= cfg
->line_out_pins
[i
];
601 spec
->multiout
.dac_nids
[i
] = snd_hda_codec_read(codec
, nid
, 0,
602 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
605 spec
->multiout
.num_dacs
= cfg
->line_outs
;
610 /* add playback controls from the parsed DAC table */
611 static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec
*spec
, const struct auto_pin_cfg
*cfg
)
614 static const char *chname
[4] = { "Front", "Surround", NULL
/*CLFE*/, "Side" };
618 for (i
= 0; i
< cfg
->line_outs
; i
++) {
619 if (!spec
->multiout
.dac_nids
[i
])
622 nid
= spec
->multiout
.dac_nids
[i
];
626 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Center Playback Volume",
627 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
629 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "LFE Playback Volume",
630 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
632 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Center Playback Switch",
633 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
635 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "LFE Playback Switch",
636 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
639 sprintf(name
, "%s Playback Volume", chname
[i
]);
640 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, name
,
641 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
643 sprintf(name
, "%s Playback Switch", chname
[i
]);
644 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, name
,
645 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
650 if (spec
->line_switch
)
651 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Line In as Output Switch", cfg
->input_pins
[AUTO_PIN_LINE
] << 8)) < 0)
654 if (spec
->mic_switch
)
655 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_IO_SWITCH
, "Mic as Output Switch", (cfg
->input_pins
[AUTO_PIN_MIC
] << 8) | 1)) < 0)
661 /* add playback controls for HP output */
662 static int stac92xx_auto_create_hp_ctls(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
664 struct sigmatel_spec
*spec
= codec
->spec
;
665 hda_nid_t pin
= cfg
->hp_pin
;
668 unsigned int wid_caps
;
673 wid_caps
= get_wcaps(codec
, pin
);
674 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
675 /* Enable unsolicited responses on the HP widget */
676 snd_hda_codec_write(codec
, pin
, 0,
677 AC_VERB_SET_UNSOLICITED_ENABLE
,
680 nid
= snd_hda_codec_read(codec
, pin
, 0, AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
681 for (i
= 0; i
< cfg
->line_outs
; i
++) {
682 if (! spec
->multiout
.dac_nids
[i
])
684 if (spec
->multiout
.dac_nids
[i
] == nid
)
688 spec
->multiout
.hp_nid
= nid
;
690 /* control HP volume/switch on the output mixer amp */
691 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Headphone Playback Volume",
692 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
694 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Headphone Playback Switch",
695 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
701 /* create playback/capture controls for input pins */
702 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
704 struct sigmatel_spec
*spec
= codec
->spec
;
705 static char *labels
[AUTO_PIN_LAST
] = {
706 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
708 struct hda_input_mux
*imux
= &spec
->private_imux
;
709 hda_nid_t con_lst
[HDA_MAX_NUM_INPUTS
];
712 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
714 if (cfg
->input_pins
[i
]) {
715 /* Enable active pin widget as an input */
716 stac92xx_auto_set_pinctl(codec
, cfg
->input_pins
[i
], AC_PINCTL_IN_EN
);
718 imux
->items
[imux
->num_items
].label
= labels
[i
];
720 for (j
=0; j
<spec
->num_muxes
; j
++) {
721 int num_cons
= snd_hda_get_connections(codec
, spec
->mux_nids
[j
], con_lst
, HDA_MAX_NUM_INPUTS
);
722 for (k
=0; k
<num_cons
; k
++)
723 if (con_lst
[k
] == cfg
->input_pins
[i
]) {
730 imux
->items
[imux
->num_items
].index
= index
;
738 static void stac92xx_auto_init_multi_out(struct hda_codec
*codec
)
740 struct sigmatel_spec
*spec
= codec
->spec
;
743 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
744 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
745 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
749 static void stac92xx_auto_init_hp_out(struct hda_codec
*codec
)
751 struct sigmatel_spec
*spec
= codec
->spec
;
754 pin
= spec
->autocfg
.hp_pin
;
755 if (pin
) /* connect to front */
756 stac92xx_auto_set_pinctl(codec
, pin
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
);
759 static int stac922x_parse_auto_config(struct hda_codec
*codec
)
761 struct sigmatel_spec
*spec
= codec
->spec
;
764 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
766 if ((err
= stac92xx_add_dyn_out_pins(codec
, &spec
->autocfg
)) < 0)
768 if ((err
= stac92xx_auto_fill_dac_nids(codec
, &spec
->autocfg
)) < 0)
770 if (! spec
->autocfg
.line_outs
&& ! spec
->autocfg
.hp_pin
)
771 return 0; /* can't find valid pin config */
773 if ((err
= stac92xx_auto_create_multi_out_ctls(spec
, &spec
->autocfg
)) < 0 ||
774 (err
= stac92xx_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0 ||
775 (err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
778 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
779 if (spec
->multiout
.max_channels
> 2)
780 spec
->surr_switch
= 1;
782 if (spec
->autocfg
.dig_out_pin
) {
783 spec
->multiout
.dig_out_nid
= 0x08;
784 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_out_pin
, AC_PINCTL_OUT_EN
);
786 if (spec
->autocfg
.dig_in_pin
) {
787 spec
->dig_in_nid
= 0x09;
788 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_in_pin
, AC_PINCTL_IN_EN
);
791 if (spec
->kctl_alloc
)
792 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
794 spec
->input_mux
= &spec
->private_imux
;
799 static int stac9200_parse_auto_config(struct hda_codec
*codec
)
801 struct sigmatel_spec
*spec
= codec
->spec
;
804 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
, NULL
)) < 0)
807 if ((err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
810 if (spec
->autocfg
.dig_out_pin
) {
811 spec
->multiout
.dig_out_nid
= 0x05;
812 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_out_pin
, AC_PINCTL_OUT_EN
);
814 if (spec
->autocfg
.dig_in_pin
) {
815 spec
->dig_in_nid
= 0x04;
816 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_in_pin
, AC_PINCTL_IN_EN
);
819 if (spec
->kctl_alloc
)
820 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
822 spec
->input_mux
= &spec
->private_imux
;
827 static int stac92xx_init(struct hda_codec
*codec
)
829 struct sigmatel_spec
*spec
= codec
->spec
;
831 snd_hda_sequence_write(codec
, spec
->init
);
833 stac92xx_auto_init_multi_out(codec
);
834 stac92xx_auto_init_hp_out(codec
);
839 static void stac92xx_free(struct hda_codec
*codec
)
841 struct sigmatel_spec
*spec
= codec
->spec
;
847 if (spec
->kctl_alloc
) {
848 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
849 kfree(spec
->kctl_alloc
[i
].name
);
850 kfree(spec
->kctl_alloc
);
856 static void stac92xx_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
859 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
860 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
861 snd_hda_codec_write(codec
, nid
, 0,
862 AC_VERB_SET_PIN_WIDGET_CONTROL
,
866 static void stac92xx_reset_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
869 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
870 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
871 snd_hda_codec_write(codec
, nid
, 0,
872 AC_VERB_SET_PIN_WIDGET_CONTROL
,
876 static void stac92xx_unsol_event(struct hda_codec
*codec
, unsigned int res
)
878 struct sigmatel_spec
*spec
= codec
->spec
;
879 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
882 if ((res
>> 26) != STAC_HP_EVENT
)
885 presence
= snd_hda_codec_read(codec
, cfg
->hp_pin
, 0,
886 AC_VERB_GET_PIN_SENSE
, 0x00) >> 31;
889 /* disable lineouts, enable hp */
890 for (i
= 0; i
< cfg
->line_outs
; i
++)
891 stac92xx_reset_pinctl(codec
, cfg
->line_out_pins
[i
],
893 stac92xx_set_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
895 /* enable lineouts, disable hp */
896 for (i
= 0; i
< cfg
->line_outs
; i
++)
897 stac92xx_set_pinctl(codec
, cfg
->line_out_pins
[i
],
899 stac92xx_reset_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
904 static int stac92xx_resume(struct hda_codec
*codec
)
906 struct sigmatel_spec
*spec
= codec
->spec
;
909 stac92xx_init(codec
);
910 for (i
= 0; i
< spec
->num_mixers
; i
++)
911 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
912 if (spec
->multiout
.dig_out_nid
)
913 snd_hda_resume_spdif_out(codec
);
914 if (spec
->dig_in_nid
)
915 snd_hda_resume_spdif_in(codec
);
921 static struct hda_codec_ops stac92xx_patch_ops
= {
922 .build_controls
= stac92xx_build_controls
,
923 .build_pcms
= stac92xx_build_pcms
,
924 .init
= stac92xx_init
,
925 .free
= stac92xx_free
,
926 .unsol_event
= stac92xx_unsol_event
,
928 .resume
= stac92xx_resume
,
932 static int patch_stac9200(struct hda_codec
*codec
)
934 struct sigmatel_spec
*spec
;
937 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
942 spec
->board_config
= snd_hda_check_board_config(codec
, stac9200_cfg_tbl
);
943 if (spec
->board_config
< 0)
944 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
947 spec
->pin_nids
= stac9200_pin_nids
;
948 spec
->pin_configs
= stac9200_brd_tbl
[spec
->board_config
];
949 stac92xx_set_config_regs(codec
);
952 spec
->multiout
.max_channels
= 2;
953 spec
->multiout
.num_dacs
= 1;
954 spec
->multiout
.dac_nids
= stac9200_dac_nids
;
955 spec
->adc_nids
= stac9200_adc_nids
;
956 spec
->mux_nids
= stac9200_mux_nids
;
959 spec
->init
= stac9200_core_init
;
960 spec
->mixer
= stac9200_mixer
;
962 err
= stac9200_parse_auto_config(codec
);
964 stac92xx_free(codec
);
968 codec
->patch_ops
= stac92xx_patch_ops
;
973 static int patch_stac922x(struct hda_codec
*codec
)
975 struct sigmatel_spec
*spec
;
978 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
983 spec
->board_config
= snd_hda_check_board_config(codec
, stac922x_cfg_tbl
);
984 if (spec
->board_config
< 0)
985 snd_printdd(KERN_INFO
"hda_codec: Unknown model for STAC922x, using BIOS defaults\n");
988 spec
->pin_nids
= stac922x_pin_nids
;
989 spec
->pin_configs
= stac922x_brd_tbl
[spec
->board_config
];
990 stac92xx_set_config_regs(codec
);
993 spec
->adc_nids
= stac922x_adc_nids
;
994 spec
->mux_nids
= stac922x_mux_nids
;
997 spec
->init
= stac922x_core_init
;
998 spec
->mixer
= stac922x_mixer
;
1000 spec
->multiout
.dac_nids
= spec
->dac_nids
;
1002 err
= stac922x_parse_auto_config(codec
);
1004 stac92xx_free(codec
);
1008 codec
->patch_ops
= stac92xx_patch_ops
;
1016 struct hda_codec_preset snd_hda_preset_sigmatel
[] = {
1017 { .id
= 0x83847690, .name
= "STAC9200", .patch
= patch_stac9200
},
1018 { .id
= 0x83847882, .name
= "STAC9220 A1", .patch
= patch_stac922x
},
1019 { .id
= 0x83847680, .name
= "STAC9221 A1", .patch
= patch_stac922x
},
1020 { .id
= 0x83847880, .name
= "STAC9220 A2", .patch
= patch_stac922x
},
1021 { .id
= 0x83847681, .name
= "STAC9220D/9223D A2", .patch
= patch_stac922x
},
1022 { .id
= 0x83847682, .name
= "STAC9221 A2", .patch
= patch_stac922x
},
1023 { .id
= 0x83847683, .name
= "STAC9221D A2", .patch
= patch_stac922x
},