aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_analog.c116
1 files changed, 115 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index cdcc815a9320..2b14fa74a8fd 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -581,6 +581,97 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
581 { } /* end */ 581 { } /* end */
582}; 582};
583 583
584/* laptop-eapd model - 2ch only */
585
586/* master controls both pins 0x1a and 0x1b */
587static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_value *ucontrol)
589{
590 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
591 long *valp = ucontrol->value.integer.value;
592 int change;
593
594 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
595 0x7f, valp[0] & 0x7f);
596 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
597 0x7f, valp[1] & 0x7f);
598 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
599 0x7f, valp[0] & 0x7f);
600 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
601 0x7f, valp[1] & 0x7f);
602 return change;
603}
604
605static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol,
606 struct snd_ctl_elem_value *ucontrol)
607{
608 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
609 long *valp = ucontrol->value.integer.value;
610 int change;
611
612 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
613 0x80, valp[0] ? 0 : 0x80);
614 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
615 0x80, valp[1] ? 0 : 0x80);
616 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
617 0x80, valp[0] ? 0 : 0x80);
618 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
619 0x80, valp[1] ? 0 : 0x80);
620 return change;
621}
622
623static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
624 .num_items = 3,
625 .items = {
626 { "Mic", 0x0 },
627 { "Internal Mic", 0x4 },
628 { "Mix", 0x5 },
629 },
630};
631
632static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
633 {
634 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
635 .name = "Master Playback Volume",
636 .info = snd_hda_mixer_amp_volume_info,
637 .get = snd_hda_mixer_amp_volume_get,
638 .put = ad1986a_laptop_master_vol_put,
639 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
640 },
641 {
642 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
643 .name = "Master Playback Switch",
644 .info = snd_hda_mixer_amp_switch_info,
645 .get = snd_hda_mixer_amp_switch_get,
646 .put = ad1986a_laptop_master_sw_put,
647 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
648 },
649 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
650 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
651 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
652 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
654 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
655 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
656 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
657 {
658 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
659 .name = "Capture Source",
660 .info = ad198x_mux_enum_info,
661 .get = ad198x_mux_enum_get,
662 .put = ad198x_mux_enum_put,
663 },
664 {
665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
666 .name = "External Amplifier",
667 .info = ad198x_eapd_info,
668 .get = ad198x_eapd_get,
669 .put = ad198x_eapd_put,
670 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
671 },
672 { } /* end */
673};
674
584/* 675/*
585 * initialization verbs 676 * initialization verbs
586 */ 677 */
@@ -683,8 +774,14 @@ static struct hda_channel_mode ad1986a_modes[3] = {
683 { 6, ad1986a_ch6_init }, 774 { 6, ad1986a_ch6_init },
684}; 775};
685 776
777/* eapd initialization */
778static struct hda_verb ad1986a_eapd_init_verbs[] = {
779 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00},
780 {}
781};
782
686/* models */ 783/* models */
687enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP }; 784enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD };
688 785
689static struct hda_board_config ad1986a_cfg_tbl[] = { 786static struct hda_board_config ad1986a_cfg_tbl[] = {
690 { .modelname = "6stack", .config = AD1986A_6STACK }, 787 { .modelname = "6stack", .config = AD1986A_6STACK },
@@ -694,6 +791,13 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
694 .config = AD1986A_LAPTOP }, /* FSC V2060 */ 791 .config = AD1986A_LAPTOP }, /* FSC V2060 */
695 { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017, 792 { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017,
696 .config = AD1986A_LAPTOP }, /* Samsung M50 */ 793 .config = AD1986A_LAPTOP }, /* Samsung M50 */
794 { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f,
795 .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */
796 { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD },
797 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024,
798 .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */
799 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1213,
800 .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */
697 {} 801 {}
698}; 802};
699 803
@@ -741,6 +845,16 @@ static int patch_ad1986a(struct hda_codec *codec)
741 spec->multiout.num_dacs = 1; 845 spec->multiout.num_dacs = 1;
742 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 846 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
743 break; 847 break;
848 case AD1986A_LAPTOP_EAPD:
849 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
850 spec->num_init_verbs = 2;
851 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
852 spec->multiout.max_channels = 2;
853 spec->multiout.num_dacs = 1;
854 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
855 spec->multiout.dig_out_nid = 0;
856 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
857 break;
744 } 858 }
745 859
746 return 0; 860 return 0;