diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-07-08 10:19:48 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-08 10:19:48 -0400 |
commit | 8452a982fb8a1d02d755a53a913c087a0d31aa18 (patch) | |
tree | 63ab15b08bcc7736e63dc4ac383248902d598838 /sound | |
parent | 4c11398edc19fdd9c651f3ff287cd628fecaf574 (diff) |
ALSA: hda - Merge ALC260 auto-parser code
Finally the last one.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 153 |
1 files changed, 11 insertions, 142 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2a94c58b2104..10de78d8bc2a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -3677,132 +3677,6 @@ static int patch_alc880(struct hda_codec *codec) | |||
3677 | /* | 3677 | /* |
3678 | * ALC260 support | 3678 | * ALC260 support |
3679 | */ | 3679 | */ |
3680 | |||
3681 | /* convert from pin to volume-mixer widget */ | ||
3682 | static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid) | ||
3683 | { | ||
3684 | if (nid >= 0x0f && nid <= 0x11) | ||
3685 | return nid - 0x7; | ||
3686 | else if (nid >= 0x12 && nid <= 0x15) | ||
3687 | return 0x08; | ||
3688 | else | ||
3689 | return 0; | ||
3690 | } | ||
3691 | |||
3692 | static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | ||
3693 | const char *pfx, int *vol_bits) | ||
3694 | { | ||
3695 | hda_nid_t nid_vol; | ||
3696 | unsigned long vol_val, sw_val; | ||
3697 | int chs, err; | ||
3698 | |||
3699 | nid_vol = alc260_pin_to_vol_mix(nid); | ||
3700 | if (!nid_vol) | ||
3701 | return 0; /* N/A */ | ||
3702 | if (nid == 0x11) | ||
3703 | chs = 2; | ||
3704 | else | ||
3705 | chs = 3; | ||
3706 | vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT); | ||
3707 | sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); | ||
3708 | |||
3709 | if (!(*vol_bits & (1 << nid_vol))) { | ||
3710 | /* first control for the volume widget */ | ||
3711 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); | ||
3712 | if (err < 0) | ||
3713 | return err; | ||
3714 | *vol_bits |= (1 << nid_vol); | ||
3715 | } | ||
3716 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); | ||
3717 | if (err < 0) | ||
3718 | return err; | ||
3719 | return 1; | ||
3720 | } | ||
3721 | |||
3722 | /* add playback controls from the parsed DAC table */ | ||
3723 | static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
3724 | const struct auto_pin_cfg *cfg) | ||
3725 | { | ||
3726 | hda_nid_t nid; | ||
3727 | int err; | ||
3728 | int vols = 0; | ||
3729 | |||
3730 | spec->multiout.num_dacs = 1; | ||
3731 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
3732 | spec->private_dac_nids[0] = 0x02; | ||
3733 | |||
3734 | nid = cfg->line_out_pins[0]; | ||
3735 | if (nid) { | ||
3736 | const char *pfx; | ||
3737 | int index; | ||
3738 | pfx = alc_get_line_out_pfx(spec, 0, true, &index); | ||
3739 | err = alc260_add_playback_controls(spec, nid, pfx, &vols); | ||
3740 | if (err < 0) | ||
3741 | return err; | ||
3742 | } | ||
3743 | |||
3744 | nid = cfg->speaker_pins[0]; | ||
3745 | if (nid) { | ||
3746 | err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); | ||
3747 | if (err < 0) | ||
3748 | return err; | ||
3749 | } | ||
3750 | |||
3751 | nid = cfg->hp_pins[0]; | ||
3752 | if (nid) { | ||
3753 | err = alc260_add_playback_controls(spec, nid, "Headphone", | ||
3754 | &vols); | ||
3755 | if (err < 0) | ||
3756 | return err; | ||
3757 | } | ||
3758 | return 0; | ||
3759 | } | ||
3760 | |||
3761 | static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, | ||
3762 | hda_nid_t nid, int pin_type, | ||
3763 | int sel_idx) | ||
3764 | { | ||
3765 | hda_nid_t mix; | ||
3766 | |||
3767 | alc_set_pin_output(codec, nid, pin_type); | ||
3768 | /* need the manual connection? */ | ||
3769 | if (nid >= 0x12) { | ||
3770 | int idx = nid - 0x12; | ||
3771 | snd_hda_codec_write(codec, idx + 0x0b, 0, | ||
3772 | AC_VERB_SET_CONNECT_SEL, sel_idx); | ||
3773 | } | ||
3774 | |||
3775 | mix = alc260_pin_to_vol_mix(nid); | ||
3776 | if (!mix) | ||
3777 | return; | ||
3778 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3779 | AMP_OUT_ZERO); | ||
3780 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3781 | AMP_IN_UNMUTE(0)); | ||
3782 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3783 | AMP_IN_UNMUTE(1)); | ||
3784 | } | ||
3785 | |||
3786 | static void alc260_auto_init_multi_out(struct hda_codec *codec) | ||
3787 | { | ||
3788 | struct alc_spec *spec = codec->spec; | ||
3789 | hda_nid_t nid; | ||
3790 | |||
3791 | nid = spec->autocfg.line_out_pins[0]; | ||
3792 | if (nid) { | ||
3793 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
3794 | alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); | ||
3795 | } | ||
3796 | |||
3797 | nid = spec->autocfg.speaker_pins[0]; | ||
3798 | if (nid) | ||
3799 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | ||
3800 | |||
3801 | nid = spec->autocfg.hp_pins[0]; | ||
3802 | if (nid) | ||
3803 | alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); | ||
3804 | } | ||
3805 | |||
3806 | static int alc260_parse_auto_config(struct hda_codec *codec) | 3680 | static int alc260_parse_auto_config(struct hda_codec *codec) |
3807 | { | 3681 | { |
3808 | struct alc_spec *spec = codec->spec; | 3682 | struct alc_spec *spec = codec->spec; |
@@ -3813,11 +3687,18 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
3813 | alc260_ignore); | 3687 | alc260_ignore); |
3814 | if (err < 0) | 3688 | if (err < 0) |
3815 | return err; | 3689 | return err; |
3816 | err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); | 3690 | err = alc_auto_fill_dac_nids(codec); |
3691 | if (err < 0) | ||
3692 | return err; | ||
3693 | err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg); | ||
3694 | if (err < 0) | ||
3695 | return err; | ||
3696 | err = alc_auto_create_hp_out(codec); | ||
3697 | if (err < 0) | ||
3698 | return err; | ||
3699 | err = alc_auto_create_speaker_out(codec); | ||
3817 | if (err < 0) | 3700 | if (err < 0) |
3818 | return err; | 3701 | return err; |
3819 | if (!spec->kctls.list) | ||
3820 | return 0; /* can't find valid BIOS pin config */ | ||
3821 | err = alc_auto_create_input_ctls(codec); | 3702 | err = alc_auto_create_input_ctls(codec); |
3822 | if (err < 0) | 3703 | if (err < 0) |
3823 | return err; | 3704 | return err; |
@@ -3837,18 +3718,6 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
3837 | return 1; | 3718 | return 1; |
3838 | } | 3719 | } |
3839 | 3720 | ||
3840 | /* additional initialization for auto-configuration model */ | ||
3841 | static void alc260_auto_init(struct hda_codec *codec) | ||
3842 | { | ||
3843 | struct alc_spec *spec = codec->spec; | ||
3844 | alc260_auto_init_multi_out(codec); | ||
3845 | alc_auto_init_analog_input(codec); | ||
3846 | alc_auto_init_input_src(codec); | ||
3847 | alc_auto_init_digital(codec); | ||
3848 | if (spec->unsol_event) | ||
3849 | alc_inithook(codec); | ||
3850 | } | ||
3851 | |||
3852 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3721 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3853 | static const struct hda_amp_list alc260_loopbacks[] = { | 3722 | static const struct hda_amp_list alc260_loopbacks[] = { |
3854 | { 0x07, HDA_INPUT, 0 }, | 3723 | { 0x07, HDA_INPUT, 0 }, |
@@ -3954,7 +3823,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
3954 | 3823 | ||
3955 | codec->patch_ops = alc_patch_ops; | 3824 | codec->patch_ops = alc_patch_ops; |
3956 | if (board_config == ALC_MODEL_AUTO) | 3825 | if (board_config == ALC_MODEL_AUTO) |
3957 | spec->init_hook = alc260_auto_init; | 3826 | spec->init_hook = alc_auto_init_std; |
3958 | spec->shutup = alc_eapd_shutup; | 3827 | spec->shutup = alc_eapd_shutup; |
3959 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3828 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3960 | if (!spec->loopback.amplist) | 3829 | if (!spec->loopback.amplist) |