diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-07-08 09:14:19 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-08 09:14:19 -0400 |
commit | 44c0240052892911d9ebcb2bbc2a5cfc3176077c (patch) | |
tree | 2c5ace762ec6c5e6cff11480eaad3ac783cf0062 /sound/pci/hda/patch_realtek.c | |
parent | a1f649d5475f6fa7ea5707510ec8b2e3019f38dd (diff) |
ALSA: hda - Fix amp-cap checks in patch_realtek.c
query_amp_caps() may return non-zero if the amp cap isn't supported
by the codec. Thus one needs to check widget-caps first, then check
the corresponding amp-caps.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3b2964e0ce07..db9df5759103 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -206,6 +206,22 @@ struct alc_spec { | |||
206 | 206 | ||
207 | #define ALC_MODEL_AUTO 0 /* common for all chips */ | 207 | #define ALC_MODEL_AUTO 0 /* common for all chips */ |
208 | 208 | ||
209 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, | ||
210 | int dir, unsigned int bits) | ||
211 | { | ||
212 | if (!nid) | ||
213 | return false; | ||
214 | if (get_wcaps(codec, nid) & (1 << (dir + 1))) | ||
215 | if (query_amp_caps(codec, nid, dir) & bits) | ||
216 | return true; | ||
217 | return false; | ||
218 | } | ||
219 | |||
220 | #define nid_has_mute(codec, nid, dir) \ | ||
221 | check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) | ||
222 | #define nid_has_volume(codec, nid, dir) \ | ||
223 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) | ||
224 | |||
209 | /* | 225 | /* |
210 | * input MUX handling | 226 | * input MUX handling |
211 | */ | 227 | */ |
@@ -2637,7 +2653,8 @@ static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, | |||
2637 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 2653 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
2638 | pin_type); | 2654 | pin_type); |
2639 | /* unmute pin */ | 2655 | /* unmute pin */ |
2640 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 2656 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) |
2657 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
2641 | AMP_OUT_UNMUTE); | 2658 | AMP_OUT_UNMUTE); |
2642 | } | 2659 | } |
2643 | 2660 | ||
@@ -2878,11 +2895,6 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec, | |||
2878 | #define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \ | 2895 | #define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \ |
2879 | alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3) | 2896 | alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3) |
2880 | 2897 | ||
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 | |||
2886 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, | 2898 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, |
2887 | hda_nid_t pin, hda_nid_t dac) | 2899 | hda_nid_t pin, hda_nid_t dac) |
2888 | { | 2900 | { |
@@ -3310,7 +3322,7 @@ static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx) | |||
3310 | 3322 | ||
3311 | nid = spec->adc_nids[adc_idx]; | 3323 | nid = spec->adc_nids[adc_idx]; |
3312 | /* mute ADC */ | 3324 | /* mute ADC */ |
3313 | if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) { | 3325 | if (nid_has_mute(codec, nid, HDA_INPUT)) { |
3314 | snd_hda_codec_write(codec, nid, 0, | 3326 | snd_hda_codec_write(codec, nid, 0, |
3315 | AC_VERB_SET_AMP_GAIN_MUTE, | 3327 | AC_VERB_SET_AMP_GAIN_MUTE, |
3316 | AMP_IN_MUTE(0)); | 3328 | AMP_IN_MUTE(0)); |
@@ -3319,7 +3331,7 @@ static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx) | |||
3319 | if (!spec->capsrc_nids) | 3331 | if (!spec->capsrc_nids) |
3320 | return; | 3332 | return; |
3321 | nid = spec->capsrc_nids[adc_idx]; | 3333 | nid = spec->capsrc_nids[adc_idx]; |
3322 | if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) | 3334 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) |
3323 | snd_hda_codec_write(codec, nid, 0, | 3335 | snd_hda_codec_write(codec, nid, 0, |
3324 | AC_VERB_SET_AMP_GAIN_MUTE, | 3336 | AC_VERB_SET_AMP_GAIN_MUTE, |
3325 | AMP_OUT_MUTE); | 3337 | AMP_OUT_MUTE); |
@@ -3436,12 +3448,10 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
3436 | }; | 3448 | }; |
3437 | 3449 | ||
3438 | /* check whether either of ADC or MUX has a volume control */ | 3450 | /* check whether either of ADC or MUX has a volume control */ |
3439 | if (!(query_amp_caps(codec, spec->adc_nids[0], HDA_INPUT) & | 3451 | if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) { |
3440 | AC_AMPCAP_NUM_STEPS)) { | ||
3441 | if (!spec->capsrc_nids) | 3452 | if (!spec->capsrc_nids) |
3442 | return; /* no volume */ | 3453 | return; /* no volume */ |
3443 | if (!(query_amp_caps(codec, spec->capsrc_nids[0], HDA_OUTPUT) & | 3454 | if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT)) |
3444 | AC_AMPCAP_NUM_STEPS)) | ||
3445 | return; /* no volume in capsrc, too */ | 3455 | return; /* no volume in capsrc, too */ |
3446 | spec->vol_in_capsrc = 1; | 3456 | spec->vol_in_capsrc = 1; |
3447 | } | 3457 | } |