aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-08 05:07:59 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-08 05:07:59 -0400
commitafcd551508dcdb38e80728137c1c166d19bd47dd (patch)
tree4d47ffda5118018780d19f77ca98926ec7f3fc32 /sound
parente59ea3ed9fe0cde526c004441465d13287426b29 (diff)
ALSA: hda - Merge ALC680 auto-parser to the standard parser
Improved the standard Realtek auto-parser to support the codec topology like ALC680. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c231
1 files changed, 90 insertions, 141 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a29e6b3c6a70..f82333b11e41 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2682,6 +2682,8 @@ static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
2682 hda_nid_t list[5]; 2682 hda_nid_t list[5];
2683 int i, num; 2683 int i, num;
2684 2684
2685 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT)
2686 return nid;
2685 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); 2687 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
2686 for (i = 0; i < num; i++) { 2688 for (i = 0; i < num; i++) {
2687 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) 2689 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
@@ -2838,6 +2840,8 @@ static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2838 const char *pfx, int cidx, 2840 const char *pfx, int cidx,
2839 hda_nid_t nid, unsigned int chs) 2841 hda_nid_t nid, unsigned int chs)
2840{ 2842{
2843 if (!nid)
2844 return 0;
2841 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, 2845 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
2842 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 2846 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2843} 2847}
@@ -2852,9 +2856,16 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2852 const char *pfx, int cidx, 2856 const char *pfx, int cidx,
2853 hda_nid_t nid, unsigned int chs) 2857 hda_nid_t nid, unsigned int chs)
2854{ 2858{
2859 int wid_type;
2855 int type; 2860 int type;
2856 unsigned long val; 2861 unsigned long val;
2857 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) { 2862 if (!nid)
2863 return 0;
2864 wid_type = get_wcaps_type(get_wcaps(codec, nid));
2865 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
2866 type = ALC_CTL_WIDGET_MUTE;
2867 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
2868 } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
2858 type = ALC_CTL_WIDGET_MUTE; 2869 type = ALC_CTL_WIDGET_MUTE;
2859 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT); 2870 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
2860 } else { 2871 } else {
@@ -2867,12 +2878,42 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2867#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \ 2878#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
2868 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3) 2879 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
2869 2880
2881#define nid_has_mute(codec, nid, dir) \
2882 (query_amp_caps(codec, nid, dir) & AC_AMPCAP_MUTE)
2883#define nid_has_volume(codec, nid, dir) \
2884 (query_amp_caps(codec, nid, dir) & AC_AMPCAP_NUM_STEPS)
2885
2886static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
2887 hda_nid_t pin, hda_nid_t dac)
2888{
2889 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2890 if (nid_has_mute(codec, pin, HDA_OUTPUT))
2891 return pin;
2892 else if (mix && nid_has_mute(codec, mix, HDA_INPUT))
2893 return mix;
2894 else if (nid_has_mute(codec, dac, HDA_OUTPUT))
2895 return dac;
2896 return 0;
2897}
2898
2899static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
2900 hda_nid_t pin, hda_nid_t dac)
2901{
2902 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2903 if (nid_has_volume(codec, dac, HDA_OUTPUT))
2904 return dac;
2905 else if (nid_has_volume(codec, mix, HDA_OUTPUT))
2906 return mix;
2907 else if (nid_has_volume(codec, pin, HDA_OUTPUT))
2908 return pin;
2909 return 0;
2910}
2911
2870/* add playback controls from the parsed DAC table */ 2912/* add playback controls from the parsed DAC table */
2871static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, 2913static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2872 const struct auto_pin_cfg *cfg) 2914 const struct auto_pin_cfg *cfg)
2873{ 2915{
2874 struct alc_spec *spec = codec->spec; 2916 struct alc_spec *spec = codec->spec;
2875 hda_nid_t nid, mix, pin;
2876 int i, err, noutputs; 2917 int i, err, noutputs;
2877 2918
2878 noutputs = cfg->line_outs; 2919 noutputs = cfg->line_outs;
@@ -2882,36 +2923,39 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2882 for (i = 0; i < noutputs; i++) { 2923 for (i = 0; i < noutputs; i++) {
2883 const char *name; 2924 const char *name;
2884 int index; 2925 int index;
2885 nid = spec->multiout.dac_nids[i]; 2926 hda_nid_t dac, pin;
2886 if (!nid) 2927 hda_nid_t sw, vol;
2928
2929 dac = spec->multiout.dac_nids[i];
2930 if (!dac)
2887 continue; 2931 continue;
2888 if (i >= cfg->line_outs) 2932 if (i >= cfg->line_outs)
2889 pin = spec->multi_io[i - 1].pin; 2933 pin = spec->multi_io[i - 1].pin;
2890 else 2934 else
2891 pin = cfg->line_out_pins[i]; 2935 pin = cfg->line_out_pins[i];
2892 mix = alc_auto_dac_to_mix(codec, pin, nid); 2936
2893 if (!mix) 2937 sw = alc_look_for_out_mute_nid(codec, pin, dac);
2894 continue; 2938 vol = alc_look_for_out_vol_nid(codec, pin, dac);
2895 name = alc_get_line_out_pfx(spec, i, true, &index); 2939 name = alc_get_line_out_pfx(spec, i, true, &index);
2896 if (!name) { 2940 if (!name) {
2897 /* Center/LFE */ 2941 /* Center/LFE */
2898 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1); 2942 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
2899 if (err < 0) 2943 if (err < 0)
2900 return err; 2944 return err;
2901 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2); 2945 err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2);
2902 if (err < 0) 2946 if (err < 0)
2903 return err; 2947 return err;
2904 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1); 2948 err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1);
2905 if (err < 0) 2949 if (err < 0)
2906 return err; 2950 return err;
2907 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2); 2951 err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2);
2908 if (err < 0) 2952 if (err < 0)
2909 return err; 2953 return err;
2910 } else { 2954 } else {
2911 err = alc_auto_add_stereo_vol(codec, name, index, nid); 2955 err = alc_auto_add_stereo_vol(codec, name, index, vol);
2912 if (err < 0) 2956 if (err < 0)
2913 return err; 2957 return err;
2914 err = alc_auto_add_stereo_sw(codec, name, index, mix); 2958 err = alc_auto_add_stereo_sw(codec, name, index, sw);
2915 if (err < 0) 2959 if (err < 0)
2916 return err; 2960 return err;
2917 } 2961 }
@@ -2924,7 +2968,7 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2924 hda_nid_t dac, const char *pfx) 2968 hda_nid_t dac, const char *pfx)
2925{ 2969{
2926 struct alc_spec *spec = codec->spec; 2970 struct alc_spec *spec = codec->spec;
2927 hda_nid_t mix; 2971 hda_nid_t sw, vol;
2928 int err; 2972 int err;
2929 2973
2930 if (!pin) 2974 if (!pin)
@@ -2938,13 +2982,12 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2938 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2982 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2939 } 2983 }
2940 2984
2941 mix = alc_auto_dac_to_mix(codec, pin, dac); 2985 sw = alc_look_for_out_mute_nid(codec, pin, dac);
2942 if (!mix) 2986 vol = alc_look_for_out_vol_nid(codec, pin, dac);
2943 return 0; 2987 err = alc_auto_add_stereo_vol(codec, pfx, 0, vol);
2944 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
2945 if (err < 0) 2988 if (err < 0)
2946 return err; 2989 return err;
2947 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix); 2990 err = alc_auto_add_stereo_sw(codec, pfx, 0, sw);
2948 if (err < 0) 2991 if (err < 0)
2949 return err; 2992 return err;
2950 return 0; 2993 return 0;
@@ -2967,15 +3010,15 @@ static int alc_auto_create_speaker_out(struct hda_codec *codec)
2967} 3010}
2968 3011
2969static void alc_auto_set_output_and_unmute(struct hda_codec *codec, 3012static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
2970 hda_nid_t nid, int pin_type, 3013 hda_nid_t pin, int pin_type,
2971 hda_nid_t dac) 3014 hda_nid_t dac)
2972{ 3015{
2973 int i, num; 3016 int i, num;
2974 hda_nid_t mix = 0; 3017 hda_nid_t nid, mix = 0;
2975 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 3018 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
2976 3019
2977 alc_set_pin_output(codec, nid, pin_type); 3020 alc_set_pin_output(codec, pin, pin_type);
2978 nid = alc_go_down_to_selector(codec, nid); 3021 nid = alc_go_down_to_selector(codec, pin);
2979 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 3022 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
2980 for (i = 0; i < num; i++) { 3023 for (i = 0; i < num; i++) {
2981 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac) 3024 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
@@ -2990,19 +3033,17 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
2990 if (num > 1) 3033 if (num > 1)
2991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 3034 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
2992 /* unmute mixer widget inputs */ 3035 /* unmute mixer widget inputs */
2993 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3036 if (nid_has_mute(codec, mix, HDA_INPUT)) {
3037 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2994 AMP_IN_UNMUTE(0)); 3038 AMP_IN_UNMUTE(0));
2995 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3039 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2996 AMP_IN_UNMUTE(1)); 3040 AMP_IN_UNMUTE(1));
3041 }
2997 /* initialize volume */ 3042 /* initialize volume */
2998 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS) 3043 nid = alc_look_for_out_vol_nid(codec, pin, dac);
2999 nid = dac; 3044 if (nid)
3000 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS) 3045 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3001 nid = mix; 3046 AMP_OUT_ZERO);
3002 else
3003 return;
3004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3005 AMP_OUT_ZERO);
3006} 3047}
3007 3048
3008static void alc_auto_init_multi_out(struct hda_codec *codec) 3049static void alc_auto_init_multi_out(struct hda_codec *codec)
@@ -6333,112 +6374,7 @@ static int patch_alc899(struct hda_codec *codec)
6333/* 6374/*
6334 * ALC680 support 6375 * ALC680 support
6335 */ 6376 */
6336/* create input playback/capture controls for the given pin */
6337static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
6338 const char *ctlname, int idx)
6339{
6340 hda_nid_t dac;
6341 int err;
6342
6343 switch (nid) {
6344 case 0x14:
6345 dac = 0x02;
6346 break;
6347 case 0x15:
6348 dac = 0x03;
6349 break;
6350 case 0x16:
6351 dac = 0x04;
6352 break;
6353 default:
6354 return 0;
6355 }
6356 if (spec->multiout.dac_nids[0] != dac &&
6357 spec->multiout.dac_nids[1] != dac) {
6358 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
6359 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
6360 HDA_OUTPUT));
6361 if (err < 0)
6362 return err;
6363
6364 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
6365 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
6366
6367 if (err < 0)
6368 return err;
6369 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
6370 }
6371
6372 return 0;
6373}
6374
6375/* add playback controls from the parsed DAC table */
6376static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
6377 const struct auto_pin_cfg *cfg)
6378{
6379 hda_nid_t nid;
6380 int err;
6381
6382 spec->multiout.dac_nids = spec->private_dac_nids;
6383
6384 nid = cfg->line_out_pins[0];
6385 if (nid) {
6386 const char *name;
6387 int index;
6388 name = alc_get_line_out_pfx(spec, 0, true, &index);
6389 err = alc680_new_analog_output(spec, nid, name, 0);
6390 if (err < 0)
6391 return err;
6392 }
6393
6394 nid = cfg->speaker_pins[0];
6395 if (nid) {
6396 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
6397 if (err < 0)
6398 return err;
6399 }
6400 nid = cfg->hp_pins[0];
6401 if (nid) {
6402 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
6403 if (err < 0)
6404 return err;
6405 }
6406
6407 return 0;
6408}
6409
6410static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
6411 hda_nid_t nid, int pin_type)
6412{
6413 alc_set_pin_output(codec, nid, pin_type);
6414}
6415 6377
6416static void alc680_auto_init_multi_out(struct hda_codec *codec)
6417{
6418 struct alc_spec *spec = codec->spec;
6419 hda_nid_t nid = spec->autocfg.line_out_pins[0];
6420 if (nid) {
6421 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6422 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
6423 }
6424}
6425
6426static void alc680_auto_init_hp_out(struct hda_codec *codec)
6427{
6428 struct alc_spec *spec = codec->spec;
6429 hda_nid_t pin;
6430
6431 pin = spec->autocfg.hp_pins[0];
6432 if (pin)
6433 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
6434 pin = spec->autocfg.speaker_pins[0];
6435 if (pin)
6436 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
6437}
6438
6439/*
6440 * BIOS auto configuration
6441 */
6442static int alc680_parse_auto_config(struct hda_codec *codec) 6378static int alc680_parse_auto_config(struct hda_codec *codec)
6443{ 6379{
6444 struct alc_spec *spec = codec->spec; 6380 struct alc_spec *spec = codec->spec;
@@ -6458,7 +6394,20 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
6458 } 6394 }
6459 return 0; /* can't find valid BIOS pin config */ 6395 return 0; /* can't find valid BIOS pin config */
6460 } 6396 }
6461 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 6397
6398 err = alc_auto_fill_dac_nids(codec);
6399 if (err < 0)
6400 return err;
6401
6402 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
6403 if (err < 0)
6404 return err;
6405
6406 err = alc_auto_create_hp_out(codec);
6407 if (err < 0)
6408 return err;
6409
6410 err = alc_auto_create_speaker_out(codec);
6462 if (err < 0) 6411 if (err < 0)
6463 return err; 6412 return err;
6464 6413
@@ -6489,8 +6438,8 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
6489static void alc680_auto_init(struct hda_codec *codec) 6438static void alc680_auto_init(struct hda_codec *codec)
6490{ 6439{
6491 struct alc_spec *spec = codec->spec; 6440 struct alc_spec *spec = codec->spec;
6492 alc680_auto_init_multi_out(codec); 6441 alc_auto_init_multi_out(codec);
6493 alc680_auto_init_hp_out(codec); 6442 alc_auto_init_extra_out(codec);
6494 alc_auto_init_analog_input(codec); 6443 alc_auto_init_analog_input(codec);
6495 alc_auto_init_input_src(codec); 6444 alc_auto_init_input_src(codec);
6496 alc_auto_init_digital(codec); 6445 alc_auto_init_digital(codec);