aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-05-13 11:22:05 -0400
committerTakashi Iwai <tiwai@suse.de>2011-05-13 11:22:05 -0400
commit1f8458a26293b692955f8dff671a3ed50dd9c603 (patch)
treee54609d3f90d53f2433f0e2a6d2d026cf4899102 /sound/pci
parent6764bcef4cb964456615565ff974ed917de3c12d (diff)
ALSA: hda - Add auto-parser support to cxt5045 / CX20549 Venice
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_conexant.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index cdb9f499d7f1..623cd9be5477 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1059,6 +1059,7 @@ enum {
1059#ifdef CONFIG_SND_DEBUG 1059#ifdef CONFIG_SND_DEBUG
1060 CXT5045_TEST, 1060 CXT5045_TEST,
1061#endif 1061#endif
1062 CXT5045_AUTO,
1062 CXT5045_MODELS 1063 CXT5045_MODELS
1063}; 1064};
1064 1065
@@ -1071,6 +1072,7 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
1071#ifdef CONFIG_SND_DEBUG 1072#ifdef CONFIG_SND_DEBUG
1072 [CXT5045_TEST] = "test", 1073 [CXT5045_TEST] = "test",
1073#endif 1074#endif
1075 [CXT5045_AUTO] = "auto",
1074}; 1076};
1075 1077
1076static const struct snd_pci_quirk cxt5045_cfg_tbl[] = { 1078static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
@@ -1097,6 +1099,14 @@ static int patch_cxt5045(struct hda_codec *codec)
1097 struct conexant_spec *spec; 1099 struct conexant_spec *spec;
1098 int board_config; 1100 int board_config;
1099 1101
1102 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1103 cxt5045_models,
1104 cxt5045_cfg_tbl);
1105 if (board_config < 0)
1106 board_config = CXT5045_AUTO;
1107 if (board_config == CXT5045_AUTO)
1108 return patch_conexant_auto(codec);
1109
1100 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1110 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1101 if (!spec) 1111 if (!spec)
1102 return -ENOMEM; 1112 return -ENOMEM;
@@ -1123,9 +1133,6 @@ static int patch_cxt5045(struct hda_codec *codec)
1123 1133
1124 codec->patch_ops = conexant_patch_ops; 1134 codec->patch_ops = conexant_patch_ops;
1125 1135
1126 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1127 cxt5045_models,
1128 cxt5045_cfg_tbl);
1129 switch (board_config) { 1136 switch (board_config) {
1130 case CXT5045_LAPTOP_HPSENSE: 1137 case CXT5045_LAPTOP_HPSENSE:
1131 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1138 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
@@ -1956,11 +1963,8 @@ static int patch_cxt5051(struct hda_codec *codec)
1956 cxt5051_cfg_tbl); 1963 cxt5051_cfg_tbl);
1957 if (board_config < 0) 1964 if (board_config < 0)
1958 board_config = CXT5051_AUTO; 1965 board_config = CXT5051_AUTO;
1959 if (board_config == CXT5051_AUTO) { 1966 if (board_config == CXT5051_AUTO)
1960 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1961 codec->chip_name);
1962 return patch_conexant_auto(codec); 1967 return patch_conexant_auto(codec);
1963 }
1964 1968
1965 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1969 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1966 if (!spec) 1970 if (!spec)
@@ -3688,15 +3692,15 @@ static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3688 AC_VERB_SET_CONNECT_SEL, idx); 3692 AC_VERB_SET_CONNECT_SEL, idx);
3689} 3693}
3690 3694
3691static void cx_auto_init_output(struct hda_codec *codec) 3695static void mute_outputs(struct hda_codec *codec, int num_nids,
3696 const hda_nid_t *nids)
3692{ 3697{
3693 struct conexant_spec *spec = codec->spec;
3694 struct auto_pin_cfg *cfg = &spec->autocfg;
3695 hda_nid_t nid;
3696 int i, val; 3698 int i, val;
3697 3699
3698 for (i = 0; i < spec->multiout.num_dacs; i++) { 3700 for (i = 0; i < num_nids; i++) {
3699 nid = spec->multiout.dac_nids[i]; 3701 hda_nid_t nid = nids[i];
3702 if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
3703 continue;
3700 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) 3704 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3701 val = AMP_OUT_MUTE; 3705 val = AMP_OUT_MUTE;
3702 else 3706 else
@@ -3704,10 +3708,22 @@ static void cx_auto_init_output(struct hda_codec *codec)
3704 snd_hda_codec_write(codec, nid, 0, 3708 snd_hda_codec_write(codec, nid, 0,
3705 AC_VERB_SET_AMP_GAIN_MUTE, val); 3709 AC_VERB_SET_AMP_GAIN_MUTE, val);
3706 } 3710 }
3711}
3707 3712
3713static void cx_auto_init_output(struct hda_codec *codec)
3714{
3715 struct conexant_spec *spec = codec->spec;
3716 struct auto_pin_cfg *cfg = &spec->autocfg;
3717 hda_nid_t nid;
3718 int i;
3719
3720 mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
3708 for (i = 0; i < cfg->hp_outs; i++) 3721 for (i = 0; i < cfg->hp_outs; i++)
3709 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3722 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3710 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 3723 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3724 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3725 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
3726 mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
3711 if (spec->auto_mute) { 3727 if (spec->auto_mute) {
3712 for (i = 0; i < cfg->hp_outs; i++) { 3728 for (i = 0; i < cfg->hp_outs; i++) {
3713 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3729 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
@@ -3747,6 +3763,8 @@ static void cx_auto_init_input(struct hda_codec *codec)
3747 3763
3748 for (i = 0; i < spec->num_adc_nids; i++) { 3764 for (i = 0; i < spec->num_adc_nids; i++) {
3749 hda_nid_t nid = spec->adc_nids[i]; 3765 hda_nid_t nid = spec->adc_nids[i];
3766 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
3767 continue;
3750 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) 3768 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
3751 val = AMP_IN_MUTE(0); 3769 val = AMP_IN_MUTE(0);
3752 else 3770 else
@@ -3839,6 +3857,19 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3839#define cx_auto_add_pb_volume(codec, nid, str, idx) \ 3857#define cx_auto_add_pb_volume(codec, nid, str, idx) \
3840 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) 3858 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
3841 3859
3860static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
3861 hda_nid_t pin, const char *name, int idx)
3862{
3863 unsigned int caps;
3864 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
3865 if (caps & AC_AMPCAP_NUM_STEPS)
3866 return cx_auto_add_pb_volume(codec, dac, name, idx);
3867 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
3868 if (caps & AC_AMPCAP_NUM_STEPS)
3869 return cx_auto_add_pb_volume(codec, pin, name, idx);
3870 return 0;
3871}
3872
3842static int cx_auto_build_output_controls(struct hda_codec *codec) 3873static int cx_auto_build_output_controls(struct hda_codec *codec)
3843{ 3874{
3844 struct conexant_spec *spec = codec->spec; 3875 struct conexant_spec *spec = codec->spec;
@@ -3847,8 +3878,10 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3847 static const char * const texts[3] = { "Front", "Surround", "CLFE" }; 3878 static const char * const texts[3] = { "Front", "Surround", "CLFE" };
3848 3879
3849 if (spec->dac_info_filled == 1) 3880 if (spec->dac_info_filled == 1)
3850 return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, 3881 return try_add_pb_volume(codec, spec->dac_info[0].dac,
3851 "Master", 0); 3882 spec->dac_info[0].pin,
3883 "Master", 0);
3884
3852 for (i = 0; i < spec->dac_info_filled; i++) { 3885 for (i = 0; i < spec->dac_info_filled; i++) {
3853 const char *label; 3886 const char *label;
3854 int idx, type; 3887 int idx, type;
@@ -3872,8 +3905,9 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3872 idx = num_spk++; 3905 idx = num_spk++;
3873 break; 3906 break;
3874 } 3907 }
3875 err = cx_auto_add_pb_volume(codec, spec->dac_info[i].dac, 3908 err = try_add_pb_volume(codec, spec->dac_info[i].dac,
3876 label, idx); 3909 spec->dac_info[i].pin,
3910 label, idx);
3877 if (err < 0) 3911 if (err < 0)
3878 return err; 3912 return err;
3879 } 3913 }
@@ -3976,19 +4010,31 @@ static int patch_conexant_auto(struct hda_codec *codec)
3976 struct conexant_spec *spec; 4010 struct conexant_spec *spec;
3977 int err; 4011 int err;
3978 4012
4013 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4014 codec->chip_name);
4015
3979 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4016 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3980 if (!spec) 4017 if (!spec)
3981 return -ENOMEM; 4018 return -ENOMEM;
3982 codec->spec = spec; 4019 codec->spec = spec;
3983 if (codec->vendor_id == 0x14f15051) { 4020 switch (codec->vendor_id) {
4021 case 0x14f15051:
3984 codec->pin_amp_workaround = 1; 4022 codec->pin_amp_workaround = 1;
3985 spec->adc_nids = cxt5051_adc_nids; 4023 spec->adc_nids = cxt5051_adc_nids;
3986 spec->num_adc_nids = ARRAY_SIZE(cxt5051_adc_nids); 4024 spec->num_adc_nids = ARRAY_SIZE(cxt5051_adc_nids);
3987 spec->capsrc_nids = spec->adc_nids; 4025 spec->capsrc_nids = spec->adc_nids;
3988 } else { 4026 break;
4027 case 0x14f15045:
4028 codec->pin_amp_workaround = 1;
4029 spec->adc_nids = cxt5045_adc_nids;
4030 spec->num_adc_nids = ARRAY_SIZE(cxt5045_adc_nids);
4031 spec->capsrc_nids = spec->adc_nids;
4032 break;
4033 default:
3989 spec->adc_nids = cx_auto_adc_nids; 4034 spec->adc_nids = cx_auto_adc_nids;
3990 spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids); 4035 spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids);
3991 spec->capsrc_nids = spec->adc_nids; 4036 spec->capsrc_nids = spec->adc_nids;
4037 break;
3992 } 4038 }
3993 err = cx_auto_parse_auto_config(codec); 4039 err = cx_auto_parse_auto_config(codec);
3994 if (err < 0) { 4040 if (err < 0) {