aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorMatthew Ranostay <mranostay@embeddedalley.com>2007-12-13 11:47:21 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:34 -0500
commite1f0d6690817d1296161094106b23a0be9ee6ca0 (patch)
tree21841d8e2b4f817da3b8c200b6681aa7a52b2057 /sound/pci
parenta8848bd6476102ff1d3bbe56662a18d6ada8674f (diff)
[ALSA] hda: Added STAC92HD73 support
Added support for new STAC92HD73 family of codecs. Additionally added features for multiple analog loopbacks, and multiple dmux mixers. Regression testing for the analog loopback changes for STAC9205 and STAC9274D completed with any issues, as well for the dmux changes. Signed-off-by: Matthew Ranostay <mranostay@embeddedalley.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_sigmatel.c407
1 files changed, 387 insertions, 20 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index d2996ad8a49a..0e6af531d365 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -62,6 +62,11 @@ enum {
62}; 62};
63 63
64enum { 64enum {
65 STAC_92HD73XX_REF,
66 STAC_92HD73XX_MODELS
67};
68
69enum {
65 STAC_92HD71BXX_REF, 70 STAC_92HD71BXX_REF,
66 STAC_92HD71BXX_MODELS 71 STAC_92HD71BXX_MODELS
67}; 72};
@@ -118,6 +123,8 @@ struct sigmatel_spec {
118 unsigned int gpio_mute: 1; 123 unsigned int gpio_mute: 1;
119 124
120 unsigned int gpio_mask, gpio_data; 125 unsigned int gpio_mask, gpio_data;
126 unsigned char aloopback_mask;
127 unsigned char aloopback_shift;
121 128
122 /* playback */ 129 /* playback */
123 struct hda_multi_out multiout; 130 struct hda_multi_out multiout;
@@ -130,7 +137,7 @@ struct sigmatel_spec {
130 unsigned int num_muxes; 137 unsigned int num_muxes;
131 hda_nid_t *dmic_nids; 138 hda_nid_t *dmic_nids;
132 unsigned int num_dmics; 139 unsigned int num_dmics;
133 hda_nid_t dmux_nid; 140 hda_nid_t *dmux_nids;
134 hda_nid_t dig_in_nid; 141 hda_nid_t dig_in_nid;
135 142
136 /* pin widgets */ 143 /* pin widgets */
@@ -145,7 +152,7 @@ struct sigmatel_spec {
145 152
146 /* capture source */ 153 /* capture source */
147 struct hda_input_mux *dinput_mux; 154 struct hda_input_mux *dinput_mux;
148 unsigned int cur_dmux; 155 unsigned int cur_dmux[2];
149 struct hda_input_mux *input_mux; 156 struct hda_input_mux *input_mux;
150 unsigned int cur_mux[3]; 157 unsigned int cur_mux[3];
151 158
@@ -176,6 +183,28 @@ static hda_nid_t stac9200_dac_nids[1] = {
176 0x02, 183 0x02,
177}; 184};
178 185
186static hda_nid_t stac92hd73xx_adc_nids[2] = {
187 0x1a, 0x1b
188};
189
190#define STAC92HD73XX_NUM_DMICS 2
191static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
192 0x13, 0x14, 0
193};
194
195#define STAC92HD73_DAC_COUNT 5
196static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
197 0x15, 0x16, 0x17, 0x18, 0x19,
198};
199
200static hda_nid_t stac92hd73xx_mux_nids[4] = {
201 0x28, 0x29, 0x2a, 0x2b,
202};
203
204static hda_nid_t stac92hd73xx_dmux_nids[2] = {
205 0x20, 0x21,
206};
207
179static hda_nid_t stac92hd71bxx_adc_nids[2] = { 208static hda_nid_t stac92hd71bxx_adc_nids[2] = {
180 0x12, 0x13, 209 0x12, 0x13,
181}; 210};
@@ -184,6 +213,10 @@ static hda_nid_t stac92hd71bxx_mux_nids[2] = {
184 0x1a, 0x1b 213 0x1a, 0x1b
185}; 214};
186 215
216static hda_nid_t stac92hd71bxx_dmux_nids[1] = {
217 0x1c,
218};
219
187static hda_nid_t stac92hd71bxx_dac_nids[2] = { 220static hda_nid_t stac92hd71bxx_dac_nids[2] = {
188 0x10, /*0x11, */ 221 0x10, /*0x11, */
189}; 222};
@@ -226,6 +259,10 @@ static hda_nid_t stac927x_mux_nids[3] = {
226 0x15, 0x16, 0x17 259 0x15, 0x16, 0x17
227}; 260};
228 261
262static hda_nid_t stac927x_dmux_nids[1] = {
263 0x1b,
264};
265
229#define STAC927X_NUM_DMICS 2 266#define STAC927X_NUM_DMICS 2
230static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 267static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
231 0x13, 0x14, 0 268 0x13, 0x14, 0
@@ -239,6 +276,10 @@ static hda_nid_t stac9205_mux_nids[2] = {
239 0x19, 0x1a 276 0x19, 0x1a
240}; 277};
241 278
279static hda_nid_t stac9205_dmux_nids[1] = {
280 0x1d,
281};
282
242#define STAC9205_NUM_DMICS 2 283#define STAC9205_NUM_DMICS 2
243static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 284static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
244 0x17, 0x18, 0 285 0x17, 0x18, 0
@@ -259,6 +300,12 @@ static hda_nid_t stac922x_pin_nids[10] = {
259 0x0f, 0x10, 0x11, 0x15, 0x1b, 300 0x0f, 0x10, 0x11, 0x15, 0x1b,
260}; 301};
261 302
303static hda_nid_t stac92hd73xx_pin_nids[12] = {
304 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
305 0x0f, 0x10, 0x11, 0x12, 0x13,
306 0x14, 0x22
307};
308
262static hda_nid_t stac92hd71bxx_pin_nids[10] = { 309static hda_nid_t stac92hd71bxx_pin_nids[10] = {
263 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 310 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
264 0x0f, 0x14, 0x18, 0x19, 0x1e, 311 0x0f, 0x14, 0x18, 0x19, 0x1e,
@@ -289,8 +336,9 @@ static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
289{ 336{
290 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 337 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
291 struct sigmatel_spec *spec = codec->spec; 338 struct sigmatel_spec *spec = codec->spec;
339 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
292 340
293 ucontrol->value.enumerated.item[0] = spec->cur_dmux; 341 ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
294 return 0; 342 return 0;
295} 343}
296 344
@@ -299,9 +347,10 @@ static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
299{ 347{
300 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 348 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
301 struct sigmatel_spec *spec = codec->spec; 349 struct sigmatel_spec *spec = codec->spec;
350 unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
302 351
303 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol, 352 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
304 spec->dmux_nid, &spec->cur_dmux); 353 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
305} 354}
306 355
307static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 356static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
@@ -337,9 +386,11 @@ static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol) 386 struct snd_ctl_elem_value *ucontrol)
338{ 387{
339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 388 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
389 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
340 struct sigmatel_spec *spec = codec->spec; 390 struct sigmatel_spec *spec = codec->spec;
341 391
342 ucontrol->value.integer.value[0] = spec->aloopback; 392 ucontrol->value.integer.value[0] = !!(spec->aloopback &
393 (spec->aloopback_mask << idx));
343 return 0; 394 return 0;
344} 395}
345 396
@@ -348,24 +399,33 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
348{ 399{
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 struct sigmatel_spec *spec = codec->spec; 401 struct sigmatel_spec *spec = codec->spec;
402 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
351 unsigned int dac_mode; 403 unsigned int dac_mode;
352 unsigned int val; 404 unsigned int val, idx_val;
353 405
354 val = !!ucontrol->value.integer.value[0]; 406 idx_val = spec->aloopback_mask << idx;
407 if (ucontrol->value.integer.value[0])
408 val = spec->aloopback | idx_val;
409 else
410 val = spec->aloopback & ~idx_val;
355 if (spec->aloopback == val) 411 if (spec->aloopback == val)
356 return 0; 412 return 0;
357 413
358 spec->aloopback = val; 414 spec->aloopback = val;
359 415
416 /* Only return the bits defined by the shift value of the
417 * first two bytes of the mask
418 */
360 dac_mode = snd_hda_codec_read(codec, codec->afg, 0, 419 dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
361 kcontrol->private_value & 0xFFFF, 0x0); 420 kcontrol->private_value & 0xFFFF, 0x0);
421 dac_mode >>= spec->aloopback_shift;
362 422
363 if (spec->aloopback) { 423 if (spec->aloopback & idx_val) {
364 snd_hda_power_up(codec); 424 snd_hda_power_up(codec);
365 dac_mode |= 0x40; 425 dac_mode |= idx_val;
366 } else { 426 } else {
367 snd_hda_power_down(codec); 427 snd_hda_power_down(codec);
368 dac_mode &= ~0x40; 428 dac_mode &= ~idx_val;
369 } 429 }
370 430
371 snd_hda_codec_write_cache(codec, codec->afg, 0, 431 snd_hda_codec_write_cache(codec, codec->afg, 0,
@@ -387,6 +447,86 @@ static struct hda_verb stac9200_eapd_init[] = {
387 {} 447 {}
388}; 448};
389 449
450static struct hda_verb stac92hd73xx_6ch_core_init[] = {
451 /* set master volume and direct control */
452 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
453 /* setup audio connections */
454 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
455 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
456 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
457 /* setup adcs to point to mixer */
458 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
459 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
460 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Front Mic */
461 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Mic */
462 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Line In */
463 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
464 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
465 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
466 /* setup import muxs */
467 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
468 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
469 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
470 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
471 {}
472};
473
474static struct hda_verb stac92hd73xx_8ch_core_init[] = {
475 /* set master volume and direct control */
476 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
477 /* setup audio connections */
478 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
479 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
480 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
481 /* connect hp ports to dac3 */
482 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
483 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
484 /* setup adcs to point to mixer */
485 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
486 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
487 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Front Mic */
488 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Mic */
489 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Line In */
490 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
491 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
492 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
493 /* setup import muxs */
494 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
495 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
496 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
497 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
498 {}
499};
500
501static struct hda_verb stac92hd73xx_10ch_core_init[] = {
502 /* set master volume and direct control */
503 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
504 /* setup audio connections */
505 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
506 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
507 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
508 /* dac3 is connected to import3 mux */
509 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
510 /* connect hp ports to dac4 */
511 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
512 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
513 /* setup adcs to point to mixer */
514 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
515 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
516 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Front Mic */
517 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Mic */
518 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Line In */
519 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
520 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
521 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
522 /* setup import muxs */
523 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
524 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
525 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
526 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
527 {}
528};
529
390static struct hda_verb stac92hd71bxx_core_init[] = { 530static struct hda_verb stac92hd71bxx_core_init[] = {
391 /* set master volume and direct control */ 531 /* set master volume and direct control */
392 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 532 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -460,11 +600,11 @@ static struct hda_verb stac9205_core_init[] = {
460 .put = stac92xx_mux_enum_put, \ 600 .put = stac92xx_mux_enum_put, \
461 } 601 }
462 602
463#define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \ 603#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
464 { \ 604 { \
465 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
466 .name = "Analog Loopback", \ 606 .name = "Analog Loopback", \
467 .count = 1, \ 607 .count = cnt, \
468 .info = stac92xx_aloopback_info, \ 608 .info = stac92xx_aloopback_info, \
469 .get = stac92xx_aloopback_get, \ 609 .get = stac92xx_aloopback_get, \
470 .put = stac92xx_aloopback_put, \ 610 .put = stac92xx_aloopback_put, \
@@ -481,6 +621,99 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
481 { } /* end */ 621 { } /* end */
482}; 622};
483 623
624static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
625 STAC_DIGITAL_INPUT_SOURCE(2),
626 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
627
628 /* hardware gain controls */
629 HDA_CODEC_VOLUME_IDX("Digital Mic Volume", 0x0, 0x13, 0x0, HDA_OUTPUT),
630 HDA_CODEC_VOLUME_IDX("Digital Mic Volume", 0x1, 0x14, 0x0, HDA_OUTPUT),
631
632 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
633 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
634
635 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
636 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
637
638 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
639 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
640
641 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
642 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
643
644 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
645 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
646
647 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
648 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
649
650 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
651 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
652 { } /* end */
653};
654
655static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
656 STAC_DIGITAL_INPUT_SOURCE(2),
657 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
658
659 /* hardware gain controls */
660 HDA_CODEC_VOLUME_IDX("Digital Mic Volume", 0x0, 0x13, 0x0, HDA_OUTPUT),
661 HDA_CODEC_VOLUME_IDX("Digital Mic Volume", 0x1, 0x14, 0x0, HDA_OUTPUT),
662
663 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
664 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
665
666 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
667 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
668
669 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
670 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
671
672 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
673 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
674
675 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
676 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
677
678 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
679 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
680
681 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
682 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
683 { } /* end */
684};
685
686static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
687 STAC_DIGITAL_INPUT_SOURCE(2),
688 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
689
690 /* hardware gain controls */
691 HDA_CODEC_VOLUME_IDX("Digital Mic Volume", 0x0, 0x13, 0x0, HDA_OUTPUT),
692 HDA_CODEC_VOLUME_IDX("Digital Mic Volume", 0x1, 0x14, 0x0, HDA_OUTPUT),
693
694 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
695 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
696
697 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
698 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
699
700 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
701 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
702
703 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
704 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
705
706 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
707 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
708
709 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
710 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
711
712 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
713 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
714 { } /* end */
715};
716
484static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { 717static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
485 STAC_DIGITAL_INPUT_SOURCE(1), 718 STAC_DIGITAL_INPUT_SOURCE(1),
486 STAC_INPUT_SOURCE(2), 719 STAC_INPUT_SOURCE(2),
@@ -513,7 +746,7 @@ static struct snd_kcontrol_new stac925x_mixer[] = {
513static struct snd_kcontrol_new stac9205_mixer[] = { 746static struct snd_kcontrol_new stac9205_mixer[] = {
514 STAC_DIGITAL_INPUT_SOURCE(1), 747 STAC_DIGITAL_INPUT_SOURCE(1),
515 STAC_INPUT_SOURCE(2), 748 STAC_INPUT_SOURCE(2),
516 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0), 749 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
517 750
518 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), 751 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
519 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), 752 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
@@ -543,7 +776,7 @@ static struct snd_kcontrol_new stac922x_mixer[] = {
543static struct snd_kcontrol_new stac927x_mixer[] = { 776static struct snd_kcontrol_new stac927x_mixer[] = {
544 STAC_DIGITAL_INPUT_SOURCE(1), 777 STAC_DIGITAL_INPUT_SOURCE(1),
545 STAC_INPUT_SOURCE(3), 778 STAC_INPUT_SOURCE(3),
546 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), 779 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
547 780
548 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), 781 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
549 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), 782 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
@@ -854,6 +1087,27 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = {
854 {} /* terminator */ 1087 {} /* terminator */
855}; 1088};
856 1089
1090static unsigned int ref92hd73xx_pin_configs[12] = {
1091 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1092 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1093 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1094};
1095
1096static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1097 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1098};
1099
1100static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1101 [STAC_92HD73XX_REF] = "ref",
1102};
1103
1104static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1105 /* SigmaTel reference board */
1106 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1107 "DFI LanParty", STAC_92HD73XX_REF),
1108 {} /* terminator */
1109};
1110
857static unsigned int ref92hd71bxx_pin_configs[10] = { 1111static unsigned int ref92hd71bxx_pin_configs[10] = {
858 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 1112 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
859 0x0181302e, 0x01114010, 0x01a19020, 0x90a000f0, 1113 0x0181302e, 0x01114010, 0x01a19020, 0x90a000f0,
@@ -2030,7 +2284,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
2030 continue; 2284 continue;
2031 2285
2032 num_cons = snd_hda_get_connections(codec, 2286 num_cons = snd_hda_get_connections(codec,
2033 spec->dmux_nid, 2287 spec->dmux_nids[0],
2034 con_lst, 2288 con_lst,
2035 HDA_MAX_NUM_INPUTS); 2289 HDA_MAX_NUM_INPUTS);
2036 for (j = 0; j < num_cons; j++) 2290 for (j = 0; j < num_cons; j++)
@@ -2211,7 +2465,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2211 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2465 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2212 2466
2213 spec->input_mux = &spec->private_imux; 2467 spec->input_mux = &spec->private_imux;
2214 spec->dinput_mux = &spec->private_dimux; 2468 if (!spec->dinput_mux)
2469 spec->dinput_mux = &spec->private_dimux;
2215 2470
2216 return 1; 2471 return 1;
2217} 2472}
@@ -2696,6 +2951,112 @@ static int patch_stac925x(struct hda_codec *codec)
2696 return 0; 2951 return 0;
2697} 2952}
2698 2953
2954static struct hda_input_mux stac92hd73xx_dmux = {
2955 .num_items = 4,
2956 .items = {
2957 { "Analog Inputs", 0x0b },
2958 { "CD", 0x08 },
2959 { "Digital Mic 1", 0x09 },
2960 { "Digital Mic 2", 0x0a },
2961 }
2962};
2963
2964static int patch_stac92hd73xx(struct hda_codec *codec)
2965{
2966 struct sigmatel_spec *spec;
2967 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
2968 int err = 0;
2969
2970 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2971 if (spec == NULL)
2972 return -ENOMEM;
2973
2974 codec->spec = spec;
2975 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
2976 spec->pin_nids = stac92hd73xx_pin_nids;
2977 spec->board_config = snd_hda_check_board_config(codec,
2978 STAC_92HD73XX_MODELS,
2979 stac92hd73xx_models,
2980 stac92hd73xx_cfg_tbl);
2981again:
2982 if (spec->board_config < 0) {
2983 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
2984 " STAC92HD73XX, using BIOS defaults\n");
2985 err = stac92xx_save_bios_config_regs(codec);
2986 if (err < 0) {
2987 stac92xx_free(codec);
2988 return err;
2989 }
2990 spec->pin_configs = spec->bios_pin_configs;
2991 } else {
2992 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
2993 stac92xx_set_config_regs(codec);
2994 }
2995
2996 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a,
2997 conn, STAC92HD73_DAC_COUNT + 2) - 1;
2998
2999 if (spec->multiout.num_dacs < 0) {
3000 printk(KERN_WARNING "hda_codec: Could not determine "
3001 "number of channels defaulting to DAC count\n");
3002 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT;
3003 }
3004
3005 switch (spec->multiout.num_dacs) {
3006 case 0x3: /* 6 Channel */
3007 spec->mixer = stac92hd73xx_6ch_mixer;
3008 spec->init = stac92hd73xx_6ch_core_init;
3009 break;
3010 case 0x4: /* 8 Channel */
3011 spec->multiout.hp_nid = 0x18;
3012 spec->mixer = stac92hd73xx_8ch_mixer;
3013 spec->init = stac92hd73xx_8ch_core_init;
3014 break;
3015 case 0x5: /* 10 Channel */
3016 spec->multiout.hp_nid = 0x19;
3017 spec->mixer = stac92hd73xx_10ch_mixer;
3018 spec->init = stac92hd73xx_10ch_core_init;
3019 };
3020
3021 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
3022 spec->aloopback_mask = 0x01;
3023 spec->aloopback_shift = 8;
3024
3025 spec->mux_nids = stac92hd73xx_mux_nids;
3026 spec->adc_nids = stac92hd73xx_adc_nids;
3027 spec->dmic_nids = stac92hd73xx_dmic_nids;
3028 spec->dmux_nids = stac92hd73xx_dmux_nids;
3029
3030 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
3031 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
3032 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
3033 spec->dinput_mux = &stac92hd73xx_dmux;
3034 /* GPIO0 High = Enable EAPD */
3035 spec->gpio_mask = spec->gpio_data = 0x000001;
3036 stac92xx_enable_gpio_mask(codec);
3037
3038 err = stac92xx_parse_auto_config(codec, 0x22, 0x24);
3039
3040 if (!err) {
3041 if (spec->board_config < 0) {
3042 printk(KERN_WARNING "hda_codec: No auto-config is "
3043 "available, default to model=ref\n");
3044 spec->board_config = STAC_92HD73XX_REF;
3045 goto again;
3046 }
3047 err = -EINVAL;
3048 }
3049
3050 if (err < 0) {
3051 stac92xx_free(codec);
3052 return err;
3053 }
3054
3055 codec->patch_ops = stac92xx_patch_ops;
3056
3057 return 0;
3058}
3059
2699static int patch_stac92hd71bxx(struct hda_codec *codec) 3060static int patch_stac92hd71bxx(struct hda_codec *codec)
2700{ 3061{
2701 struct sigmatel_spec *spec; 3062 struct sigmatel_spec *spec;
@@ -2736,7 +3097,7 @@ again:
2736 spec->mux_nids = stac92hd71bxx_mux_nids; 3097 spec->mux_nids = stac92hd71bxx_mux_nids;
2737 spec->adc_nids = stac92hd71bxx_adc_nids; 3098 spec->adc_nids = stac92hd71bxx_adc_nids;
2738 spec->dmic_nids = stac92hd71bxx_dmic_nids; 3099 spec->dmic_nids = stac92hd71bxx_dmic_nids;
2739 spec->dmux_nid = 0x1c; 3100 spec->dmux_nids = stac92hd71bxx_dmux_nids;
2740 3101
2741 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); 3102 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
2742 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); 3103 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
@@ -2931,7 +3292,7 @@ static int patch_stac927x(struct hda_codec *codec)
2931 case 0x10280209: 3292 case 0x10280209:
2932 spec->dmic_nids = stac927x_dmic_nids; 3293 spec->dmic_nids = stac927x_dmic_nids;
2933 spec->num_dmics = STAC927X_NUM_DMICS; 3294 spec->num_dmics = STAC927X_NUM_DMICS;
2934 spec->dmux_nid = 0x1b; 3295 spec->dmux_nids = stac927x_dmux_nids;
2935 3296
2936 /* Enable DMIC0 */ 3297 /* Enable DMIC0 */
2937 stac92xx_set_config_reg(codec, 0x13, 0x90a60040); 3298 stac92xx_set_config_reg(codec, 0x13, 0x90a60040);
@@ -2947,6 +3308,8 @@ static int patch_stac927x(struct hda_codec *codec)
2947 } 3308 }
2948 3309
2949 spec->multiout.dac_nids = spec->dac_nids; 3310 spec->multiout.dac_nids = spec->dac_nids;
3311 spec->aloopback_mask = 0x40;
3312 spec->aloopback_shift = 0;
2950 stac92xx_enable_gpio_mask(codec); 3313 stac92xx_enable_gpio_mask(codec);
2951 3314
2952 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); 3315 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
@@ -3004,11 +3367,13 @@ static int patch_stac9205(struct hda_codec *codec)
3004 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); 3367 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
3005 spec->dmic_nids = stac9205_dmic_nids; 3368 spec->dmic_nids = stac9205_dmic_nids;
3006 spec->num_dmics = STAC9205_NUM_DMICS; 3369 spec->num_dmics = STAC9205_NUM_DMICS;
3007 spec->dmux_nid = 0x1d; 3370 spec->dmux_nids = stac9205_dmux_nids;
3008 3371
3009 spec->init = stac9205_core_init; 3372 spec->init = stac9205_core_init;
3010 spec->mixer = stac9205_mixer; 3373 spec->mixer = stac9205_mixer;
3011 3374
3375 spec->aloopback_mask = 0x40;
3376 spec->aloopback_shift = 0;
3012 spec->multiout.dac_nids = spec->dac_nids; 3377 spec->multiout.dac_nids = spec->dac_nids;
3013 3378
3014 switch (spec->board_config){ 3379 switch (spec->board_config){
@@ -3337,6 +3702,8 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
3337 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, 3702 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
3338 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, 3703 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
3339 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 3704 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
3705 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
3706 { .id = 0x111d7675, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
3340 { .id = 0x111d76b0, .name = "92HD71BXX", .patch = patch_stac92hd71bxx }, 3707 { .id = 0x111d76b0, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
3341 {} /* terminator */ 3708 {} /* terminator */
3342}; 3709};