aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_conexant.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r--sound/pci/hda/patch_conexant.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index fbe97d32140d..4d5004e693f0 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3114,6 +3114,8 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3114 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), 3114 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3115 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), 3115 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3116 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 3116 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3117 SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
3118 SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
3117 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), 3119 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3118 SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS), 3120 SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
3119 SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS), 3121 SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
@@ -3410,7 +3412,7 @@ static void cx_auto_parse_output(struct hda_codec *codec)
3410 } 3412 }
3411 } 3413 }
3412 spec->multiout.dac_nids = spec->private_dac_nids; 3414 spec->multiout.dac_nids = spec->private_dac_nids;
3413 spec->multiout.max_channels = nums * 2; 3415 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3414 3416
3415 if (cfg->hp_outs > 0) 3417 if (cfg->hp_outs > 0)
3416 spec->auto_mute = 1; 3418 spec->auto_mute = 1;
@@ -3729,9 +3731,9 @@ static int cx_auto_init(struct hda_codec *codec)
3729 return 0; 3731 return 0;
3730} 3732}
3731 3733
3732static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, 3734static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3733 const char *dir, int cidx, 3735 const char *dir, int cidx,
3734 hda_nid_t nid, int hda_dir) 3736 hda_nid_t nid, int hda_dir, int amp_idx)
3735{ 3737{
3736 static char name[32]; 3738 static char name[32];
3737 static struct snd_kcontrol_new knew[] = { 3739 static struct snd_kcontrol_new knew[] = {
@@ -3743,7 +3745,8 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
3743 3745
3744 for (i = 0; i < 2; i++) { 3746 for (i = 0; i < 2; i++) {
3745 struct snd_kcontrol *kctl; 3747 struct snd_kcontrol *kctl;
3746 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, hda_dir); 3748 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
3749 hda_dir);
3747 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; 3750 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
3748 knew[i].index = cidx; 3751 knew[i].index = cidx;
3749 snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); 3752 snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
@@ -3759,6 +3762,9 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
3759 return 0; 3762 return 0;
3760} 3763}
3761 3764
3765#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \
3766 cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
3767
3762#define cx_auto_add_pb_volume(codec, nid, str, idx) \ 3768#define cx_auto_add_pb_volume(codec, nid, str, idx) \
3763 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) 3769 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
3764 3770
@@ -3808,29 +3814,60 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
3808 struct conexant_spec *spec = codec->spec; 3814 struct conexant_spec *spec = codec->spec;
3809 struct auto_pin_cfg *cfg = &spec->autocfg; 3815 struct auto_pin_cfg *cfg = &spec->autocfg;
3810 static const char *prev_label; 3816 static const char *prev_label;
3811 int i, err, cidx; 3817 int i, err, cidx, conn_len;
3818 hda_nid_t conn[HDA_MAX_CONNECTIONS];
3819
3820 int multi_adc_volume = 0; /* If the ADC nid has several input volumes */
3821 int adc_nid = spec->adc_nids[0];
3822
3823 conn_len = snd_hda_get_connections(codec, adc_nid, conn,
3824 HDA_MAX_CONNECTIONS);
3825 if (conn_len < 0)
3826 return conn_len;
3827
3828 multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1;
3829 if (!multi_adc_volume) {
3830 err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid,
3831 HDA_INPUT);
3832 if (err < 0)
3833 return err;
3834 }
3812 3835
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; 3836 prev_label = NULL;
3818 cidx = 0; 3837 cidx = 0;
3819 for (i = 0; i < cfg->num_inputs; i++) { 3838 for (i = 0; i < cfg->num_inputs; i++) {
3820 hda_nid_t nid = cfg->inputs[i].pin; 3839 hda_nid_t nid = cfg->inputs[i].pin;
3821 const char *label; 3840 const char *label;
3822 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) 3841 int j;
3842 int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
3843 if (!pin_amp && !multi_adc_volume)
3823 continue; 3844 continue;
3845
3824 label = hda_get_autocfg_input_label(codec, cfg, i); 3846 label = hda_get_autocfg_input_label(codec, cfg, i);
3825 if (label == prev_label) 3847 if (label == prev_label)
3826 cidx++; 3848 cidx++;
3827 else 3849 else
3828 cidx = 0; 3850 cidx = 0;
3829 prev_label = label; 3851 prev_label = label;
3830 err = cx_auto_add_volume(codec, label, " Capture", cidx, 3852
3831 nid, HDA_INPUT); 3853 if (pin_amp) {
3832 if (err < 0) 3854 err = cx_auto_add_volume(codec, label, " Boost", cidx,
3833 return err; 3855 nid, HDA_INPUT);
3856 if (err < 0)
3857 return err;
3858 }
3859
3860 if (!multi_adc_volume)
3861 continue;
3862 for (j = 0; j < conn_len; j++) {
3863 if (conn[j] == nid) {
3864 err = cx_auto_add_volume_idx(codec, label,
3865 " Capture", cidx, adc_nid, HDA_INPUT, j);
3866 if (err < 0)
3867 return err;
3868 break;
3869 }
3870 }
3834 } 3871 }
3835 return 0; 3872 return 0;
3836} 3873}
@@ -3902,6 +3939,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
3902 .patch = patch_cxt5066 }, 3939 .patch = patch_cxt5066 },
3903 { .id = 0x14f15069, .name = "CX20585", 3940 { .id = 0x14f15069, .name = "CX20585",
3904 .patch = patch_cxt5066 }, 3941 .patch = patch_cxt5066 },
3942 { .id = 0x14f1506e, .name = "CX20590",
3943 .patch = patch_cxt5066 },
3905 { .id = 0x14f15097, .name = "CX20631", 3944 { .id = 0x14f15097, .name = "CX20631",
3906 .patch = patch_conexant_auto }, 3945 .patch = patch_conexant_auto },
3907 { .id = 0x14f15098, .name = "CX20632", 3946 { .id = 0x14f15098, .name = "CX20632",
@@ -3928,6 +3967,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15066");
3928MODULE_ALIAS("snd-hda-codec-id:14f15067"); 3967MODULE_ALIAS("snd-hda-codec-id:14f15067");
3929MODULE_ALIAS("snd-hda-codec-id:14f15068"); 3968MODULE_ALIAS("snd-hda-codec-id:14f15068");
3930MODULE_ALIAS("snd-hda-codec-id:14f15069"); 3969MODULE_ALIAS("snd-hda-codec-id:14f15069");
3970MODULE_ALIAS("snd-hda-codec-id:14f1506e");
3931MODULE_ALIAS("snd-hda-codec-id:14f15097"); 3971MODULE_ALIAS("snd-hda-codec-id:14f15097");
3932MODULE_ALIAS("snd-hda-codec-id:14f15098"); 3972MODULE_ALIAS("snd-hda-codec-id:14f15098");
3933MODULE_ALIAS("snd-hda-codec-id:14f150a1"); 3973MODULE_ALIAS("snd-hda-codec-id:14f150a1");