diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bc55c1e96df5..22aea7b089c6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4984,6 +4984,69 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4984 | } | 4984 | } |
4985 | } | 4985 | } |
4986 | 4986 | ||
4987 | /* fill adc_nids (and capsrc_nids) containing all active input pins */ | ||
4988 | static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | ||
4989 | int num_nids) | ||
4990 | { | ||
4991 | struct alc_spec *spec = codec->spec; | ||
4992 | int n; | ||
4993 | hda_nid_t fallback_adc = 0, fallback_cap = 0; | ||
4994 | |||
4995 | for (n = 0; n < num_nids; n++) { | ||
4996 | hda_nid_t adc, cap; | ||
4997 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
4998 | int nconns, i, j; | ||
4999 | |||
5000 | adc = nids[n]; | ||
5001 | if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) | ||
5002 | continue; | ||
5003 | cap = adc; | ||
5004 | nconns = snd_hda_get_connections(codec, cap, conn, | ||
5005 | ARRAY_SIZE(conn)); | ||
5006 | if (nconns == 1) { | ||
5007 | cap = conn[0]; | ||
5008 | nconns = snd_hda_get_connections(codec, cap, conn, | ||
5009 | ARRAY_SIZE(conn)); | ||
5010 | } | ||
5011 | if (nconns <= 0) | ||
5012 | continue; | ||
5013 | if (!fallback_adc) { | ||
5014 | fallback_adc = adc; | ||
5015 | fallback_cap = cap; | ||
5016 | } | ||
5017 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
5018 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
5019 | if (!nid) | ||
5020 | continue; | ||
5021 | for (j = 0; j < nconns; j++) { | ||
5022 | if (conn[j] == nid) | ||
5023 | break; | ||
5024 | } | ||
5025 | if (j >= nconns) | ||
5026 | break; | ||
5027 | } | ||
5028 | if (i >= AUTO_PIN_LAST) { | ||
5029 | int num_adcs = spec->num_adc_nids; | ||
5030 | spec->private_adc_nids[num_adcs] = adc; | ||
5031 | spec->private_capsrc_nids[num_adcs] = cap; | ||
5032 | spec->num_adc_nids++; | ||
5033 | spec->adc_nids = spec->private_adc_nids; | ||
5034 | if (adc != cap) | ||
5035 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
5036 | } | ||
5037 | } | ||
5038 | if (!spec->num_adc_nids) { | ||
5039 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" | ||
5040 | " using fallback 0x%x\n", fallback_adc); | ||
5041 | spec->private_adc_nids[0] = fallback_adc; | ||
5042 | spec->adc_nids = spec->private_adc_nids; | ||
5043 | if (fallback_adc != fallback_cap) { | ||
5044 | spec->private_capsrc_nids[0] = fallback_cap; | ||
5045 | spec->capsrc_nids = spec->private_adc_nids; | ||
5046 | } | ||
5047 | } | ||
5048 | } | ||
5049 | |||
4987 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 5050 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
4988 | #define set_beep_amp(spec, nid, idx, dir) \ | 5051 | #define set_beep_amp(spec, nid, idx, dir) \ |
4989 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 5052 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
@@ -13333,9 +13396,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { | |||
13333 | 0x22, | 13396 | 0x22, |
13334 | }; | 13397 | }; |
13335 | 13398 | ||
13336 | /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), | 13399 | static hda_nid_t alc269_adc_candidates[] = { |
13337 | * not a mux! | 13400 | 0x08, 0x09, 0x07, |
13338 | */ | 13401 | }; |
13339 | 13402 | ||
13340 | #define alc269_modes alc260_modes | 13403 | #define alc269_modes alc260_modes |
13341 | #define alc269_capture_source alc880_lg_lw_capture_source | 13404 | #define alc269_capture_source alc880_lg_lw_capture_source |
@@ -13842,7 +13905,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13842 | struct alc_spec *spec = codec->spec; | 13905 | struct alc_spec *spec = codec->spec; |
13843 | int err; | 13906 | int err; |
13844 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 13907 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
13845 | hda_nid_t real_capsrc_nids; | ||
13846 | 13908 | ||
13847 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 13909 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
13848 | alc269_ignore); | 13910 | alc269_ignore); |
@@ -13866,18 +13928,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13866 | 13928 | ||
13867 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { | 13929 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { |
13868 | add_verb(spec, alc269vb_init_verbs); | 13930 | add_verb(spec, alc269vb_init_verbs); |
13869 | real_capsrc_nids = alc269vb_capsrc_nids[0]; | ||
13870 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); | 13931 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); |
13871 | } else { | 13932 | } else { |
13872 | add_verb(spec, alc269_init_verbs); | 13933 | add_verb(spec, alc269_init_verbs); |
13873 | real_capsrc_nids = alc269_capsrc_nids[0]; | ||
13874 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 13934 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
13875 | } | 13935 | } |
13876 | 13936 | ||
13877 | spec->num_mux_defs = 1; | 13937 | spec->num_mux_defs = 1; |
13878 | spec->input_mux = &spec->private_imux[0]; | 13938 | spec->input_mux = &spec->private_imux[0]; |
13939 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | ||
13940 | sizeof(alc269_adc_candidates)); | ||
13941 | |||
13879 | /* set default input source */ | 13942 | /* set default input source */ |
13880 | snd_hda_codec_write_cache(codec, real_capsrc_nids, | 13943 | snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], |
13881 | 0, AC_VERB_SET_CONNECT_SEL, | 13944 | 0, AC_VERB_SET_CONNECT_SEL, |
13882 | spec->input_mux->items[0].index); | 13945 | spec->input_mux->items[0].index); |
13883 | 13946 | ||
@@ -14156,14 +14219,16 @@ static int patch_alc269(struct hda_codec *codec) | |||
14156 | spec->stream_digital_playback = &alc269_pcm_digital_playback; | 14219 | spec->stream_digital_playback = &alc269_pcm_digital_playback; |
14157 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 14220 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
14158 | 14221 | ||
14159 | if (!is_alc269vb) { | 14222 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ |
14160 | spec->adc_nids = alc269_adc_nids; | 14223 | if (!is_alc269vb) { |
14161 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 14224 | spec->adc_nids = alc269_adc_nids; |
14162 | spec->capsrc_nids = alc269_capsrc_nids; | 14225 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
14163 | } else { | 14226 | spec->capsrc_nids = alc269_capsrc_nids; |
14164 | spec->adc_nids = alc269vb_adc_nids; | 14227 | } else { |
14165 | spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); | 14228 | spec->adc_nids = alc269vb_adc_nids; |
14166 | spec->capsrc_nids = alc269vb_capsrc_nids; | 14229 | spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); |
14230 | spec->capsrc_nids = alc269vb_capsrc_nids; | ||
14231 | } | ||
14167 | } | 14232 | } |
14168 | 14233 | ||
14169 | if (!spec->cap_mixer) | 14234 | if (!spec->cap_mixer) |