diff options
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 4d363cfa6c81..cdcc815a9320 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -379,6 +379,14 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, | |||
379 | return 1; | 379 | return 1; |
380 | } | 380 | } |
381 | 381 | ||
382 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, | ||
383 | struct snd_ctl_elem_info *uinfo); | ||
384 | static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, | ||
385 | struct snd_ctl_elem_value *ucontrol); | ||
386 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | ||
387 | struct snd_ctl_elem_value *ucontrol); | ||
388 | |||
389 | |||
382 | /* | 390 | /* |
383 | * AD1986A specific | 391 | * AD1986A specific |
384 | */ | 392 | */ |
@@ -527,6 +535,52 @@ static struct snd_kcontrol_new ad1986a_mixers[] = { | |||
527 | { } /* end */ | 535 | { } /* end */ |
528 | }; | 536 | }; |
529 | 537 | ||
538 | /* additional mixers for 3stack mode */ | ||
539 | static struct snd_kcontrol_new ad1986a_3st_mixers[] = { | ||
540 | { | ||
541 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
542 | .name = "Channel Mode", | ||
543 | .info = ad198x_ch_mode_info, | ||
544 | .get = ad198x_ch_mode_get, | ||
545 | .put = ad198x_ch_mode_put, | ||
546 | }, | ||
547 | { } /* end */ | ||
548 | }; | ||
549 | |||
550 | /* laptop model - 2ch only */ | ||
551 | static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; | ||
552 | |||
553 | static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { | ||
554 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
555 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
556 | HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
557 | HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
558 | /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), | ||
559 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */ | ||
560 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
561 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
562 | HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), | ||
563 | HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), | ||
564 | HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), | ||
565 | HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
566 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
567 | HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
568 | /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), | ||
569 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), | ||
570 | HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), | ||
571 | HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ | ||
572 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), | ||
573 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), | ||
574 | { | ||
575 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
576 | .name = "Capture Source", | ||
577 | .info = ad198x_mux_enum_info, | ||
578 | .get = ad198x_mux_enum_get, | ||
579 | .put = ad198x_mux_enum_put, | ||
580 | }, | ||
581 | { } /* end */ | ||
582 | }; | ||
583 | |||
530 | /* | 584 | /* |
531 | * initialization verbs | 585 | * initialization verbs |
532 | */ | 586 | */ |
@@ -585,10 +639,68 @@ static struct hda_verb ad1986a_init_verbs[] = { | |||
585 | { } /* end */ | 639 | { } /* end */ |
586 | }; | 640 | }; |
587 | 641 | ||
642 | /* additional verbs for 3-stack model */ | ||
643 | static struct hda_verb ad1986a_3st_init_verbs[] = { | ||
644 | /* Mic and line-in selectors */ | ||
645 | {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
646 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
647 | { } /* end */ | ||
648 | }; | ||
649 | |||
650 | static struct hda_verb ad1986a_ch2_init[] = { | ||
651 | /* Surround out -> Line In */ | ||
652 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
653 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
654 | /* CLFE -> Mic in */ | ||
655 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
656 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
657 | { } /* end */ | ||
658 | }; | ||
659 | |||
660 | static struct hda_verb ad1986a_ch4_init[] = { | ||
661 | /* Surround out -> Surround */ | ||
662 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
663 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
664 | /* CLFE -> Mic in */ | ||
665 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
666 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
667 | { } /* end */ | ||
668 | }; | ||
669 | |||
670 | static struct hda_verb ad1986a_ch6_init[] = { | ||
671 | /* Surround out -> Surround out */ | ||
672 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
673 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
674 | /* CLFE -> CLFE */ | ||
675 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
676 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
677 | { } /* end */ | ||
678 | }; | ||
679 | |||
680 | static struct hda_channel_mode ad1986a_modes[3] = { | ||
681 | { 2, ad1986a_ch2_init }, | ||
682 | { 4, ad1986a_ch4_init }, | ||
683 | { 6, ad1986a_ch6_init }, | ||
684 | }; | ||
685 | |||
686 | /* models */ | ||
687 | enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP }; | ||
688 | |||
689 | static struct hda_board_config ad1986a_cfg_tbl[] = { | ||
690 | { .modelname = "6stack", .config = AD1986A_6STACK }, | ||
691 | { .modelname = "3stack", .config = AD1986A_3STACK }, | ||
692 | { .modelname = "laptop", .config = AD1986A_LAPTOP }, | ||
693 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, | ||
694 | .config = AD1986A_LAPTOP }, /* FSC V2060 */ | ||
695 | { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017, | ||
696 | .config = AD1986A_LAPTOP }, /* Samsung M50 */ | ||
697 | {} | ||
698 | }; | ||
588 | 699 | ||
589 | static int patch_ad1986a(struct hda_codec *codec) | 700 | static int patch_ad1986a(struct hda_codec *codec) |
590 | { | 701 | { |
591 | struct ad198x_spec *spec; | 702 | struct ad198x_spec *spec; |
703 | int board_config; | ||
592 | 704 | ||
593 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 705 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
594 | if (spec == NULL) | 706 | if (spec == NULL) |
@@ -612,6 +724,25 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
612 | 724 | ||
613 | codec->patch_ops = ad198x_patch_ops; | 725 | codec->patch_ops = ad198x_patch_ops; |
614 | 726 | ||
727 | /* override some parameters */ | ||
728 | board_config = snd_hda_check_board_config(codec, ad1986a_cfg_tbl); | ||
729 | switch (board_config) { | ||
730 | case AD1986A_3STACK: | ||
731 | spec->num_mixers = 2; | ||
732 | spec->mixers[1] = ad1986a_3st_mixers; | ||
733 | spec->num_init_verbs = 2; | ||
734 | spec->init_verbs[1] = ad1986a_3st_init_verbs; | ||
735 | spec->channel_mode = ad1986a_modes; | ||
736 | spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); | ||
737 | break; | ||
738 | case AD1986A_LAPTOP: | ||
739 | spec->mixers[0] = ad1986a_laptop_mixers; | ||
740 | spec->multiout.max_channels = 2; | ||
741 | spec->multiout.num_dacs = 1; | ||
742 | spec->multiout.dac_nids = ad1986a_laptop_dac_nids; | ||
743 | break; | ||
744 | } | ||
745 | |||
615 | return 0; | 746 | return 0; |
616 | } | 747 | } |
617 | 748 | ||