aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_conexant.c61
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
3732static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, 3732static 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}