diff options
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 61 |
1 files changed, 48 insertions, 13 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index fbe97d32140d..cd29eafdc0ed 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3729,9 +3729,9 @@ static int cx_auto_init(struct hda_codec *codec) | |||
3729 | return 0; | 3729 | return 0; |
3730 | } | 3730 | } |
3731 | 3731 | ||
3732 | static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, | 3732 | static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, |
3733 | const char *dir, int cidx, | 3733 | const char *dir, int cidx, |
3734 | hda_nid_t nid, int hda_dir) | 3734 | hda_nid_t nid, int hda_dir, int amp_idx) |
3735 | { | 3735 | { |
3736 | static char name[32]; | 3736 | static char name[32]; |
3737 | static struct snd_kcontrol_new knew[] = { | 3737 | static struct snd_kcontrol_new knew[] = { |
@@ -3743,7 +3743,8 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, | |||
3743 | 3743 | ||
3744 | for (i = 0; i < 2; i++) { | 3744 | for (i = 0; i < 2; i++) { |
3745 | struct snd_kcontrol *kctl; | 3745 | struct snd_kcontrol *kctl; |
3746 | knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, hda_dir); | 3746 | knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx, |
3747 | hda_dir); | ||
3747 | knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; | 3748 | knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; |
3748 | knew[i].index = cidx; | 3749 | knew[i].index = cidx; |
3749 | snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); | 3750 | snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); |
@@ -3759,6 +3760,9 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, | |||
3759 | return 0; | 3760 | return 0; |
3760 | } | 3761 | } |
3761 | 3762 | ||
3763 | #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \ | ||
3764 | cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0) | ||
3765 | |||
3762 | #define cx_auto_add_pb_volume(codec, nid, str, idx) \ | 3766 | #define cx_auto_add_pb_volume(codec, nid, str, idx) \ |
3763 | cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) | 3767 | cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) |
3764 | 3768 | ||
@@ -3808,29 +3812,60 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) | |||
3808 | struct conexant_spec *spec = codec->spec; | 3812 | struct conexant_spec *spec = codec->spec; |
3809 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3813 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3810 | static const char *prev_label; | 3814 | static const char *prev_label; |
3811 | int i, err, cidx; | 3815 | int i, err, cidx, conn_len; |
3816 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; | ||
3817 | |||
3818 | int multi_adc_volume = 0; /* If the ADC nid has several input volumes */ | ||
3819 | int adc_nid = spec->adc_nids[0]; | ||
3820 | |||
3821 | conn_len = snd_hda_get_connections(codec, adc_nid, conn, | ||
3822 | HDA_MAX_CONNECTIONS); | ||
3823 | if (conn_len < 0) | ||
3824 | return conn_len; | ||
3825 | |||
3826 | multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1; | ||
3827 | if (!multi_adc_volume) { | ||
3828 | err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid, | ||
3829 | HDA_INPUT); | ||
3830 | if (err < 0) | ||
3831 | return err; | ||
3832 | } | ||
3812 | 3833 | ||
3813 | err = cx_auto_add_volume(codec, "Capture", "", 0, spec->adc_nids[0], | ||
3814 | HDA_INPUT); | ||
3815 | if (err < 0) | ||
3816 | return err; | ||
3817 | prev_label = NULL; | 3834 | prev_label = NULL; |
3818 | cidx = 0; | 3835 | cidx = 0; |
3819 | for (i = 0; i < cfg->num_inputs; i++) { | 3836 | for (i = 0; i < cfg->num_inputs; i++) { |
3820 | hda_nid_t nid = cfg->inputs[i].pin; | 3837 | hda_nid_t nid = cfg->inputs[i].pin; |
3821 | const char *label; | 3838 | const char *label; |
3822 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) | 3839 | int j; |
3840 | int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP; | ||
3841 | if (!pin_amp && !multi_adc_volume) | ||
3823 | continue; | 3842 | continue; |
3843 | |||
3824 | label = hda_get_autocfg_input_label(codec, cfg, i); | 3844 | label = hda_get_autocfg_input_label(codec, cfg, i); |
3825 | if (label == prev_label) | 3845 | if (label == prev_label) |
3826 | cidx++; | 3846 | cidx++; |
3827 | else | 3847 | else |
3828 | cidx = 0; | 3848 | cidx = 0; |
3829 | prev_label = label; | 3849 | prev_label = label; |
3830 | err = cx_auto_add_volume(codec, label, " Capture", cidx, | 3850 | |
3831 | nid, HDA_INPUT); | 3851 | if (pin_amp) { |
3832 | if (err < 0) | 3852 | err = cx_auto_add_volume(codec, label, " Boost", cidx, |
3833 | return err; | 3853 | nid, HDA_INPUT); |
3854 | if (err < 0) | ||
3855 | return err; | ||
3856 | } | ||
3857 | |||
3858 | if (!multi_adc_volume) | ||
3859 | continue; | ||
3860 | for (j = 0; j < conn_len; j++) { | ||
3861 | if (conn[j] == nid) { | ||
3862 | err = cx_auto_add_volume_idx(codec, label, | ||
3863 | " Capture", cidx, adc_nid, HDA_INPUT, j); | ||
3864 | if (err < 0) | ||
3865 | return err; | ||
3866 | break; | ||
3867 | } | ||
3868 | } | ||
3834 | } | 3869 | } |
3835 | return 0; | 3870 | return 0; |
3836 | } | 3871 | } |