diff options
-rw-r--r-- | sound/pci/hda/patch_via.c | 304 |
1 files changed, 281 insertions, 23 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 4cad16c532c4..4e4d2c5b261f 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -33,6 +33,7 @@ | |||
33 | /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ | 33 | /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ |
34 | /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ | 34 | /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ |
35 | /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ | 35 | /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ |
36 | /* 2008-04-09 Lydia Wang Add Independent HP feature */ | ||
36 | /* */ | 37 | /* */ |
37 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 38 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
38 | 39 | ||
@@ -41,6 +42,7 @@ | |||
41 | #include <linux/delay.h> | 42 | #include <linux/delay.h> |
42 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
43 | #include <sound/core.h> | 44 | #include <sound/core.h> |
45 | #include <sound/asoundef.h> | ||
44 | #include "hda_codec.h" | 46 | #include "hda_codec.h" |
45 | #include "hda_local.h" | 47 | #include "hda_local.h" |
46 | #include "hda_patch.h" | 48 | #include "hda_patch.h" |
@@ -140,9 +142,13 @@ struct via_spec { | |||
140 | struct auto_pin_cfg autocfg; | 142 | struct auto_pin_cfg autocfg; |
141 | unsigned int num_kctl_alloc, num_kctl_used; | 143 | unsigned int num_kctl_alloc, num_kctl_used; |
142 | struct snd_kcontrol_new *kctl_alloc; | 144 | struct snd_kcontrol_new *kctl_alloc; |
143 | struct hda_input_mux private_imux; | 145 | struct hda_input_mux private_imux[2]; |
144 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 146 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
145 | 147 | ||
148 | /* HP mode source */ | ||
149 | const struct hda_input_mux *hp_mux; | ||
150 | unsigned int hp_independent_mode; | ||
151 | |||
146 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 152 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
147 | struct hda_loopback_check loopback; | 153 | struct hda_loopback_check loopback; |
148 | #endif | 154 | #endif |
@@ -326,6 +332,92 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
326 | &spec->cur_mux[adc_idx]); | 332 | &spec->cur_mux[adc_idx]); |
327 | } | 333 | } |
328 | 334 | ||
335 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, | ||
336 | struct snd_ctl_elem_info *uinfo) | ||
337 | { | ||
338 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
339 | struct via_spec *spec = codec->spec; | ||
340 | return snd_hda_input_mux_info(spec->hp_mux, uinfo); | ||
341 | } | ||
342 | |||
343 | static int via_independent_hp_get(struct snd_kcontrol *kcontrol, | ||
344 | struct snd_ctl_elem_value *ucontrol) | ||
345 | { | ||
346 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
347 | struct via_spec *spec = codec->spec; | ||
348 | hda_nid_t nid = spec->autocfg.hp_pins[0]; | ||
349 | unsigned int pinsel = snd_hda_codec_read(codec, nid, 0, | ||
350 | AC_VERB_GET_CONNECT_SEL, | ||
351 | 0x00); | ||
352 | |||
353 | ucontrol->value.enumerated.item[0] = pinsel; | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | ||
359 | struct snd_ctl_elem_value *ucontrol) | ||
360 | { | ||
361 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
362 | struct via_spec *spec = codec->spec; | ||
363 | hda_nid_t nid = spec->autocfg.hp_pins[0]; | ||
364 | unsigned int pinsel = ucontrol->value.enumerated.item[0]; | ||
365 | unsigned int con_nid = snd_hda_codec_read(codec, nid, 0, | ||
366 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
367 | |||
368 | if (con_nid == spec->multiout.hp_nid) { | ||
369 | if (pinsel == 0) { | ||
370 | if (!spec->hp_independent_mode) { | ||
371 | if (spec->multiout.num_dacs > 1) | ||
372 | spec->multiout.num_dacs -= 1; | ||
373 | spec->hp_independent_mode = 1; | ||
374 | } | ||
375 | } else if (pinsel == 1) { | ||
376 | if (spec->hp_independent_mode) { | ||
377 | if (spec->multiout.num_dacs > 1) | ||
378 | spec->multiout.num_dacs += 1; | ||
379 | spec->hp_independent_mode = 0; | ||
380 | } | ||
381 | } | ||
382 | } else { | ||
383 | if (pinsel == 0) { | ||
384 | if (spec->hp_independent_mode) { | ||
385 | if (spec->multiout.num_dacs > 1) | ||
386 | spec->multiout.num_dacs += 1; | ||
387 | spec->hp_independent_mode = 0; | ||
388 | } | ||
389 | } else if (pinsel == 1) { | ||
390 | if (!spec->hp_independent_mode) { | ||
391 | if (spec->multiout.num_dacs > 1) | ||
392 | spec->multiout.num_dacs -= 1; | ||
393 | spec->hp_independent_mode = 1; | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, | ||
398 | pinsel); | ||
399 | |||
400 | if (spec->multiout.hp_nid && | ||
401 | spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT]) | ||
402 | snd_hda_codec_setup_stream(codec, | ||
403 | spec->multiout.hp_nid, | ||
404 | 0, 0, 0); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static struct snd_kcontrol_new via_hp_mixer[] = { | ||
410 | { | ||
411 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
412 | .name = "Independent HP", | ||
413 | .count = 1, | ||
414 | .info = via_independent_hp_info, | ||
415 | .get = via_independent_hp_get, | ||
416 | .put = via_independent_hp_put, | ||
417 | }, | ||
418 | { } /* end */ | ||
419 | }; | ||
420 | |||
329 | /* capture mixer elements */ | 421 | /* capture mixer elements */ |
330 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { | 422 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { |
331 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), | 423 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), |
@@ -410,6 +502,138 @@ static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
410 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 502 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
411 | } | 503 | } |
412 | 504 | ||
505 | |||
506 | static void playback_multi_pcm_prep_0(struct hda_codec *codec, | ||
507 | unsigned int stream_tag, | ||
508 | unsigned int format, | ||
509 | struct snd_pcm_substream *substream) | ||
510 | { | ||
511 | struct via_spec *spec = codec->spec; | ||
512 | struct hda_multi_out *mout = &spec->multiout; | ||
513 | hda_nid_t *nids = mout->dac_nids; | ||
514 | int chs = substream->runtime->channels; | ||
515 | int i; | ||
516 | |||
517 | mutex_lock(&codec->spdif_mutex); | ||
518 | if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { | ||
519 | if (chs == 2 && | ||
520 | snd_hda_is_supported_format(codec, mout->dig_out_nid, | ||
521 | format) && | ||
522 | !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { | ||
523 | mout->dig_out_used = HDA_DIG_ANALOG_DUP; | ||
524 | /* turn off SPDIF once; otherwise the IEC958 bits won't | ||
525 | * be updated */ | ||
526 | if (codec->spdif_ctls & AC_DIG1_ENABLE) | ||
527 | snd_hda_codec_write(codec, mout->dig_out_nid, 0, | ||
528 | AC_VERB_SET_DIGI_CONVERT_1, | ||
529 | codec->spdif_ctls & | ||
530 | ~AC_DIG1_ENABLE & 0xff); | ||
531 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, | ||
532 | stream_tag, 0, format); | ||
533 | /* turn on again (if needed) */ | ||
534 | if (codec->spdif_ctls & AC_DIG1_ENABLE) | ||
535 | snd_hda_codec_write(codec, mout->dig_out_nid, 0, | ||
536 | AC_VERB_SET_DIGI_CONVERT_1, | ||
537 | codec->spdif_ctls & 0xff); | ||
538 | } else { | ||
539 | mout->dig_out_used = 0; | ||
540 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, | ||
541 | 0, 0, 0); | ||
542 | } | ||
543 | } | ||
544 | mutex_unlock(&codec->spdif_mutex); | ||
545 | |||
546 | /* front */ | ||
547 | snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, | ||
548 | 0, format); | ||
549 | |||
550 | if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && | ||
551 | !spec->hp_independent_mode) | ||
552 | /* headphone out will just decode front left/right (stereo) */ | ||
553 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, | ||
554 | 0, format); | ||
555 | |||
556 | /* extra outputs copied from front */ | ||
557 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) | ||
558 | if (mout->extra_out_nid[i]) | ||
559 | snd_hda_codec_setup_stream(codec, | ||
560 | mout->extra_out_nid[i], | ||
561 | stream_tag, 0, format); | ||
562 | |||
563 | /* surrounds */ | ||
564 | for (i = 1; i < mout->num_dacs; i++) { | ||
565 | if (chs >= (i + 1) * 2) /* independent out */ | ||
566 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, | ||
567 | i * 2, format); | ||
568 | else /* copy front */ | ||
569 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, | ||
570 | 0, format); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
575 | struct hda_codec *codec, | ||
576 | unsigned int stream_tag, | ||
577 | unsigned int format, | ||
578 | struct snd_pcm_substream *substream) | ||
579 | { | ||
580 | struct via_spec *spec = codec->spec; | ||
581 | struct hda_multi_out *mout = &spec->multiout; | ||
582 | hda_nid_t *nids = mout->dac_nids; | ||
583 | |||
584 | if (substream->number == 0) | ||
585 | playback_multi_pcm_prep_0(codec, stream_tag, format, | ||
586 | substream); | ||
587 | else { | ||
588 | if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && | ||
589 | spec->hp_independent_mode) | ||
590 | snd_hda_codec_setup_stream(codec, mout->hp_nid, | ||
591 | stream_tag, 0, format); | ||
592 | } | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
598 | struct hda_codec *codec, | ||
599 | struct snd_pcm_substream *substream) | ||
600 | { | ||
601 | struct via_spec *spec = codec->spec; | ||
602 | struct hda_multi_out *mout = &spec->multiout; | ||
603 | hda_nid_t *nids = mout->dac_nids; | ||
604 | int i; | ||
605 | |||
606 | if (substream->number == 0) { | ||
607 | for (i = 0; i < mout->num_dacs; i++) | ||
608 | snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); | ||
609 | |||
610 | if (mout->hp_nid && !spec->hp_independent_mode) | ||
611 | snd_hda_codec_setup_stream(codec, mout->hp_nid, | ||
612 | 0, 0, 0); | ||
613 | |||
614 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) | ||
615 | if (mout->extra_out_nid[i]) | ||
616 | snd_hda_codec_setup_stream(codec, | ||
617 | mout->extra_out_nid[i], | ||
618 | 0, 0, 0); | ||
619 | mutex_lock(&codec->spdif_mutex); | ||
620 | if (mout->dig_out_nid && | ||
621 | mout->dig_out_used == HDA_DIG_ANALOG_DUP) { | ||
622 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, | ||
623 | 0, 0, 0); | ||
624 | mout->dig_out_used = 0; | ||
625 | } | ||
626 | mutex_unlock(&codec->spdif_mutex); | ||
627 | } else { | ||
628 | if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && | ||
629 | spec->hp_independent_mode) | ||
630 | snd_hda_codec_setup_stream(codec, mout->hp_nid, | ||
631 | 0, 0, 0); | ||
632 | } | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
413 | /* | 637 | /* |
414 | * Digital out | 638 | * Digital out |
415 | */ | 639 | */ |
@@ -466,14 +690,14 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
466 | } | 690 | } |
467 | 691 | ||
468 | static struct hda_pcm_stream vt1708_pcm_analog_playback = { | 692 | static struct hda_pcm_stream vt1708_pcm_analog_playback = { |
469 | .substreams = 1, | 693 | .substreams = 2, |
470 | .channels_min = 2, | 694 | .channels_min = 2, |
471 | .channels_max = 8, | 695 | .channels_max = 8, |
472 | .nid = 0x10, /* NID to query formats and rates */ | 696 | .nid = 0x10, /* NID to query formats and rates */ |
473 | .ops = { | 697 | .ops = { |
474 | .open = via_playback_pcm_open, | 698 | .open = via_playback_pcm_open, |
475 | .prepare = via_playback_pcm_prepare, | 699 | .prepare = via_playback_multi_pcm_prepare, |
476 | .cleanup = via_playback_pcm_cleanup | 700 | .cleanup = via_playback_multi_pcm_cleanup |
477 | }, | 701 | }, |
478 | }; | 702 | }; |
479 | 703 | ||
@@ -865,6 +1089,24 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, | |||
865 | return 0; | 1089 | return 0; |
866 | } | 1090 | } |
867 | 1091 | ||
1092 | static void create_hp_imux(struct via_spec *spec) | ||
1093 | { | ||
1094 | int i; | ||
1095 | struct hda_input_mux *imux = &spec->private_imux[1]; | ||
1096 | static const char *texts[] = { "OFF", "ON", NULL}; | ||
1097 | |||
1098 | /* for hp mode select */ | ||
1099 | i = 0; | ||
1100 | while (texts[i] != NULL) { | ||
1101 | imux->items[imux->num_items].label = texts[i]; | ||
1102 | imux->items[imux->num_items].index = i; | ||
1103 | imux->num_items++; | ||
1104 | i++; | ||
1105 | } | ||
1106 | |||
1107 | spec->hp_mux = &spec->private_imux[1]; | ||
1108 | } | ||
1109 | |||
868 | static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | 1110 | static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) |
869 | { | 1111 | { |
870 | int err; | 1112 | int err; |
@@ -885,6 +1127,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
885 | if (err < 0) | 1127 | if (err < 0) |
886 | return err; | 1128 | return err; |
887 | 1129 | ||
1130 | create_hp_imux(spec); | ||
1131 | |||
888 | return 0; | 1132 | return 0; |
889 | } | 1133 | } |
890 | 1134 | ||
@@ -895,7 +1139,7 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, | |||
895 | static char *labels[] = { | 1139 | static char *labels[] = { |
896 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL | 1140 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL |
897 | }; | 1141 | }; |
898 | struct hda_input_mux *imux = &spec->private_imux; | 1142 | struct hda_input_mux *imux = &spec->private_imux[0]; |
899 | int i, err, idx = 0; | 1143 | int i, err, idx = 0; |
900 | 1144 | ||
901 | /* for internal loopback recording select */ | 1145 | /* for internal loopback recording select */ |
@@ -1006,7 +1250,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
1006 | 1250 | ||
1007 | spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; | 1251 | spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; |
1008 | 1252 | ||
1009 | spec->input_mux = &spec->private_imux; | 1253 | spec->input_mux = &spec->private_imux[0]; |
1254 | |||
1255 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | ||
1010 | 1256 | ||
1011 | return 1; | 1257 | return 1; |
1012 | } | 1258 | } |
@@ -1400,7 +1646,7 @@ static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, | |||
1400 | static char *labels[] = { | 1646 | static char *labels[] = { |
1401 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL | 1647 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL |
1402 | }; | 1648 | }; |
1403 | struct hda_input_mux *imux = &spec->private_imux; | 1649 | struct hda_input_mux *imux = &spec->private_imux[0]; |
1404 | int i, err, idx = 0; | 1650 | int i, err, idx = 0; |
1405 | 1651 | ||
1406 | /* for internal loopback recording select */ | 1652 | /* for internal loopback recording select */ |
@@ -1474,7 +1720,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
1474 | if (spec->kctl_alloc) | 1720 | if (spec->kctl_alloc) |
1475 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 1721 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
1476 | 1722 | ||
1477 | spec->input_mux = &spec->private_imux; | 1723 | spec->input_mux = &spec->private_imux[0]; |
1478 | 1724 | ||
1479 | return 1; | 1725 | return 1; |
1480 | } | 1726 | } |
@@ -1731,26 +1977,26 @@ static struct hda_verb vt1708B_uniwill_init_verbs[] = { | |||
1731 | }; | 1977 | }; |
1732 | 1978 | ||
1733 | static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { | 1979 | static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { |
1734 | .substreams = 1, | 1980 | .substreams = 2, |
1735 | .channels_min = 2, | 1981 | .channels_min = 2, |
1736 | .channels_max = 8, | 1982 | .channels_max = 8, |
1737 | .nid = 0x10, /* NID to query formats and rates */ | 1983 | .nid = 0x10, /* NID to query formats and rates */ |
1738 | .ops = { | 1984 | .ops = { |
1739 | .open = via_playback_pcm_open, | 1985 | .open = via_playback_pcm_open, |
1740 | .prepare = via_playback_pcm_prepare, | 1986 | .prepare = via_playback_multi_pcm_prepare, |
1741 | .cleanup = via_playback_pcm_cleanup | 1987 | .cleanup = via_playback_multi_pcm_cleanup |
1742 | }, | 1988 | }, |
1743 | }; | 1989 | }; |
1744 | 1990 | ||
1745 | static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { | 1991 | static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { |
1746 | .substreams = 1, | 1992 | .substreams = 2, |
1747 | .channels_min = 2, | 1993 | .channels_min = 2, |
1748 | .channels_max = 4, | 1994 | .channels_max = 4, |
1749 | .nid = 0x10, /* NID to query formats and rates */ | 1995 | .nid = 0x10, /* NID to query formats and rates */ |
1750 | .ops = { | 1996 | .ops = { |
1751 | .open = via_playback_pcm_open, | 1997 | .open = via_playback_pcm_open, |
1752 | .prepare = via_playback_pcm_prepare, | 1998 | .prepare = via_playback_multi_pcm_prepare, |
1753 | .cleanup = via_playback_pcm_cleanup | 1999 | .cleanup = via_playback_multi_pcm_cleanup |
1754 | }, | 2000 | }, |
1755 | }; | 2001 | }; |
1756 | 2002 | ||
@@ -1929,6 +2175,8 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
1929 | if (err < 0) | 2175 | if (err < 0) |
1930 | return err; | 2176 | return err; |
1931 | 2177 | ||
2178 | create_hp_imux(spec); | ||
2179 | |||
1932 | return 0; | 2180 | return 0; |
1933 | } | 2181 | } |
1934 | 2182 | ||
@@ -1939,7 +2187,7 @@ static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, | |||
1939 | static char *labels[] = { | 2187 | static char *labels[] = { |
1940 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL | 2188 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL |
1941 | }; | 2189 | }; |
1942 | struct hda_input_mux *imux = &spec->private_imux; | 2190 | struct hda_input_mux *imux = &spec->private_imux[0]; |
1943 | int i, err, idx = 0; | 2191 | int i, err, idx = 0; |
1944 | 2192 | ||
1945 | /* for internal loopback recording select */ | 2193 | /* for internal loopback recording select */ |
@@ -2013,7 +2261,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
2013 | if (spec->kctl_alloc) | 2261 | if (spec->kctl_alloc) |
2014 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 2262 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
2015 | 2263 | ||
2016 | spec->input_mux = &spec->private_imux; | 2264 | spec->input_mux = &spec->private_imux[0]; |
2265 | |||
2266 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | ||
2017 | 2267 | ||
2018 | return 1; | 2268 | return 1; |
2019 | } | 2269 | } |
@@ -2369,6 +2619,8 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
2369 | if (err < 0) | 2619 | if (err < 0) |
2370 | return err; | 2620 | return err; |
2371 | 2621 | ||
2622 | create_hp_imux(spec); | ||
2623 | |||
2372 | return 0; | 2624 | return 0; |
2373 | } | 2625 | } |
2374 | 2626 | ||
@@ -2379,7 +2631,7 @@ static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, | |||
2379 | static char *labels[] = { | 2631 | static char *labels[] = { |
2380 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL | 2632 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL |
2381 | }; | 2633 | }; |
2382 | struct hda_input_mux *imux = &spec->private_imux; | 2634 | struct hda_input_mux *imux = &spec->private_imux[0]; |
2383 | int i, err, idx = 0; | 2635 | int i, err, idx = 0; |
2384 | 2636 | ||
2385 | /* for internal loopback recording select */ | 2637 | /* for internal loopback recording select */ |
@@ -2453,7 +2705,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
2453 | if (spec->kctl_alloc) | 2705 | if (spec->kctl_alloc) |
2454 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 2706 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
2455 | 2707 | ||
2456 | spec->input_mux = &spec->private_imux; | 2708 | spec->input_mux = &spec->private_imux[0]; |
2709 | |||
2710 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | ||
2457 | 2711 | ||
2458 | return 1; | 2712 | return 1; |
2459 | } | 2713 | } |
@@ -2579,14 +2833,14 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = { | |||
2579 | }; | 2833 | }; |
2580 | 2834 | ||
2581 | static struct hda_pcm_stream vt1702_pcm_analog_playback = { | 2835 | static struct hda_pcm_stream vt1702_pcm_analog_playback = { |
2582 | .substreams = 1, | 2836 | .substreams = 2, |
2583 | .channels_min = 2, | 2837 | .channels_min = 2, |
2584 | .channels_max = 2, | 2838 | .channels_max = 2, |
2585 | .nid = 0x10, /* NID to query formats and rates */ | 2839 | .nid = 0x10, /* NID to query formats and rates */ |
2586 | .ops = { | 2840 | .ops = { |
2587 | .open = via_playback_pcm_open, | 2841 | .open = via_playback_pcm_open, |
2588 | .prepare = via_playback_pcm_prepare, | 2842 | .prepare = via_playback_multi_pcm_prepare, |
2589 | .cleanup = via_playback_pcm_cleanup | 2843 | .cleanup = via_playback_multi_pcm_cleanup |
2590 | }, | 2844 | }, |
2591 | }; | 2845 | }; |
2592 | 2846 | ||
@@ -2685,6 +2939,8 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
2685 | if (err < 0) | 2939 | if (err < 0) |
2686 | return err; | 2940 | return err; |
2687 | 2941 | ||
2942 | create_hp_imux(spec); | ||
2943 | |||
2688 | return 0; | 2944 | return 0; |
2689 | } | 2945 | } |
2690 | 2946 | ||
@@ -2695,7 +2951,7 @@ static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec, | |||
2695 | static char *labels[] = { | 2951 | static char *labels[] = { |
2696 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL | 2952 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL |
2697 | }; | 2953 | }; |
2698 | struct hda_input_mux *imux = &spec->private_imux; | 2954 | struct hda_input_mux *imux = &spec->private_imux[0]; |
2699 | int i, err, idx = 0; | 2955 | int i, err, idx = 0; |
2700 | 2956 | ||
2701 | /* for internal loopback recording select */ | 2957 | /* for internal loopback recording select */ |
@@ -2765,7 +3021,9 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
2765 | if (spec->kctl_alloc) | 3021 | if (spec->kctl_alloc) |
2766 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 3022 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
2767 | 3023 | ||
2768 | spec->input_mux = &spec->private_imux; | 3024 | spec->input_mux = &spec->private_imux[0]; |
3025 | |||
3026 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | ||
2769 | 3027 | ||
2770 | return 1; | 3028 | return 1; |
2771 | } | 3029 | } |