diff options
| -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) |
