diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-08-30 07:05:52 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-08-30 07:05:52 -0400 |
commit | 66ceeb6bc2809bef0cfa18b1e22ddad5fc9b58b0 (patch) | |
tree | b170068000a988e8ad084492c103526b6ebe50df /sound | |
parent | c1e0bb92174dd16ffba5be0e4e5fbd366f61ff7f (diff) |
ALSA: hda - Use new inputs[] field to parse input-pins for Realtek codecs
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 208 |
1 files changed, 110 insertions, 98 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 50e0c82fd994..3e0f4816aed7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1265,16 +1265,14 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1265 | int i; | 1265 | int i; |
1266 | 1266 | ||
1267 | /* there must be only two mic inputs exclusively */ | 1267 | /* there must be only two mic inputs exclusively */ |
1268 | for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) | 1268 | for (i = 0; i < cfg->num_inputs; i++) |
1269 | if (cfg->input_pins[i]) | 1269 | if (cfg->inputs[i].type >= AUTO_PIN_LINE) |
1270 | return; | 1270 | return; |
1271 | 1271 | ||
1272 | fixed = ext = 0; | 1272 | fixed = ext = 0; |
1273 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) { | 1273 | for (i = 0; i < cfg->num_inputs; i++) { |
1274 | hda_nid_t nid = cfg->input_pins[i]; | 1274 | hda_nid_t nid = cfg->inputs[i].pin; |
1275 | unsigned int defcfg; | 1275 | unsigned int defcfg; |
1276 | if (!nid) | ||
1277 | return; | ||
1278 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 1276 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
1279 | switch (get_defcfg_connect(defcfg)) { | 1277 | switch (get_defcfg_connect(defcfg)) { |
1280 | case AC_JACK_PORT_FIXED: | 1278 | case AC_JACK_PORT_FIXED: |
@@ -4719,7 +4717,7 @@ static struct snd_kcontrol_new alc880_control_templates[] = { | |||
4719 | 4717 | ||
4720 | /* add dynamic controls */ | 4718 | /* add dynamic controls */ |
4721 | static int add_control(struct alc_spec *spec, int type, const char *name, | 4719 | static int add_control(struct alc_spec *spec, int type, const char *name, |
4722 | unsigned long val) | 4720 | int cidx, unsigned long val) |
4723 | { | 4721 | { |
4724 | struct snd_kcontrol_new *knew; | 4722 | struct snd_kcontrol_new *knew; |
4725 | 4723 | ||
@@ -4731,6 +4729,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
4731 | knew->name = kstrdup(name, GFP_KERNEL); | 4729 | knew->name = kstrdup(name, GFP_KERNEL); |
4732 | if (!knew->name) | 4730 | if (!knew->name) |
4733 | return -ENOMEM; | 4731 | return -ENOMEM; |
4732 | knew->index = cidx; | ||
4734 | if (get_amp_nid_(val)) | 4733 | if (get_amp_nid_(val)) |
4735 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | 4734 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; |
4736 | knew->private_value = val; | 4735 | knew->private_value = val; |
@@ -4739,17 +4738,21 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
4739 | 4738 | ||
4740 | static int add_control_with_pfx(struct alc_spec *spec, int type, | 4739 | static int add_control_with_pfx(struct alc_spec *spec, int type, |
4741 | const char *pfx, const char *dir, | 4740 | const char *pfx, const char *dir, |
4742 | const char *sfx, unsigned long val) | 4741 | const char *sfx, int cidx, unsigned long val) |
4743 | { | 4742 | { |
4744 | char name[32]; | 4743 | char name[32]; |
4745 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); | 4744 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); |
4746 | return add_control(spec, type, name, val); | 4745 | return add_control(spec, type, name, cidx, val); |
4747 | } | 4746 | } |
4748 | 4747 | ||
4749 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ | 4748 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ |
4750 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val) | 4749 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) |
4751 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ | 4750 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ |
4752 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val) | 4751 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) |
4752 | #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ | ||
4753 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) | ||
4754 | #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ | ||
4755 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) | ||
4753 | 4756 | ||
4754 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) | 4757 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) |
4755 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) | 4758 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) |
@@ -4902,16 +4905,16 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
4902 | 4905 | ||
4903 | /* create input playback/capture controls for the given pin */ | 4906 | /* create input playback/capture controls for the given pin */ |
4904 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | 4907 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
4905 | const char *ctlname, | 4908 | const char *ctlname, int ctlidx, |
4906 | int idx, hda_nid_t mix_nid) | 4909 | int idx, hda_nid_t mix_nid) |
4907 | { | 4910 | { |
4908 | int err; | 4911 | int err; |
4909 | 4912 | ||
4910 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, | 4913 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, |
4911 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 4914 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
4912 | if (err < 0) | 4915 | if (err < 0) |
4913 | return err; | 4916 | return err; |
4914 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, | 4917 | err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, |
4915 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 4918 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
4916 | if (err < 0) | 4919 | if (err < 0) |
4917 | return err; | 4920 | return err; |
@@ -4932,21 +4935,26 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, | |||
4932 | { | 4935 | { |
4933 | struct alc_spec *spec = codec->spec; | 4936 | struct alc_spec *spec = codec->spec; |
4934 | struct hda_input_mux *imux = &spec->private_imux[0]; | 4937 | struct hda_input_mux *imux = &spec->private_imux[0]; |
4935 | int i, err, idx; | 4938 | int i, err, idx, type, type_idx = 0; |
4936 | 4939 | ||
4937 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4940 | for (i = 0; i < cfg->num_inputs; i++) { |
4938 | hda_nid_t pin; | 4941 | hda_nid_t pin; |
4939 | 4942 | ||
4940 | pin = cfg->input_pins[i]; | 4943 | pin = cfg->inputs[i].pin; |
4941 | if (!alc_is_input_pin(codec, pin)) | 4944 | if (!alc_is_input_pin(codec, pin)) |
4942 | continue; | 4945 | continue; |
4943 | 4946 | ||
4947 | type = cfg->inputs[i].type; | ||
4948 | if (i > 0 && type == cfg->inputs[i - 1].type) | ||
4949 | type_idx++; | ||
4950 | else | ||
4951 | type_idx = 0; | ||
4944 | if (mixer) { | 4952 | if (mixer) { |
4945 | idx = get_connection_index(codec, mixer, pin); | 4953 | idx = get_connection_index(codec, mixer, pin); |
4946 | if (idx >= 0) { | 4954 | if (idx >= 0) { |
4947 | err = new_analog_input(spec, pin, | 4955 | err = new_analog_input(spec, pin, |
4948 | auto_pin_cfg_labels[i], | 4956 | auto_pin_cfg_labels[type], |
4949 | idx, mixer); | 4957 | type_idx, idx, mixer); |
4950 | if (err < 0) | 4958 | if (err < 0) |
4951 | return err; | 4959 | return err; |
4952 | } | 4960 | } |
@@ -4959,7 +4967,7 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, | |||
4959 | idx = get_connection_index(codec, cap2, pin); | 4967 | idx = get_connection_index(codec, cap2, pin); |
4960 | if (idx >= 0) { | 4968 | if (idx >= 0) { |
4961 | imux->items[imux->num_items].label = | 4969 | imux->items[imux->num_items].label = |
4962 | auto_pin_cfg_labels[i]; | 4970 | snd_hda_get_input_pin_label(cfg, i); |
4963 | imux->items[imux->num_items].index = idx; | 4971 | imux->items[imux->num_items].index = idx; |
4964 | imux->num_items++; | 4972 | imux->num_items++; |
4965 | } | 4973 | } |
@@ -5034,10 +5042,11 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec) | |||
5034 | static void alc880_auto_init_analog_input(struct hda_codec *codec) | 5042 | static void alc880_auto_init_analog_input(struct hda_codec *codec) |
5035 | { | 5043 | { |
5036 | struct alc_spec *spec = codec->spec; | 5044 | struct alc_spec *spec = codec->spec; |
5045 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
5037 | int i; | 5046 | int i; |
5038 | 5047 | ||
5039 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5048 | for (i = 0; i < cfg->num_inputs; i++) { |
5040 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5049 | hda_nid_t nid = cfg->inputs[i].pin; |
5041 | if (alc_is_input_pin(codec, nid)) { | 5050 | if (alc_is_input_pin(codec, nid)) { |
5042 | alc_set_input_pin(codec, nid, i); | 5051 | alc_set_input_pin(codec, nid, i); |
5043 | if (nid != ALC880_PIN_CD_NID && | 5052 | if (nid != ALC880_PIN_CD_NID && |
@@ -5204,19 +5213,13 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | |||
5204 | static void fixup_single_adc(struct hda_codec *codec) | 5213 | static void fixup_single_adc(struct hda_codec *codec) |
5205 | { | 5214 | { |
5206 | struct alc_spec *spec = codec->spec; | 5215 | struct alc_spec *spec = codec->spec; |
5207 | hda_nid_t pin = 0; | 5216 | struct auto_pin_cfg *cfg = &spec->autocfg; |
5208 | int i; | 5217 | int i; |
5209 | 5218 | ||
5210 | /* search for the input pin; there must be only one */ | 5219 | /* search for the input pin; there must be only one */ |
5211 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5220 | if (cfg->num_inputs != 1) |
5212 | if (spec->autocfg.input_pins[i]) { | ||
5213 | pin = spec->autocfg.input_pins[i]; | ||
5214 | break; | ||
5215 | } | ||
5216 | } | ||
5217 | if (!pin) | ||
5218 | return; | 5221 | return; |
5219 | i = init_capsrc_for_pin(codec, pin); | 5222 | i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); |
5220 | if (i >= 0) { | 5223 | if (i >= 0) { |
5221 | /* use only this ADC */ | 5224 | /* use only this ADC */ |
5222 | if (spec->capsrc_nids) | 5225 | if (spec->capsrc_nids) |
@@ -5269,6 +5272,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5269 | int num_nids) | 5272 | int num_nids) |
5270 | { | 5273 | { |
5271 | struct alc_spec *spec = codec->spec; | 5274 | struct alc_spec *spec = codec->spec; |
5275 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
5272 | int n; | 5276 | int n; |
5273 | hda_nid_t fallback_adc = 0, fallback_cap = 0; | 5277 | hda_nid_t fallback_adc = 0, fallback_cap = 0; |
5274 | 5278 | ||
@@ -5294,10 +5298,8 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5294 | fallback_adc = adc; | 5298 | fallback_adc = adc; |
5295 | fallback_cap = cap; | 5299 | fallback_cap = cap; |
5296 | } | 5300 | } |
5297 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5301 | for (i = 0; i < cfg->num_inputs; i++) { |
5298 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5302 | hda_nid_t nid = cfg->inputs[i].pin; |
5299 | if (!nid) | ||
5300 | continue; | ||
5301 | for (j = 0; j < nconns; j++) { | 5303 | for (j = 0; j < nconns; j++) { |
5302 | if (conn[j] == nid) | 5304 | if (conn[j] == nid) |
5303 | break; | 5305 | break; |
@@ -5305,7 +5307,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5305 | if (j >= nconns) | 5307 | if (j >= nconns) |
5306 | break; | 5308 | break; |
5307 | } | 5309 | } |
5308 | if (i >= AUTO_PIN_LAST) { | 5310 | if (i >= cfg->num_inputs) { |
5309 | int num_adcs = spec->num_adc_nids; | 5311 | int num_adcs = spec->num_adc_nids; |
5310 | spec->private_adc_nids[num_adcs] = adc; | 5312 | spec->private_adc_nids[num_adcs] = adc; |
5311 | spec->private_capsrc_nids[num_adcs] = cap; | 5313 | spec->private_capsrc_nids[num_adcs] = cap; |
@@ -6672,10 +6674,11 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
6672 | static void alc260_auto_init_analog_input(struct hda_codec *codec) | 6674 | static void alc260_auto_init_analog_input(struct hda_codec *codec) |
6673 | { | 6675 | { |
6674 | struct alc_spec *spec = codec->spec; | 6676 | struct alc_spec *spec = codec->spec; |
6677 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
6675 | int i; | 6678 | int i; |
6676 | 6679 | ||
6677 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 6680 | for (i = 0; i < cfg->num_inputs; i++) { |
6678 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 6681 | hda_nid_t nid = cfg->inputs[i].pin; |
6679 | if (nid >= 0x12) { | 6682 | if (nid >= 0x12) { |
6680 | alc_set_input_pin(codec, nid, i); | 6683 | alc_set_input_pin(codec, nid, i); |
6681 | if (nid != ALC260_PIN_CD_NID && | 6684 | if (nid != ALC260_PIN_CD_NID && |
@@ -10538,12 +10541,11 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) | |||
10538 | static void alc882_auto_init_analog_input(struct hda_codec *codec) | 10541 | static void alc882_auto_init_analog_input(struct hda_codec *codec) |
10539 | { | 10542 | { |
10540 | struct alc_spec *spec = codec->spec; | 10543 | struct alc_spec *spec = codec->spec; |
10544 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
10541 | int i; | 10545 | int i; |
10542 | 10546 | ||
10543 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 10547 | for (i = 0; i < cfg->num_inputs; i++) { |
10544 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 10548 | hda_nid_t nid = cfg->inputs[i].pin; |
10545 | if (!nid) | ||
10546 | continue; | ||
10547 | alc_set_input_pin(codec, nid, i); | 10549 | alc_set_input_pin(codec, nid, i); |
10548 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | 10550 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) |
10549 | snd_hda_codec_write(codec, nid, 0, | 10551 | snd_hda_codec_write(codec, nid, 0, |
@@ -10606,24 +10608,23 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) | |||
10606 | static int alc_auto_add_mic_boost(struct hda_codec *codec) | 10608 | static int alc_auto_add_mic_boost(struct hda_codec *codec) |
10607 | { | 10609 | { |
10608 | struct alc_spec *spec = codec->spec; | 10610 | struct alc_spec *spec = codec->spec; |
10609 | int err; | 10611 | struct auto_pin_cfg *cfg = &spec->autocfg; |
10612 | int i, err; | ||
10610 | hda_nid_t nid; | 10613 | hda_nid_t nid; |
10611 | 10614 | ||
10612 | nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; | 10615 | for (i = 0; i < cfg->num_inputs; i++) { |
10613 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { | 10616 | if (cfg->inputs[i].type > AUTO_PIN_FRONT_MIC) |
10614 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 10617 | break; |
10615 | "Mic Boost", | 10618 | nid = cfg->inputs[i].pin; |
10616 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10619 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { |
10617 | if (err < 0) | 10620 | char label[32]; |
10618 | return err; | 10621 | snprintf(label, sizeof(label), "%s Boost", |
10619 | } | 10622 | snd_hda_get_input_pin_label(cfg, i)); |
10620 | nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; | 10623 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, |
10621 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { | ||
10622 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
10623 | "Front Mic Boost", | ||
10624 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10624 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
10625 | if (err < 0) | 10625 | if (err < 0) |
10626 | return err; | 10626 | return err; |
10627 | } | ||
10627 | } | 10628 | } |
10628 | return 0; | 10629 | return 0; |
10629 | } | 10630 | } |
@@ -15577,10 +15578,11 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) | |||
15577 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 15578 | static void alc861_auto_init_analog_input(struct hda_codec *codec) |
15578 | { | 15579 | { |
15579 | struct alc_spec *spec = codec->spec; | 15580 | struct alc_spec *spec = codec->spec; |
15581 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
15580 | int i; | 15582 | int i; |
15581 | 15583 | ||
15582 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 15584 | for (i = 0; i < cfg->num_inputs; i++) { |
15583 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 15585 | hda_nid_t nid = cfg->inputs[i].pin; |
15584 | if (nid >= 0x0c && nid <= 0x11) | 15586 | if (nid >= 0x0c && nid <= 0x11) |
15585 | alc_set_input_pin(codec, nid, i); | 15587 | alc_set_input_pin(codec, nid, i); |
15586 | } | 15588 | } |
@@ -16569,10 +16571,11 @@ static void alc861vd_auto_init_hp_out(struct hda_codec *codec) | |||
16569 | static void alc861vd_auto_init_analog_input(struct hda_codec *codec) | 16571 | static void alc861vd_auto_init_analog_input(struct hda_codec *codec) |
16570 | { | 16572 | { |
16571 | struct alc_spec *spec = codec->spec; | 16573 | struct alc_spec *spec = codec->spec; |
16574 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
16572 | int i; | 16575 | int i; |
16573 | 16576 | ||
16574 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 16577 | for (i = 0; i < cfg->num_inputs; i++) { |
16575 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 16578 | hda_nid_t nid = cfg->inputs[i].pin; |
16576 | if (alc_is_input_pin(codec, nid)) { | 16579 | if (alc_is_input_pin(codec, nid)) { |
16577 | alc_set_input_pin(codec, nid, i); | 16580 | alc_set_input_pin(codec, nid, i); |
16578 | if (nid != ALC861VD_PIN_CD_NID && | 16581 | if (nid != ALC861VD_PIN_CD_NID && |
@@ -18805,10 +18808,11 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) | |||
18805 | static void alc662_auto_init_analog_input(struct hda_codec *codec) | 18808 | static void alc662_auto_init_analog_input(struct hda_codec *codec) |
18806 | { | 18809 | { |
18807 | struct alc_spec *spec = codec->spec; | 18810 | struct alc_spec *spec = codec->spec; |
18811 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
18808 | int i; | 18812 | int i; |
18809 | 18813 | ||
18810 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 18814 | for (i = 0; i < cfg->num_inputs; i++) { |
18811 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 18815 | hda_nid_t nid = cfg->inputs[i].pin; |
18812 | if (alc_is_input_pin(codec, nid)) { | 18816 | if (alc_is_input_pin(codec, nid)) { |
18813 | alc_set_input_pin(codec, nid, i); | 18817 | alc_set_input_pin(codec, nid, i); |
18814 | if (nid != ALC662_PIN_CD_NID && | 18818 | if (nid != ALC662_PIN_CD_NID && |
@@ -19037,6 +19041,39 @@ static hda_nid_t alc680_adc_nids[3] = { | |||
19037 | /* | 19041 | /* |
19038 | * Analog capture ADC cgange | 19042 | * Analog capture ADC cgange |
19039 | */ | 19043 | */ |
19044 | static void alc680_rec_autoswitch(struct hda_codec *codec) | ||
19045 | { | ||
19046 | struct alc_spec *spec = codec->spec; | ||
19047 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19048 | int pin_found = 0; | ||
19049 | int type_found = AUTO_PIN_LAST; | ||
19050 | hda_nid_t nid; | ||
19051 | int i; | ||
19052 | |||
19053 | for (i = 0; i < cfg->num_inputs; i++) { | ||
19054 | nid = cfg->inputs[i].pin; | ||
19055 | if (!(snd_hda_query_pin_caps(codec, nid) & | ||
19056 | AC_PINCAP_PRES_DETECT)) | ||
19057 | continue; | ||
19058 | if (snd_hda_jack_detect(codec, nid)) { | ||
19059 | if (cfg->inputs[i].type < type_found) { | ||
19060 | type_found = cfg->inputs[i].type; | ||
19061 | pin_found = nid; | ||
19062 | } | ||
19063 | } | ||
19064 | } | ||
19065 | |||
19066 | nid = 0x07; | ||
19067 | if (pin_found) | ||
19068 | snd_hda_get_connections(codec, pin_found, &nid, 1); | ||
19069 | |||
19070 | if (nid != spec->cur_adc) | ||
19071 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
19072 | spec->cur_adc = nid; | ||
19073 | snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, | ||
19074 | spec->cur_adc_format); | ||
19075 | } | ||
19076 | |||
19040 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | 19077 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, |
19041 | struct hda_codec *codec, | 19078 | struct hda_codec *codec, |
19042 | unsigned int stream_tag, | 19079 | unsigned int stream_tag, |
@@ -19044,24 +19081,12 @@ static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
19044 | struct snd_pcm_substream *substream) | 19081 | struct snd_pcm_substream *substream) |
19045 | { | 19082 | { |
19046 | struct alc_spec *spec = codec->spec; | 19083 | struct alc_spec *spec = codec->spec; |
19047 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19048 | unsigned int pre_mic, pre_line; | ||
19049 | |||
19050 | pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | ||
19051 | pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]); | ||
19052 | 19084 | ||
19085 | spec->cur_adc = 0x07; | ||
19053 | spec->cur_adc_stream_tag = stream_tag; | 19086 | spec->cur_adc_stream_tag = stream_tag; |
19054 | spec->cur_adc_format = format; | 19087 | spec->cur_adc_format = format; |
19055 | 19088 | ||
19056 | if (pre_mic || pre_line) { | 19089 | alc680_rec_autoswitch(codec); |
19057 | if (pre_mic) | ||
19058 | snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0, | ||
19059 | format); | ||
19060 | else | ||
19061 | snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0, | ||
19062 | format); | ||
19063 | } else | ||
19064 | snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format); | ||
19065 | return 0; | 19090 | return 0; |
19066 | } | 19091 | } |
19067 | 19092 | ||
@@ -19147,6 +19172,7 @@ static struct hda_verb alc680_init_verbs[] = { | |||
19147 | 19172 | ||
19148 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 19173 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
19149 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | 19174 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, |
19175 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | ||
19150 | 19176 | ||
19151 | { } | 19177 | { } |
19152 | }; | 19178 | }; |
@@ -19159,25 +19185,11 @@ static void alc680_base_setup(struct hda_codec *codec) | |||
19159 | spec->autocfg.hp_pins[0] = 0x16; | 19185 | spec->autocfg.hp_pins[0] = 0x16; |
19160 | spec->autocfg.speaker_pins[0] = 0x14; | 19186 | spec->autocfg.speaker_pins[0] = 0x14; |
19161 | spec->autocfg.speaker_pins[1] = 0x15; | 19187 | spec->autocfg.speaker_pins[1] = 0x15; |
19162 | spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18; | 19188 | spec->autocfg.num_inputs = 2; |
19163 | spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19; | 19189 | spec->autocfg.inputs[0].pin = 0x18; |
19164 | } | 19190 | spec->autocfg.inputs[0].type = AUTO_PIN_MIC; |
19165 | 19191 | spec->autocfg.inputs[1].pin = 0x19; | |
19166 | static void alc680_rec_autoswitch(struct hda_codec *codec) | 19192 | spec->autocfg.inputs[1].type = AUTO_PIN_LINE; |
19167 | { | ||
19168 | struct alc_spec *spec = codec->spec; | ||
19169 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19170 | unsigned int present; | ||
19171 | hda_nid_t new_adc; | ||
19172 | |||
19173 | present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | ||
19174 | |||
19175 | new_adc = present ? 0x8 : 0x7; | ||
19176 | __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1); | ||
19177 | snd_hda_codec_setup_stream(codec, new_adc, | ||
19178 | spec->cur_adc_stream_tag, 0, | ||
19179 | spec->cur_adc_format); | ||
19180 | |||
19181 | } | 19193 | } |
19182 | 19194 | ||
19183 | static void alc680_unsol_event(struct hda_codec *codec, | 19195 | static void alc680_unsol_event(struct hda_codec *codec, |