aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-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};