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@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"
39 #define NUM_CONTROL_ALLOC 32
40 #define STAC_HP_EVENT 0x37
41 #define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT)
43 struct sigmatel_spec
{
44 snd_kcontrol_new_t
*mixers
[4];
45 unsigned int num_mixers
;
47 unsigned int surr_switch
: 1;
50 struct hda_multi_out multiout
;
51 hda_nid_t dac_nids
[4];
55 unsigned int num_adcs
;
57 unsigned int num_muxes
;
63 unsigned int num_pins
;
64 unsigned int *pin_configs
;
67 /* codec specific stuff */
68 struct hda_verb
*init
;
69 snd_kcontrol_new_t
*mixer
;
72 struct hda_input_mux
*input_mux
;
73 unsigned int cur_mux
[2];
76 unsigned int num_ch_modes
;
77 unsigned int cur_ch_mode
;
79 struct hda_pcm pcm_rec
[2]; /* PCM information */
81 /* dynamic controls and input_mux */
82 struct auto_pin_cfg autocfg
;
83 unsigned int num_kctl_alloc
, num_kctl_used
;
84 snd_kcontrol_new_t
*kctl_alloc
;
85 struct hda_input_mux private_imux
;
88 static hda_nid_t stac9200_adc_nids
[1] = {
92 static hda_nid_t stac9200_mux_nids
[1] = {
96 static hda_nid_t stac9200_dac_nids
[1] = {
100 static hda_nid_t stac922x_adc_nids
[2] = {
104 static hda_nid_t stac922x_mux_nids
[2] = {
109 static hda_nid_t stac9200_pin_nids
[8] = {
110 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
113 static hda_nid_t stac922x_pin_nids
[10] = {
114 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
115 0x0f, 0x10, 0x11, 0x15, 0x1b,
119 static int stac92xx_mux_enum_info(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_info_t
*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(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*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(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*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 int stac922x_channel_modes
[3] = {2, 6, 8};
160 static int stac922x_ch_mode_info(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_info_t
*uinfo
)
162 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
163 struct sigmatel_spec
*spec
= codec
->spec
;
165 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
167 uinfo
->value
.enumerated
.items
= spec
->num_ch_modes
;
168 if (uinfo
->value
.enumerated
.item
>= uinfo
->value
.enumerated
.items
)
169 uinfo
->value
.enumerated
.item
= uinfo
->value
.enumerated
.items
- 1;
170 sprintf(uinfo
->value
.enumerated
.name
, "%dch",
171 stac922x_channel_modes
[uinfo
->value
.enumerated
.item
]);
175 static int stac922x_ch_mode_get(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*ucontrol
)
177 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
178 struct sigmatel_spec
*spec
= codec
->spec
;
180 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_ch_mode
;
184 static int stac922x_ch_mode_put(snd_kcontrol_t
*kcontrol
, snd_ctl_elem_value_t
*ucontrol
)
186 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
187 struct sigmatel_spec
*spec
= codec
->spec
;
189 if (ucontrol
->value
.enumerated
.item
[0] >= spec
->num_ch_modes
)
190 ucontrol
->value
.enumerated
.item
[0] = spec
->num_ch_modes
;
191 if (ucontrol
->value
.enumerated
.item
[0] == spec
->cur_ch_mode
&&
195 spec
->cur_ch_mode
= ucontrol
->value
.enumerated
.item
[0];
196 spec
->multiout
.max_channels
= stac922x_channel_modes
[spec
->cur_ch_mode
];
201 static snd_kcontrol_new_t stac9200_mixer
[] = {
202 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT
),
203 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT
),
205 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
206 .name
= "Input Source",
208 .info
= stac92xx_mux_enum_info
,
209 .get
= stac92xx_mux_enum_get
,
210 .put
= stac92xx_mux_enum_put
,
212 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT
),
213 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT
),
214 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT
),
218 /* This needs to be generated dynamically based on sequence */
219 static snd_kcontrol_new_t stac922x_mixer
[] = {
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", 0x17, 0x0, HDA_INPUT
),
229 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT
),
230 HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT
),
234 static snd_kcontrol_new_t stac922x_ch_mode_mixer
[] = {
236 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
237 .name
= "Channel Mode",
238 .info
= stac922x_ch_mode_info
,
239 .get
= stac922x_ch_mode_get
,
240 .put
= stac922x_ch_mode_put
,
245 static int stac92xx_build_controls(struct hda_codec
*codec
)
247 struct sigmatel_spec
*spec
= codec
->spec
;
251 err
= snd_hda_add_new_ctls(codec
, spec
->mixer
);
255 for (i
= 0; i
< spec
->num_mixers
; i
++) {
256 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
261 if (spec
->surr_switch
) {
262 err
= snd_hda_add_new_ctls(codec
, stac922x_ch_mode_mixer
);
266 if (spec
->multiout
.dig_out_nid
) {
267 err
= snd_hda_create_spdif_out_ctls(codec
, spec
->multiout
.dig_out_nid
);
271 if (spec
->dig_in_nid
) {
272 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
280 static unsigned int stac9200_pin_configs
[8] = {
281 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
282 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
285 static unsigned int stac922x_pin_configs
[10] = {
286 0x01014010, 0x01014011, 0x01014012, 0x0221401f,
287 0x01813122, 0x01014014, 0x01441030, 0x01c41030,
288 0x40000100, 0x40000100,
291 static void stac92xx_set_config_regs(struct hda_codec
*codec
)
294 struct sigmatel_spec
*spec
= codec
->spec
;
295 unsigned int pin_cfg
;
297 for (i
=0; i
< spec
->num_pins
; i
++) {
298 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
299 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
,
300 spec
->pin_configs
[i
] & 0x000000ff);
301 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
302 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1
,
303 (spec
->pin_configs
[i
] & 0x0000ff00) >> 8);
304 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
305 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2
,
306 (spec
->pin_configs
[i
] & 0x00ff0000) >> 16);
307 snd_hda_codec_write(codec
, spec
->pin_nids
[i
], 0,
308 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3
,
309 spec
->pin_configs
[i
] >> 24);
310 pin_cfg
= snd_hda_codec_read(codec
, spec
->pin_nids
[i
], 0,
311 AC_VERB_GET_CONFIG_DEFAULT
,
313 printk("pin nid %2.2x pin config %8.8x\n", spec
->pin_nids
[i
], pin_cfg
);
319 * Analog playback callbacks
321 static int stac92xx_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
322 struct hda_codec
*codec
,
323 snd_pcm_substream_t
*substream
)
325 struct sigmatel_spec
*spec
= codec
->spec
;
326 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
330 * set up the i/o for analog out
331 * when the digital out is available, copy the front out to digital out, too.
333 static int stac92xx_multi_out_analog_prepare(struct hda_codec
*codec
, struct hda_multi_out
*mout
,
334 unsigned int stream_tag
,
336 snd_pcm_substream_t
*substream
)
338 hda_nid_t
*nids
= mout
->dac_nids
;
339 int chs
= substream
->runtime
->channels
;
342 down(&codec
->spdif_mutex
);
343 if (mout
->dig_out_nid
&& mout
->dig_out_used
!= HDA_DIG_EXCLUSIVE
) {
345 snd_hda_is_supported_format(codec
, mout
->dig_out_nid
, format
) &&
346 ! (codec
->spdif_status
& IEC958_AES0_NONAUDIO
)) {
347 mout
->dig_out_used
= HDA_DIG_ANALOG_DUP
;
348 /* setup digital receiver */
349 snd_hda_codec_setup_stream(codec
, mout
->dig_out_nid
,
350 stream_tag
, 0, format
);
352 mout
->dig_out_used
= 0;
353 snd_hda_codec_setup_stream(codec
, mout
->dig_out_nid
, 0, 0, 0);
356 up(&codec
->spdif_mutex
);
359 snd_hda_codec_setup_stream(codec
, nids
[HDA_FRONT
], stream_tag
, 0, format
);
361 /* headphone out will just decode front left/right (stereo) */
362 snd_hda_codec_setup_stream(codec
, mout
->hp_nid
, stream_tag
, 0, format
);
364 if (mout
->max_channels
> 2)
365 for (i
= 1; i
< mout
->num_dacs
; i
++) {
366 if ((mout
->max_channels
== 6) && (i
== 3))
368 if (chs
>= (i
+ 1) * 2) /* independent out */
369 snd_hda_codec_setup_stream(codec
, nids
[i
], stream_tag
, i
* 2,
371 else /* copy front */
372 snd_hda_codec_setup_stream(codec
, nids
[i
], stream_tag
, 0,
379 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
380 struct hda_codec
*codec
,
381 unsigned int stream_tag
,
383 snd_pcm_substream_t
*substream
)
385 struct sigmatel_spec
*spec
= codec
->spec
;
386 return stac92xx_multi_out_analog_prepare(codec
, &spec
->multiout
, stream_tag
,
390 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
391 struct hda_codec
*codec
,
392 snd_pcm_substream_t
*substream
)
394 struct sigmatel_spec
*spec
= codec
->spec
;
395 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
399 * Digital playback callbacks
401 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
402 struct hda_codec
*codec
,
403 snd_pcm_substream_t
*substream
)
405 struct sigmatel_spec
*spec
= codec
->spec
;
406 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
409 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
410 struct hda_codec
*codec
,
411 snd_pcm_substream_t
*substream
)
413 struct sigmatel_spec
*spec
= codec
->spec
;
414 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
419 * Analog capture callbacks
421 static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
422 struct hda_codec
*codec
,
423 unsigned int stream_tag
,
425 snd_pcm_substream_t
*substream
)
427 struct sigmatel_spec
*spec
= codec
->spec
;
429 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
430 stream_tag
, 0, format
);
434 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
435 struct hda_codec
*codec
,
436 snd_pcm_substream_t
*substream
)
438 struct sigmatel_spec
*spec
= codec
->spec
;
440 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
], 0, 0, 0);
444 static struct hda_pcm_stream stac92xx_pcm_digital_playback
= {
448 /* NID is set in stac92xx_build_pcms */
450 .open
= stac92xx_dig_playback_pcm_open
,
451 .close
= stac92xx_dig_playback_pcm_close
455 static struct hda_pcm_stream stac92xx_pcm_digital_capture
= {
459 /* NID is set in stac92xx_build_pcms */
462 static struct hda_pcm_stream stac92xx_pcm_analog_playback
= {
466 .nid
= 0x02, /* NID to query formats and rates */
468 .open
= stac92xx_playback_pcm_open
,
469 .prepare
= stac92xx_playback_pcm_prepare
,
470 .cleanup
= stac92xx_playback_pcm_cleanup
474 static struct hda_pcm_stream stac92xx_pcm_analog_capture
= {
478 .nid
= 0x06, /* NID to query formats and rates */
480 .prepare
= stac92xx_capture_pcm_prepare
,
481 .cleanup
= stac92xx_capture_pcm_cleanup
485 static int stac92xx_build_pcms(struct hda_codec
*codec
)
487 struct sigmatel_spec
*spec
= codec
->spec
;
488 struct hda_pcm
*info
= spec
->pcm_rec
;
491 codec
->pcm_info
= info
;
493 info
->name
= "STAC92xx Analog";
494 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_analog_playback
;
495 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_analog_capture
;
497 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
500 info
->name
= "STAC92xx Digital";
501 if (spec
->multiout
.dig_out_nid
) {
502 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = stac92xx_pcm_digital_playback
;
503 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
505 if (spec
->dig_in_nid
) {
506 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = stac92xx_pcm_digital_capture
;
507 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
516 STAC_CTL_WIDGET_MUTE
,
519 static snd_kcontrol_new_t stac92xx_control_templates
[] = {
520 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
521 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
524 /* add dynamic controls */
525 static int stac92xx_add_control(struct sigmatel_spec
*spec
, int type
, const char *name
, unsigned long val
)
527 snd_kcontrol_new_t
*knew
;
529 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
530 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
532 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
); /* array + terminator */
535 if (spec
->kctl_alloc
) {
536 memcpy(knew
, spec
->kctl_alloc
, sizeof(*knew
) * spec
->num_kctl_alloc
);
537 kfree(spec
->kctl_alloc
);
539 spec
->kctl_alloc
= knew
;
540 spec
->num_kctl_alloc
= num
;
543 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
544 *knew
= stac92xx_control_templates
[type
];
545 knew
->name
= kstrdup(name
, GFP_KERNEL
);
548 knew
->private_value
= val
;
549 spec
->num_kctl_used
++;
553 /* fill in the dac_nids table from the parsed pin configuration */
554 static int stac92xx_auto_fill_dac_nids(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
556 struct sigmatel_spec
*spec
= codec
->spec
;
560 /* check the pins hardwired to audio widget */
561 for (i
= 0; i
< cfg
->line_outs
; i
++) {
562 nid
= cfg
->line_out_pins
[i
];
563 spec
->multiout
.dac_nids
[i
] = snd_hda_codec_read(codec
, nid
, 0,
564 AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
567 spec
->multiout
.num_dacs
= cfg
->line_outs
;
572 /* add playback controls from the parsed DAC table */
573 static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec
*spec
, const struct auto_pin_cfg
*cfg
)
576 static const char *chname
[4] = { "Front", "Surround", NULL
/*CLFE*/, "Side" };
580 for (i
= 0; i
< cfg
->line_outs
; i
++) {
581 if (! spec
->multiout
.dac_nids
[i
])
584 nid
= spec
->multiout
.dac_nids
[i
];
588 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Center Playback Volume",
589 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
591 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "LFE Playback Volume",
592 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
594 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Center Playback Switch",
595 HDA_COMPOSE_AMP_VAL(nid
, 1, 0, HDA_OUTPUT
))) < 0)
597 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "LFE Playback Switch",
598 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
))) < 0)
601 sprintf(name
, "%s Playback Volume", chname
[i
]);
602 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, name
,
603 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
605 sprintf(name
, "%s Playback Switch", chname
[i
]);
606 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, name
,
607 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
615 /* add playback controls for HP output */
616 static int stac92xx_auto_create_hp_ctls(struct hda_codec
*codec
, struct auto_pin_cfg
*cfg
)
618 struct sigmatel_spec
*spec
= codec
->spec
;
619 hda_nid_t pin
= cfg
->hp_pin
;
622 unsigned int wid_caps
;
627 wid_caps
= snd_hda_param_read(codec
, pin
, AC_PAR_AUDIO_WIDGET_CAP
);
628 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
629 /* Enable unsolicited responses on the HP widget */
630 snd_hda_codec_write(codec
, pin
, 0,
631 AC_VERB_SET_UNSOLICITED_ENABLE
,
634 nid
= snd_hda_codec_read(codec
, pin
, 0, AC_VERB_GET_CONNECT_LIST
, 0) & 0xff;
635 for (i
= 0; i
< cfg
->line_outs
; i
++) {
636 if (! spec
->multiout
.dac_nids
[i
])
638 if (spec
->multiout
.dac_nids
[i
] == nid
)
642 spec
->multiout
.hp_nid
= nid
;
644 /* control HP volume/switch on the output mixer amp */
645 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_VOL
, "Headphone Playback Volume",
646 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
648 if ((err
= stac92xx_add_control(spec
, STAC_CTL_WIDGET_MUTE
, "Headphone Playback Switch",
649 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
))) < 0)
655 /* create playback/capture controls for input pins */
656 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec
*codec
, const struct auto_pin_cfg
*cfg
)
658 struct sigmatel_spec
*spec
= codec
->spec
;
659 static char *labels
[AUTO_PIN_LAST
] = {
660 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
662 struct hda_input_mux
*imux
= &spec
->private_imux
;
663 hda_nid_t con_lst
[HDA_MAX_NUM_INPUTS
];
666 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
668 if (cfg
->input_pins
[i
]) {
669 imux
->items
[imux
->num_items
].label
= labels
[i
];
671 for (j
=0; j
<spec
->num_muxes
; j
++) {
672 int num_cons
= snd_hda_get_connections(codec
, spec
->mux_nids
[j
], con_lst
, HDA_MAX_NUM_INPUTS
);
673 for (k
=0; k
<num_cons
; k
++)
674 if (con_lst
[k
] == cfg
->input_pins
[i
]) {
681 imux
->items
[imux
->num_items
].index
= index
;
689 static void stac92xx_auto_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
, int pin_type
)
692 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
695 static void stac92xx_auto_init_multi_out(struct hda_codec
*codec
)
697 struct sigmatel_spec
*spec
= codec
->spec
;
700 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
701 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
702 stac92xx_auto_set_pinctl(codec
, nid
, AC_PINCTL_OUT_EN
);
706 static void stac92xx_auto_init_hp_out(struct hda_codec
*codec
)
708 struct sigmatel_spec
*spec
= codec
->spec
;
711 pin
= spec
->autocfg
.hp_pin
;
712 if (pin
) /* connect to front */
713 stac92xx_auto_set_pinctl(codec
, pin
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
);
716 static int stac922x_parse_auto_config(struct hda_codec
*codec
)
718 struct sigmatel_spec
*spec
= codec
->spec
;
721 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
)) < 0)
723 if ((err
= stac92xx_auto_fill_dac_nids(codec
, &spec
->autocfg
)) < 0)
725 if (! spec
->autocfg
.line_outs
&& ! spec
->autocfg
.hp_pin
)
726 return 0; /* can't find valid pin config */
728 if ((err
= stac92xx_auto_create_multi_out_ctls(spec
, &spec
->autocfg
)) < 0 ||
729 (err
= stac92xx_auto_create_hp_ctls(codec
, &spec
->autocfg
)) < 0 ||
730 (err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
733 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
734 if (spec
->multiout
.max_channels
> 2) {
735 spec
->surr_switch
= 1;
736 spec
->cur_ch_mode
= 1;
737 spec
->num_ch_modes
= 2;
738 if (spec
->multiout
.max_channels
== 8) {
740 spec
->num_ch_modes
++;
744 if (spec
->autocfg
.dig_out_pin
) {
745 spec
->multiout
.dig_out_nid
= 0x08;
746 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_out_pin
, AC_PINCTL_OUT_EN
);
748 if (spec
->autocfg
.dig_in_pin
) {
749 spec
->dig_in_nid
= 0x09;
750 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_in_pin
, AC_PINCTL_IN_EN
);
753 if (spec
->kctl_alloc
)
754 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
756 spec
->input_mux
= &spec
->private_imux
;
761 static int stac9200_parse_auto_config(struct hda_codec
*codec
)
763 struct sigmatel_spec
*spec
= codec
->spec
;
766 if ((err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
)) < 0)
769 if ((err
= stac92xx_auto_create_analog_input_ctls(codec
, &spec
->autocfg
)) < 0)
772 if (spec
->autocfg
.dig_out_pin
) {
773 spec
->multiout
.dig_out_nid
= 0x05;
774 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_out_pin
, AC_PINCTL_OUT_EN
);
776 if (spec
->autocfg
.dig_in_pin
) {
777 spec
->dig_in_nid
= 0x04;
778 stac92xx_auto_set_pinctl(codec
, spec
->autocfg
.dig_in_pin
, AC_PINCTL_IN_EN
);
781 if (spec
->kctl_alloc
)
782 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
784 spec
->input_mux
= &spec
->private_imux
;
789 static int stac92xx_init_pstate(struct hda_codec
*codec
)
791 hda_nid_t nid
, nid_start
;
794 snd_hda_codec_write(codec
, 0x01, 0, AC_VERB_SET_POWER_STATE
, 0x00);
796 nodes
= snd_hda_get_sub_nodes(codec
, codec
->afg
, &nid_start
);
797 for (nid
= nid_start
; nid
< nodes
+ nid_start
; nid
++) {
798 unsigned int wid_caps
= snd_hda_param_read(codec
, nid
,
799 AC_PAR_AUDIO_WIDGET_CAP
);
800 if (wid_caps
& AC_WCAP_POWER
)
801 snd_hda_codec_write(codec
, nid
, 0,
802 AC_VERB_SET_POWER_STATE
, 0x00);
810 static int stac92xx_init(struct hda_codec
*codec
)
812 struct sigmatel_spec
*spec
= codec
->spec
;
814 stac92xx_init_pstate(codec
);
816 snd_hda_sequence_write(codec
, spec
->init
);
818 stac92xx_auto_init_multi_out(codec
);
819 stac92xx_auto_init_hp_out(codec
);
824 static void stac92xx_free(struct hda_codec
*codec
)
826 struct sigmatel_spec
*spec
= codec
->spec
;
832 if (spec
->kctl_alloc
) {
833 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
834 kfree(spec
->kctl_alloc
[i
].name
);
835 kfree(spec
->kctl_alloc
);
841 static void stac92xx_set_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
844 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
845 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
846 snd_hda_codec_write(codec
, nid
, 0,
847 AC_VERB_SET_PIN_WIDGET_CONTROL
,
851 static void stac92xx_reset_pinctl(struct hda_codec
*codec
, hda_nid_t nid
,
854 unsigned int pin_ctl
= snd_hda_codec_read(codec
, nid
,
855 0, AC_VERB_GET_PIN_WIDGET_CONTROL
, 0x00);
856 snd_hda_codec_write(codec
, nid
, 0,
857 AC_VERB_SET_PIN_WIDGET_CONTROL
,
861 static void stac92xx_unsol_event(struct hda_codec
*codec
, unsigned int res
)
863 struct sigmatel_spec
*spec
= codec
->spec
;
864 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
867 if ((res
>> 26) != STAC_HP_EVENT
)
870 presence
= snd_hda_codec_read(codec
, cfg
->hp_pin
, 0,
871 AC_VERB_GET_PIN_SENSE
, 0x00) >> 31;
874 /* disable lineouts, enable hp */
875 for (i
= 0; i
< cfg
->line_outs
; i
++)
876 stac92xx_reset_pinctl(codec
, cfg
->line_out_pins
[i
],
878 stac92xx_set_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
880 /* enable lineouts, disable hp */
881 for (i
= 0; i
< cfg
->line_outs
; i
++)
882 stac92xx_set_pinctl(codec
, cfg
->line_out_pins
[i
],
884 stac92xx_reset_pinctl(codec
, cfg
->hp_pin
, AC_PINCTL_OUT_EN
);
889 static int stac92xx_resume(struct hda_codec
*codec
)
891 struct sigmatel_spec
*spec
= codec
->spec
;
894 stac92xx_init(codec
);
895 for (i
= 0; i
< spec
->num_mixers
; i
++)
896 snd_hda_resume_ctls(codec
, spec
->mixers
[i
]);
897 if (spec
->multiout
.dig_out_nid
)
898 snd_hda_resume_spdif_out(codec
);
899 if (spec
->dig_in_nid
)
900 snd_hda_resume_spdif_in(codec
);
906 static struct hda_codec_ops stac92xx_patch_ops
= {
907 .build_controls
= stac92xx_build_controls
,
908 .build_pcms
= stac92xx_build_pcms
,
909 .init
= stac92xx_init
,
910 .free
= stac92xx_free
,
911 .unsol_event
= stac92xx_unsol_event
,
913 .resume
= stac92xx_resume
,
917 static int patch_stac9200(struct hda_codec
*codec
)
919 struct sigmatel_spec
*spec
;
922 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
929 spec
->pin_nids
= stac9200_pin_nids
;
931 spec
->pin_configs
= stac9200_pin_configs
;
932 stac92xx_set_config_regs(codec
);
934 spec
->multiout
.max_channels
= 2;
935 spec
->multiout
.num_dacs
= 1;
936 spec
->multiout
.dac_nids
= stac9200_dac_nids
;
937 spec
->adc_nids
= stac9200_adc_nids
;
938 spec
->mux_nids
= stac9200_mux_nids
;
941 spec
->init
= stac9200_core_init
;
942 spec
->mixer
= stac9200_mixer
;
944 err
= stac9200_parse_auto_config(codec
);
946 stac92xx_free(codec
);
950 codec
->patch_ops
= stac92xx_patch_ops
;
955 static int patch_stac922x(struct hda_codec
*codec
)
957 struct sigmatel_spec
*spec
;
960 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
968 spec
->pin_nids
= stac922x_pin_nids
;
969 spec
->pin_configs
= stac922x_pin_configs
;
970 stac92xx_set_config_regs(codec
);
972 spec
->adc_nids
= stac922x_adc_nids
;
973 spec
->mux_nids
= stac922x_mux_nids
;
976 spec
->init
= stac922x_core_init
;
977 spec
->mixer
= stac922x_mixer
;
979 spec
->multiout
.dac_nids
= spec
->dac_nids
;
981 err
= stac922x_parse_auto_config(codec
);
983 stac92xx_free(codec
);
987 codec
->patch_ops
= stac92xx_patch_ops
;
995 struct hda_codec_preset snd_hda_preset_sigmatel
[] = {
996 { .id
= 0x83847690, .name
= "STAC9200", .patch
= patch_stac9200
},
997 { .id
= 0x83847882, .name
= "STAC9220 A1", .patch
= patch_stac922x
},
998 { .id
= 0x83847680, .name
= "STAC9221 A1", .patch
= patch_stac922x
},
999 { .id
= 0x83847880, .name
= "STAC9220 A2", .patch
= patch_stac922x
},
1000 { .id
= 0x83847681, .name
= "STAC9220D/9223D A2", .patch
= patch_stac922x
},
1001 { .id
= 0x83847682, .name
= "STAC9221 A2", .patch
= patch_stac922x
},
1002 { .id
= 0x83847683, .name
= "STAC9221D A2", .patch
= patch_stac922x
},