aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_via.c85
1 files changed, 46 insertions, 39 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 9e8dd57e8d5c..e3bd5261986e 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -252,6 +252,7 @@ struct via_spec {
252 /* HP mode source */ 252 /* HP mode source */
253 const struct hda_input_mux *hp_mux; 253 const struct hda_input_mux *hp_mux;
254 unsigned int hp_independent_mode; 254 unsigned int hp_independent_mode;
255 unsigned int hp_independent_mode_index;
255 256
256 enum VIA_HDA_CODEC codec_type; 257 enum VIA_HDA_CODEC codec_type;
257 258
@@ -584,6 +585,36 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active)
584 } 585 }
585} 586}
586 587
588static int update_side_mute_status(struct hda_codec *codec)
589{
590 /* mute side channel */
591 struct via_spec *spec = codec->spec;
592 unsigned int parm = spec->hp_independent_mode
593 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
594 hda_nid_t sw3;
595
596 switch (spec->codec_type) {
597 case VT1708:
598 sw3 = 0x1b;
599 break;
600 case VT1709_10CH:
601 sw3 = 0x29;
602 break;
603 case VT1708B_8CH:
604 case VT1708S:
605 sw3 = 0x27;
606 break;
607 default:
608 sw3 = 0;
609 break;
610 }
611
612 if (sw3)
613 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
614 parm);
615 return 0;
616}
617
587static int via_independent_hp_put(struct snd_kcontrol *kcontrol, 618static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_value *ucontrol) 619 struct snd_ctl_elem_value *ucontrol)
589{ 620{
@@ -591,47 +622,18 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
591 struct via_spec *spec = codec->spec; 622 struct via_spec *spec = codec->spec;
592 hda_nid_t nid = spec->autocfg.hp_pins[0]; 623 hda_nid_t nid = spec->autocfg.hp_pins[0];
593 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 624 unsigned int pinsel = ucontrol->value.enumerated.item[0];
594 unsigned int con_nid = snd_hda_codec_read(codec, nid, 0, 625 /* Get Independent Mode index of headphone pin widget */
595 AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 626 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
596 627 ? 1 : 0;
597 if (con_nid == spec->multiout.hp_nid) {
598 if (pinsel == 0) {
599 if (!spec->hp_independent_mode) {
600 if (spec->multiout.num_dacs > 1)
601 spec->multiout.num_dacs -= 1;
602 spec->hp_independent_mode = 1;
603 }
604 } else if (pinsel == 1) {
605 if (spec->hp_independent_mode) {
606 if (spec->multiout.num_dacs > 1)
607 spec->multiout.num_dacs += 1;
608 spec->hp_independent_mode = 0;
609 }
610 }
611 } else {
612 if (pinsel == 0) {
613 if (spec->hp_independent_mode) {
614 if (spec->multiout.num_dacs > 1)
615 spec->multiout.num_dacs += 1;
616 spec->hp_independent_mode = 0;
617 }
618 } else if (pinsel == 1) {
619 if (!spec->hp_independent_mode) {
620 if (spec->multiout.num_dacs > 1)
621 spec->multiout.num_dacs -= 1;
622 spec->hp_independent_mode = 1;
623 }
624 }
625 }
626 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
627 pinsel);
628 628
629 if (spec->multiout.hp_nid && 629 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
630 spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT]) 630
631 snd_hda_codec_setup_stream(codec, 631 if (spec->multiout.hp_nid && spec->multiout.hp_nid
632 spec->multiout.hp_nid, 632 != spec->multiout.dac_nids[HDA_FRONT])
633 0, 0, 0); 633 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
634 0, 0, 0);
634 635
636 update_side_mute_status(codec);
635 /* update HP volume/swtich active state */ 637 /* update HP volume/swtich active state */
636 if (spec->codec_type == VT1708S 638 if (spec->codec_type == VT1708S
637 || spec->codec_type == VT1702) { 639 || spec->codec_type == VT1702) {
@@ -1447,6 +1449,7 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1447 return 0; 1449 return 0;
1448 1450
1449 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 1451 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
1452 spec->hp_independent_mode_index = 1;
1450 1453
1451 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1454 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1452 "Headphone Playback Volume", 1455 "Headphone Playback Volume",
@@ -1982,6 +1985,7 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1982 spec->multiout.hp_nid = VT1709_HP_DAC_NID; 1985 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1983 else if (spec->multiout.num_dacs == 3) /* 6 channels */ 1986 else if (spec->multiout.num_dacs == 3) /* 6 channels */
1984 spec->multiout.hp_nid = 0; 1987 spec->multiout.hp_nid = 0;
1988 spec->hp_independent_mode_index = 1;
1985 1989
1986 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1990 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1987 "Headphone Playback Volume", 1991 "Headphone Playback Volume",
@@ -2541,6 +2545,7 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2541 return 0; 2545 return 0;
2542 2546
2543 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */ 2547 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
2548 spec->hp_independent_mode_index = 1;
2544 2549
2545 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2550 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2546 "Headphone Playback Volume", 2551 "Headphone Playback Volume",
@@ -3011,6 +3016,7 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3011 return 0; 3016 return 0;
3012 3017
3013 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */ 3018 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3019 spec->hp_independent_mode_index = 1;
3014 3020
3015 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3021 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3016 "Headphone Playback Volume", 3022 "Headphone Playback Volume",
@@ -3368,6 +3374,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3368 if (!pin) 3374 if (!pin)
3369 return 0; 3375 return 0;
3370 spec->multiout.hp_nid = 0x1D; 3376 spec->multiout.hp_nid = 0x1D;
3377 spec->hp_independent_mode_index = 0;
3371 3378
3372 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3379 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3373 "Headphone Playback Volume", 3380 "Headphone Playback Volume",