diff options
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 105 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.h | 5 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 7 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 24 | ||||
| -rw-r--r-- | sound/pci/hda/patch_analog.c | 117 | ||||
| -rw-r--r-- | sound/pci/hda/patch_conexant.c | 124 | ||||
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 22 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 204 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 318 |
9 files changed, 417 insertions, 509 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ae5c5d5e4b7c..2c79e96d0324 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <sound/asoundef.h> | 29 | #include <sound/asoundef.h> |
| 30 | #include <sound/tlv.h> | 30 | #include <sound/tlv.h> |
| 31 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
| 32 | #include <sound/jack.h> | ||
| 32 | #include "hda_local.h" | 33 | #include "hda_local.h" |
| 33 | #include "hda_beep.h" | 34 | #include "hda_beep.h" |
| 34 | #include <sound/hda_hwdep.h> | 35 | #include <sound/hda_hwdep.h> |
| @@ -4959,5 +4960,109 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) | |||
| 4959 | } | 4960 | } |
| 4960 | EXPORT_SYMBOL_HDA(snd_print_pcm_bits); | 4961 | EXPORT_SYMBOL_HDA(snd_print_pcm_bits); |
| 4961 | 4962 | ||
| 4963 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 4964 | /* | ||
| 4965 | * Input-jack notification support | ||
| 4966 | */ | ||
| 4967 | struct hda_jack_item { | ||
| 4968 | hda_nid_t nid; | ||
| 4969 | int type; | ||
| 4970 | struct snd_jack *jack; | ||
| 4971 | }; | ||
| 4972 | |||
| 4973 | static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, | ||
| 4974 | int type) | ||
| 4975 | { | ||
| 4976 | switch (type) { | ||
| 4977 | case SND_JACK_HEADPHONE: | ||
| 4978 | return "Headphone"; | ||
| 4979 | case SND_JACK_MICROPHONE: | ||
| 4980 | return "Mic"; | ||
| 4981 | case SND_JACK_LINEOUT: | ||
| 4982 | return "Line-out"; | ||
| 4983 | case SND_JACK_HEADSET: | ||
| 4984 | return "Headset"; | ||
| 4985 | default: | ||
| 4986 | return "Misc"; | ||
| 4987 | } | ||
| 4988 | } | ||
| 4989 | |||
| 4990 | static void hda_free_jack_priv(struct snd_jack *jack) | ||
| 4991 | { | ||
| 4992 | struct hda_jack_item *jacks = jack->private_data; | ||
| 4993 | jacks->nid = 0; | ||
| 4994 | jacks->jack = NULL; | ||
| 4995 | } | ||
| 4996 | |||
| 4997 | int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, | ||
| 4998 | const char *name) | ||
| 4999 | { | ||
| 5000 | struct hda_jack_item *jack; | ||
| 5001 | int err; | ||
| 5002 | |||
| 5003 | snd_array_init(&codec->jacks, sizeof(*jack), 32); | ||
| 5004 | jack = snd_array_new(&codec->jacks); | ||
| 5005 | if (!jack) | ||
| 5006 | return -ENOMEM; | ||
| 5007 | |||
| 5008 | jack->nid = nid; | ||
| 5009 | jack->type = type; | ||
| 5010 | if (!name) | ||
| 5011 | name = get_jack_default_name(codec, nid, type); | ||
| 5012 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | ||
| 5013 | if (err < 0) { | ||
| 5014 | jack->nid = 0; | ||
| 5015 | return err; | ||
| 5016 | } | ||
| 5017 | jack->jack->private_data = jack; | ||
| 5018 | jack->jack->private_free = hda_free_jack_priv; | ||
| 5019 | return 0; | ||
| 5020 | } | ||
| 5021 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); | ||
| 5022 | |||
| 5023 | void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) | ||
| 5024 | { | ||
| 5025 | struct hda_jack_item *jacks = codec->jacks.list; | ||
| 5026 | int i; | ||
| 5027 | |||
| 5028 | if (!jacks) | ||
| 5029 | return; | ||
| 5030 | |||
| 5031 | for (i = 0; i < codec->jacks.used; i++, jacks++) { | ||
| 5032 | unsigned int pin_ctl; | ||
| 5033 | unsigned int present; | ||
| 5034 | int type; | ||
| 5035 | |||
| 5036 | if (jacks->nid != nid) | ||
| 5037 | continue; | ||
| 5038 | present = snd_hda_jack_detect(codec, nid); | ||
| 5039 | type = jacks->type; | ||
| 5040 | if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { | ||
| 5041 | pin_ctl = snd_hda_codec_read(codec, nid, 0, | ||
| 5042 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
| 5043 | type = (pin_ctl & AC_PINCTL_HP_EN) ? | ||
| 5044 | SND_JACK_HEADPHONE : SND_JACK_LINEOUT; | ||
| 5045 | } | ||
| 5046 | snd_jack_report(jacks->jack, present ? type : 0); | ||
| 5047 | } | ||
| 5048 | } | ||
| 5049 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); | ||
| 5050 | |||
| 5051 | /* free jack instances manually when clearing/reconfiguring */ | ||
| 5052 | void snd_hda_input_jack_free(struct hda_codec *codec) | ||
| 5053 | { | ||
| 5054 | if (!codec->bus->shutdown && codec->jacks.list) { | ||
| 5055 | struct hda_jack_item *jacks = codec->jacks.list; | ||
| 5056 | int i; | ||
| 5057 | for (i = 0; i < codec->jacks.used; i++, jacks++) { | ||
| 5058 | if (jacks->jack) | ||
| 5059 | snd_device_free(codec->bus->card, jacks->jack); | ||
| 5060 | } | ||
| 5061 | } | ||
| 5062 | snd_array_free(&codec->jacks); | ||
| 5063 | } | ||
| 5064 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_free); | ||
| 5065 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
| 5066 | |||
| 4962 | MODULE_DESCRIPTION("HDA codec core"); | 5067 | MODULE_DESCRIPTION("HDA codec core"); |
| 4963 | MODULE_LICENSE("GPL"); | 5068 | MODULE_LICENSE("GPL"); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index fdf8d44f8b6b..e46d5420a9f2 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -866,6 +866,11 @@ struct hda_codec { | |||
| 866 | /* codec-specific additional proc output */ | 866 | /* codec-specific additional proc output */ |
| 867 | void (*proc_widget_hook)(struct snd_info_buffer *buffer, | 867 | void (*proc_widget_hook)(struct snd_info_buffer *buffer, |
| 868 | struct hda_codec *codec, hda_nid_t nid); | 868 | struct hda_codec *codec, hda_nid_t nid); |
| 869 | |||
| 870 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 871 | /* jack detection */ | ||
| 872 | struct snd_array jacks; | ||
| 873 | #endif | ||
| 869 | }; | 874 | }; |
| 870 | 875 | ||
| 871 | /* direction */ | 876 | /* direction */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fcedad9a5fef..70a9d32f0e96 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -1052,9 +1052,12 @@ static void azx_init_pci(struct azx *chip) | |||
| 1052 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 1052 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
| 1053 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 1053 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
| 1054 | * Ensuring these bits are 0 clears playback static on some HD Audio | 1054 | * Ensuring these bits are 0 clears playback static on some HD Audio |
| 1055 | * codecs | 1055 | * codecs. |
| 1056 | * The PCI register TCSEL is defined in the Intel manuals. | ||
| 1056 | */ | 1057 | */ |
| 1057 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); | 1058 | if (chip->driver_type != AZX_DRIVER_ATI && |
| 1059 | chip->driver_type != AZX_DRIVER_ATIHDMI) | ||
| 1060 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); | ||
| 1058 | 1061 | ||
| 1059 | switch (chip->driver_type) { | 1062 | switch (chip->driver_type) { |
| 1060 | case AZX_DRIVER_ATI: | 1063 | case AZX_DRIVER_ATI: |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 3ab5e7a303db..ff5e2ac2239a 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -656,4 +656,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec, | |||
| 656 | #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 | 656 | #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 |
| 657 | void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); | 657 | void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); |
| 658 | 658 | ||
| 659 | /* | ||
| 660 | * Input-jack notification support | ||
| 661 | */ | ||
| 662 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 663 | int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, | ||
| 664 | const char *name); | ||
| 665 | void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid); | ||
| 666 | void snd_hda_input_jack_free(struct hda_codec *codec); | ||
| 667 | #else /* CONFIG_SND_HDA_INPUT_JACK */ | ||
| 668 | static inline int snd_hda_input_jack_add(struct hda_codec *codec, | ||
| 669 | hda_nid_t nid, int type, | ||
| 670 | const char *name) | ||
| 671 | { | ||
| 672 | return 0; | ||
| 673 | } | ||
| 674 | static inline void snd_hda_input_jack_report(struct hda_codec *codec, | ||
| 675 | hda_nid_t nid) | ||
| 676 | { | ||
| 677 | } | ||
| 678 | static inline void snd_hda_input_jack_free(struct hda_codec *codec) | ||
| 679 | { | ||
| 680 | } | ||
| 681 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
| 682 | |||
| 659 | #endif /* __SOUND_HDA_LOCAL_H */ | 683 | #endif /* __SOUND_HDA_LOCAL_H */ |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 8dabab798689..734c6ee55d8a 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -30,10 +30,10 @@ | |||
| 30 | #include "hda_beep.h" | 30 | #include "hda_beep.h" |
| 31 | 31 | ||
| 32 | struct ad198x_spec { | 32 | struct ad198x_spec { |
| 33 | struct snd_kcontrol_new *mixers[5]; | 33 | struct snd_kcontrol_new *mixers[6]; |
| 34 | int num_mixers; | 34 | int num_mixers; |
| 35 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 35 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
| 36 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 36 | const struct hda_verb *init_verbs[6]; /* initialization verbs |
| 37 | * don't forget NULL termination! | 37 | * don't forget NULL termination! |
| 38 | */ | 38 | */ |
| 39 | unsigned int num_init_verbs; | 39 | unsigned int num_init_verbs; |
| @@ -331,36 +331,11 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
| 331 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 331 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | static int ad198x_alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 335 | struct hda_codec *codec, | ||
| 336 | unsigned int stream_tag, | ||
| 337 | unsigned int format, | ||
| 338 | struct snd_pcm_substream *substream) | ||
| 339 | { | ||
| 340 | struct ad198x_spec *spec = codec->spec; | ||
| 341 | snd_hda_codec_setup_stream(codec, spec->alt_dac_nid[0], stream_tag, | ||
| 342 | 0, format); | ||
| 343 | return 0; | ||
| 344 | } | ||
| 345 | |||
| 346 | static int ad198x_alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 347 | struct hda_codec *codec, | ||
| 348 | struct snd_pcm_substream *substream) | ||
| 349 | { | ||
| 350 | struct ad198x_spec *spec = codec->spec; | ||
| 351 | snd_hda_codec_cleanup_stream(codec, spec->alt_dac_nid[0]); | ||
| 352 | return 0; | ||
| 353 | } | ||
| 354 | |||
| 355 | static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { | 334 | static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { |
| 356 | .substreams = 1, | 335 | .substreams = 1, |
| 357 | .channels_min = 2, | 336 | .channels_min = 2, |
| 358 | .channels_max = 2, | 337 | .channels_max = 2, |
| 359 | /* NID is set in ad198x_build_pcms */ | 338 | /* NID is set in ad198x_build_pcms */ |
| 360 | .ops = { | ||
| 361 | .prepare = ad198x_alt_playback_pcm_prepare, | ||
| 362 | .cleanup = ad198x_alt_playback_pcm_cleanup | ||
| 363 | }, | ||
| 364 | }; | 339 | }; |
| 365 | 340 | ||
| 366 | /* | 341 | /* |
| @@ -2239,29 +2214,6 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { | |||
| 2239 | static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { | 2214 | static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { |
| 2240 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 2215 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
| 2241 | 2216 | ||
| 2242 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | ||
| 2243 | HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), | ||
| 2244 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), | ||
| 2245 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), | ||
| 2246 | HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT), | ||
| 2247 | HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), | ||
| 2248 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), | ||
| 2249 | |||
| 2250 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), | ||
| 2251 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), | ||
| 2252 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), | ||
| 2253 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), | ||
| 2254 | HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), | ||
| 2255 | HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), | ||
| 2256 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), | ||
| 2257 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), | ||
| 2258 | |||
| 2259 | HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), | ||
| 2260 | HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 2261 | |||
| 2262 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), | ||
| 2263 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), | ||
| 2264 | |||
| 2265 | { } /* end */ | 2217 | { } /* end */ |
| 2266 | }; | 2218 | }; |
| 2267 | 2219 | ||
| @@ -2545,11 +2497,6 @@ static struct hda_verb ad1988_6stack_init_verbs[] = { | |||
| 2545 | }; | 2497 | }; |
| 2546 | 2498 | ||
| 2547 | static struct hda_verb ad1988_6stack_fp_init_verbs[] = { | 2499 | static struct hda_verb ad1988_6stack_fp_init_verbs[] = { |
| 2548 | /* Front, Surround, CLFE, side DAC; unmute as default */ | ||
| 2549 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2550 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2551 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2552 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2553 | /* Headphone; unmute as default */ | 2500 | /* Headphone; unmute as default */ |
| 2554 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2501 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2555 | /* Port-A front headphon path */ | 2502 | /* Port-A front headphon path */ |
| @@ -2558,50 +2505,6 @@ static struct hda_verb ad1988_6stack_fp_init_verbs[] = { | |||
| 2558 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2505 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
| 2559 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2506 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2560 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 2507 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
| 2561 | /* Port-D line-out path */ | ||
| 2562 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2563 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2564 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2565 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 2566 | /* Port-F surround path */ | ||
| 2567 | {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2568 | {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2569 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2570 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 2571 | /* Port-G CLFE path */ | ||
| 2572 | {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2573 | {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2574 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2575 | {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 2576 | /* Port-H side path */ | ||
| 2577 | {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2578 | {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2579 | {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2580 | {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 2581 | /* Mono out path */ | ||
| 2582 | {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ | ||
| 2583 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2584 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2585 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 2586 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ | ||
| 2587 | /* Port-B front mic-in path */ | ||
| 2588 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 2589 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 2590 | {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 2591 | /* Port-C line-in path */ | ||
| 2592 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 2593 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 2594 | {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 2595 | {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
| 2596 | /* Port-E mic-in path */ | ||
| 2597 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 2598 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 2599 | {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 2600 | {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
| 2601 | /* Analog CD Input */ | ||
| 2602 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 2603 | /* Analog Mix output amp */ | ||
| 2604 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
| 2605 | 2508 | ||
| 2606 | { } | 2509 | { } |
| 2607 | }; | 2510 | }; |
| @@ -3316,20 +3219,20 @@ static int patch_ad1988(struct hda_codec *codec) | |||
| 3316 | spec->mixers[0] = ad1988_6stack_mixers1_rev2; | 3219 | spec->mixers[0] = ad1988_6stack_mixers1_rev2; |
| 3317 | else | 3220 | else |
| 3318 | spec->mixers[0] = ad1988_6stack_mixers1; | 3221 | spec->mixers[0] = ad1988_6stack_mixers1; |
| 3222 | spec->mixers[1] = ad1988_6stack_mixers2; | ||
| 3223 | spec->num_init_verbs = 1; | ||
| 3224 | spec->init_verbs[0] = ad1988_6stack_init_verbs; | ||
| 3319 | if (board_config == AD1988_6STACK_DIG_FP) { | 3225 | if (board_config == AD1988_6STACK_DIG_FP) { |
| 3320 | spec->mixers[1] = ad1988_6stack_fp_mixers; | 3226 | spec->num_mixers++; |
| 3227 | spec->mixers[2] = ad1988_6stack_fp_mixers; | ||
| 3228 | spec->num_init_verbs++; | ||
| 3229 | spec->init_verbs[1] = ad1988_6stack_fp_init_verbs; | ||
| 3321 | spec->slave_vols = ad1988_6stack_fp_slave_vols; | 3230 | spec->slave_vols = ad1988_6stack_fp_slave_vols; |
| 3322 | spec->slave_sws = ad1988_6stack_fp_slave_sws; | 3231 | spec->slave_sws = ad1988_6stack_fp_slave_sws; |
| 3323 | spec->alt_dac_nid = ad1988_alt_dac_nid; | 3232 | spec->alt_dac_nid = ad1988_alt_dac_nid; |
| 3324 | spec->stream_analog_alt_playback = | 3233 | spec->stream_analog_alt_playback = |
| 3325 | &ad198x_pcm_analog_alt_playback; | 3234 | &ad198x_pcm_analog_alt_playback; |
| 3326 | } else | 3235 | } |
| 3327 | spec->mixers[1] = ad1988_6stack_mixers2; | ||
| 3328 | spec->num_init_verbs = 1; | ||
| 3329 | if (board_config == AD1988_6STACK_DIG_FP) | ||
| 3330 | spec->init_verbs[0] = ad1988_6stack_fp_init_verbs; | ||
| 3331 | else | ||
| 3332 | spec->init_verbs[0] = ad1988_6stack_init_verbs; | ||
| 3333 | if ((board_config == AD1988_6STACK_DIG) || | 3236 | if ((board_config == AD1988_6STACK_DIG) || |
| 3334 | (board_config == AD1988_6STACK_DIG_FP)) { | 3237 | (board_config == AD1988_6STACK_DIG_FP)) { |
| 3335 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; | 3238 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4d5004e693f0..d08cf31596f3 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -49,14 +49,6 @@ | |||
| 49 | #define AUTO_MIC_PORTB (1 << 1) | 49 | #define AUTO_MIC_PORTB (1 << 1) |
| 50 | #define AUTO_MIC_PORTC (1 << 2) | 50 | #define AUTO_MIC_PORTC (1 << 2) |
| 51 | 51 | ||
| 52 | struct conexant_jack { | ||
| 53 | |||
| 54 | hda_nid_t nid; | ||
| 55 | int type; | ||
| 56 | struct snd_jack *jack; | ||
| 57 | |||
| 58 | }; | ||
| 59 | |||
| 60 | struct pin_dac_pair { | 52 | struct pin_dac_pair { |
| 61 | hda_nid_t pin; | 53 | hda_nid_t pin; |
| 62 | hda_nid_t dac; | 54 | hda_nid_t dac; |
| @@ -111,9 +103,6 @@ struct conexant_spec { | |||
| 111 | 103 | ||
| 112 | unsigned int spdif_route; | 104 | unsigned int spdif_route; |
| 113 | 105 | ||
| 114 | /* jack detection */ | ||
| 115 | struct snd_array jacks; | ||
| 116 | |||
| 117 | /* dynamic controls, init_verbs and input_mux */ | 106 | /* dynamic controls, init_verbs and input_mux */ |
| 118 | struct auto_pin_cfg autocfg; | 107 | struct auto_pin_cfg autocfg; |
| 119 | struct hda_input_mux private_imux; | 108 | struct hda_input_mux private_imux; |
| @@ -393,71 +382,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
| 393 | &spec->cur_mux[adc_idx]); | 382 | &spec->cur_mux[adc_idx]); |
| 394 | } | 383 | } |
| 395 | 384 | ||
| 396 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 397 | static void conexant_free_jack_priv(struct snd_jack *jack) | ||
| 398 | { | ||
| 399 | struct conexant_jack *jacks = jack->private_data; | ||
| 400 | jacks->nid = 0; | ||
| 401 | jacks->jack = NULL; | ||
| 402 | } | ||
| 403 | |||
| 404 | static int conexant_add_jack(struct hda_codec *codec, | ||
| 405 | hda_nid_t nid, int type) | ||
| 406 | { | ||
| 407 | struct conexant_spec *spec; | ||
| 408 | struct conexant_jack *jack; | ||
| 409 | const char *name; | ||
| 410 | int i, err; | ||
| 411 | |||
| 412 | spec = codec->spec; | ||
| 413 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | ||
| 414 | |||
| 415 | jack = spec->jacks.list; | ||
| 416 | for (i = 0; i < spec->jacks.used; i++, jack++) | ||
| 417 | if (jack->nid == nid) | ||
| 418 | return 0 ; /* already present */ | ||
| 419 | |||
| 420 | jack = snd_array_new(&spec->jacks); | ||
| 421 | name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; | ||
| 422 | |||
| 423 | if (!jack) | ||
| 424 | return -ENOMEM; | ||
| 425 | |||
| 426 | jack->nid = nid; | ||
| 427 | jack->type = type; | ||
| 428 | |||
| 429 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | ||
| 430 | if (err < 0) | ||
| 431 | return err; | ||
| 432 | jack->jack->private_data = jack; | ||
| 433 | jack->jack->private_free = conexant_free_jack_priv; | ||
| 434 | return 0; | ||
| 435 | } | ||
| 436 | |||
| 437 | static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
| 438 | { | ||
| 439 | struct conexant_spec *spec = codec->spec; | ||
| 440 | struct conexant_jack *jacks = spec->jacks.list; | ||
| 441 | |||
| 442 | if (jacks) { | ||
| 443 | int i; | ||
| 444 | for (i = 0; i < spec->jacks.used; i++) { | ||
| 445 | if (jacks->nid == nid) { | ||
| 446 | unsigned int present; | ||
| 447 | present = snd_hda_jack_detect(codec, nid); | ||
| 448 | |||
| 449 | present = (present) ? jacks->type : 0 ; | ||
| 450 | |||
| 451 | snd_jack_report(jacks->jack, | ||
| 452 | present); | ||
| 453 | } | ||
| 454 | jacks++; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | } | ||
| 458 | |||
| 459 | static int conexant_init_jacks(struct hda_codec *codec) | 385 | static int conexant_init_jacks(struct hda_codec *codec) |
| 460 | { | 386 | { |
| 387 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 461 | struct conexant_spec *spec = codec->spec; | 388 | struct conexant_spec *spec = codec->spec; |
| 462 | int i; | 389 | int i; |
| 463 | 390 | ||
| @@ -469,15 +396,15 @@ static int conexant_init_jacks(struct hda_codec *codec) | |||
| 469 | int err = 0; | 396 | int err = 0; |
| 470 | switch (hv->param ^ AC_USRSP_EN) { | 397 | switch (hv->param ^ AC_USRSP_EN) { |
| 471 | case CONEXANT_HP_EVENT: | 398 | case CONEXANT_HP_EVENT: |
| 472 | err = conexant_add_jack(codec, hv->nid, | 399 | err = snd_hda_input_jack_add(codec, hv->nid, |
| 473 | SND_JACK_HEADPHONE); | 400 | SND_JACK_HEADPHONE, NULL); |
| 474 | conexant_report_jack(codec, hv->nid); | 401 | snd_hda_input_jack_report(codec, hv->nid); |
| 475 | break; | 402 | break; |
| 476 | case CXT5051_PORTC_EVENT: | 403 | case CXT5051_PORTC_EVENT: |
| 477 | case CONEXANT_MIC_EVENT: | 404 | case CONEXANT_MIC_EVENT: |
| 478 | err = conexant_add_jack(codec, hv->nid, | 405 | err = snd_hda_input_jack_add(codec, hv->nid, |
| 479 | SND_JACK_MICROPHONE); | 406 | SND_JACK_MICROPHONE, NULL); |
| 480 | conexant_report_jack(codec, hv->nid); | 407 | snd_hda_input_jack_report(codec, hv->nid); |
| 481 | break; | 408 | break; |
| 482 | } | 409 | } |
| 483 | if (err < 0) | 410 | if (err < 0) |
| @@ -485,19 +412,9 @@ static int conexant_init_jacks(struct hda_codec *codec) | |||
| 485 | ++hv; | 412 | ++hv; |
| 486 | } | 413 | } |
| 487 | } | 414 | } |
| 488 | return 0; | 415 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ |
| 489 | |||
| 490 | } | ||
| 491 | #else | ||
| 492 | static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
| 493 | { | ||
| 494 | } | ||
| 495 | |||
| 496 | static inline int conexant_init_jacks(struct hda_codec *codec) | ||
| 497 | { | ||
| 498 | return 0; | 416 | return 0; |
| 499 | } | 417 | } |
| 500 | #endif | ||
| 501 | 418 | ||
| 502 | static int conexant_init(struct hda_codec *codec) | 419 | static int conexant_init(struct hda_codec *codec) |
| 503 | { | 420 | { |
| @@ -511,18 +428,7 @@ static int conexant_init(struct hda_codec *codec) | |||
| 511 | 428 | ||
| 512 | static void conexant_free(struct hda_codec *codec) | 429 | static void conexant_free(struct hda_codec *codec) |
| 513 | { | 430 | { |
| 514 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 431 | snd_hda_input_jack_free(codec); |
| 515 | struct conexant_spec *spec = codec->spec; | ||
| 516 | if (spec->jacks.list) { | ||
| 517 | struct conexant_jack *jacks = spec->jacks.list; | ||
| 518 | int i; | ||
| 519 | for (i = 0; i < spec->jacks.used; i++, jacks++) { | ||
| 520 | if (jacks->jack) | ||
| 521 | snd_device_free(codec->bus->card, jacks->jack); | ||
| 522 | } | ||
| 523 | snd_array_free(&spec->jacks); | ||
| 524 | } | ||
| 525 | #endif | ||
| 526 | snd_hda_detach_beep_device(codec); | 432 | snd_hda_detach_beep_device(codec); |
| 527 | kfree(codec->spec); | 433 | kfree(codec->spec); |
| 528 | } | 434 | } |
| @@ -1787,7 +1693,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, | |||
| 1787 | cxt5051_portc_automic(codec); | 1693 | cxt5051_portc_automic(codec); |
| 1788 | break; | 1694 | break; |
| 1789 | } | 1695 | } |
| 1790 | conexant_report_jack(codec, nid); | 1696 | snd_hda_input_jack_report(codec, nid); |
| 1791 | } | 1697 | } |
| 1792 | 1698 | ||
| 1793 | static struct snd_kcontrol_new cxt5051_playback_mixers[] = { | 1699 | static struct snd_kcontrol_new cxt5051_playback_mixers[] = { |
| @@ -1959,10 +1865,8 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, | |||
| 1959 | snd_hda_codec_write(codec, nid, 0, | 1865 | snd_hda_codec_write(codec, nid, 0, |
| 1960 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1866 | AC_VERB_SET_UNSOLICITED_ENABLE, |
| 1961 | AC_USRSP_EN | event); | 1867 | AC_USRSP_EN | event); |
| 1962 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 1868 | snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL); |
| 1963 | conexant_add_jack(codec, nid, SND_JACK_MICROPHONE); | 1869 | snd_hda_input_jack_report(codec, nid); |
| 1964 | conexant_report_jack(codec, nid); | ||
| 1965 | #endif | ||
| 1966 | } | 1870 | } |
| 1967 | 1871 | ||
| 1968 | static struct hda_verb cxt5051_ideapad_init_verbs[] = { | 1872 | static struct hda_verb cxt5051_ideapad_init_verbs[] = { |
| @@ -3477,11 +3381,11 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) | |||
| 3477 | switch (res >> 26) { | 3381 | switch (res >> 26) { |
| 3478 | case CONEXANT_HP_EVENT: | 3382 | case CONEXANT_HP_EVENT: |
| 3479 | cx_auto_hp_automute(codec); | 3383 | cx_auto_hp_automute(codec); |
| 3480 | conexant_report_jack(codec, nid); | 3384 | snd_hda_input_jack_report(codec, nid); |
| 3481 | break; | 3385 | break; |
| 3482 | case CONEXANT_MIC_EVENT: | 3386 | case CONEXANT_MIC_EVENT: |
| 3483 | cx_auto_automic(codec); | 3387 | cx_auto_automic(codec); |
| 3484 | conexant_report_jack(codec, nid); | 3388 | snd_hda_input_jack_report(codec, nid); |
| 3485 | break; | 3389 | break; |
| 3486 | } | 3390 | } |
| 3487 | } | 3391 | } |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index ec0fa2dd0a27..251773e45f61 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -110,6 +110,12 @@ struct dp_audio_infoframe { | |||
| 110 | u8 LFEPBL01_LSV36_DM_INH7; | 110 | u8 LFEPBL01_LSV36_DM_INH7; |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | union audio_infoframe { | ||
| 114 | struct hdmi_audio_infoframe hdmi; | ||
| 115 | struct dp_audio_infoframe dp; | ||
| 116 | u8 bytes[0]; | ||
| 117 | }; | ||
| 118 | |||
| 113 | /* | 119 | /* |
| 114 | * CEA speaker placement: | 120 | * CEA speaker placement: |
| 115 | * | 121 | * |
| @@ -620,8 +626,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 620 | int channels = substream->runtime->channels; | 626 | int channels = substream->runtime->channels; |
| 621 | int ca; | 627 | int ca; |
| 622 | int i; | 628 | int i; |
| 623 | u8 ai[max(sizeof(struct hdmi_audio_infoframe), | 629 | union audio_infoframe ai; |
| 624 | sizeof(struct dp_audio_infoframe))]; | ||
| 625 | 630 | ||
| 626 | ca = hdmi_channel_allocation(codec, nid, channels); | 631 | ca = hdmi_channel_allocation(codec, nid, channels); |
| 627 | 632 | ||
| @@ -633,11 +638,10 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 633 | 638 | ||
| 634 | pin_nid = spec->pin[i]; | 639 | pin_nid = spec->pin[i]; |
| 635 | 640 | ||
| 636 | memset(ai, 0, sizeof(ai)); | 641 | memset(&ai, 0, sizeof(ai)); |
| 637 | if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ | 642 | if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ |
| 638 | struct hdmi_audio_infoframe *hdmi_ai; | 643 | struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; |
| 639 | 644 | ||
| 640 | hdmi_ai = (struct hdmi_audio_infoframe *)ai; | ||
| 641 | hdmi_ai->type = 0x84; | 645 | hdmi_ai->type = 0x84; |
| 642 | hdmi_ai->ver = 0x01; | 646 | hdmi_ai->ver = 0x01; |
| 643 | hdmi_ai->len = 0x0a; | 647 | hdmi_ai->len = 0x0a; |
| @@ -645,9 +649,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 645 | hdmi_ai->CA = ca; | 649 | hdmi_ai->CA = ca; |
| 646 | hdmi_checksum_audio_infoframe(hdmi_ai); | 650 | hdmi_checksum_audio_infoframe(hdmi_ai); |
| 647 | } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ | 651 | } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ |
| 648 | struct dp_audio_infoframe *dp_ai; | 652 | struct dp_audio_infoframe *dp_ai = &ai.dp; |
| 649 | 653 | ||
| 650 | dp_ai = (struct dp_audio_infoframe *)ai; | ||
| 651 | dp_ai->type = 0x84; | 654 | dp_ai->type = 0x84; |
| 652 | dp_ai->len = 0x1b; | 655 | dp_ai->len = 0x1b; |
| 653 | dp_ai->ver = 0x11 << 2; | 656 | dp_ai->ver = 0x11 << 2; |
| @@ -664,7 +667,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 664 | * sizeof(*dp_ai) to avoid partial match/update problems when | 667 | * sizeof(*dp_ai) to avoid partial match/update problems when |
| 665 | * the user switches between HDMI/DP monitors. | 668 | * the user switches between HDMI/DP monitors. |
| 666 | */ | 669 | */ |
| 667 | if (!hdmi_infoframe_uptodate(codec, pin_nid, ai, sizeof(ai))) { | 670 | if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, |
| 671 | sizeof(ai))) { | ||
| 668 | snd_printdd("hdmi_setup_audio_infoframe: " | 672 | snd_printdd("hdmi_setup_audio_infoframe: " |
| 669 | "cvt=%d pin=%d channels=%d\n", | 673 | "cvt=%d pin=%d channels=%d\n", |
| 670 | nid, pin_nid, | 674 | nid, pin_nid, |
| @@ -672,7 +676,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 672 | hdmi_setup_channel_mapping(codec, pin_nid, ca); | 676 | hdmi_setup_channel_mapping(codec, pin_nid, ca); |
| 673 | hdmi_stop_infoframe_trans(codec, pin_nid); | 677 | hdmi_stop_infoframe_trans(codec, pin_nid); |
| 674 | hdmi_fill_audio_infoframe(codec, pin_nid, | 678 | hdmi_fill_audio_infoframe(codec, pin_nid, |
| 675 | ai, sizeof(ai)); | 679 | ai.bytes, sizeof(ai)); |
| 676 | hdmi_start_infoframe_trans(codec, pin_nid); | 680 | hdmi_start_infoframe_trans(codec, pin_nid); |
| 677 | } | 681 | } |
| 678 | } | 682 | } |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4261bb8eec1d..639d2746713f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -282,12 +282,6 @@ struct alc_mic_route { | |||
| 282 | unsigned char amix_idx; | 282 | unsigned char amix_idx; |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | struct alc_jack { | ||
| 286 | hda_nid_t nid; | ||
| 287 | int type; | ||
| 288 | struct snd_jack *jack; | ||
| 289 | }; | ||
| 290 | |||
| 291 | #define MUX_IDX_UNDEF ((unsigned char)-1) | 285 | #define MUX_IDX_UNDEF ((unsigned char)-1) |
| 292 | 286 | ||
| 293 | struct alc_customize_define { | 287 | struct alc_customize_define { |
| @@ -366,9 +360,6 @@ struct alc_spec { | |||
| 366 | /* PCM information */ | 360 | /* PCM information */ |
| 367 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ | 361 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
| 368 | 362 | ||
| 369 | /* jack detection */ | ||
| 370 | struct snd_array jacks; | ||
| 371 | |||
| 372 | /* dynamic controls, init_verbs and input_mux */ | 363 | /* dynamic controls, init_verbs and input_mux */ |
| 373 | struct auto_pin_cfg autocfg; | 364 | struct auto_pin_cfg autocfg; |
| 374 | struct alc_customize_define cdefine; | 365 | struct alc_customize_define cdefine; |
| @@ -394,6 +385,7 @@ struct alc_spec { | |||
| 394 | /* other flags */ | 385 | /* other flags */ |
| 395 | unsigned int no_analog :1; /* digital I/O only */ | 386 | unsigned int no_analog :1; /* digital I/O only */ |
| 396 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ | 387 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ |
| 388 | unsigned int single_input_src:1; | ||
| 397 | int init_amp; | 389 | int init_amp; |
| 398 | int codec_variant; /* flag for other variants */ | 390 | int codec_variant; /* flag for other variants */ |
| 399 | 391 | ||
| @@ -1032,94 +1024,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
| 1032 | alc_fix_pll(codec); | 1024 | alc_fix_pll(codec); |
| 1033 | } | 1025 | } |
| 1034 | 1026 | ||
| 1035 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 1036 | static void alc_free_jack_priv(struct snd_jack *jack) | ||
| 1037 | { | ||
| 1038 | struct alc_jack *jacks = jack->private_data; | ||
| 1039 | jacks->nid = 0; | ||
| 1040 | jacks->jack = NULL; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | static int alc_add_jack(struct hda_codec *codec, | ||
| 1044 | hda_nid_t nid, int type) | ||
| 1045 | { | ||
| 1046 | struct alc_spec *spec; | ||
| 1047 | struct alc_jack *jack; | ||
| 1048 | const char *name; | ||
| 1049 | int err; | ||
| 1050 | |||
| 1051 | spec = codec->spec; | ||
| 1052 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | ||
| 1053 | jack = snd_array_new(&spec->jacks); | ||
| 1054 | if (!jack) | ||
| 1055 | return -ENOMEM; | ||
| 1056 | |||
| 1057 | jack->nid = nid; | ||
| 1058 | jack->type = type; | ||
| 1059 | name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; | ||
| 1060 | |||
| 1061 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | ||
| 1062 | if (err < 0) | ||
| 1063 | return err; | ||
| 1064 | jack->jack->private_data = jack; | ||
| 1065 | jack->jack->private_free = alc_free_jack_priv; | ||
| 1066 | return 0; | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
| 1070 | { | ||
| 1071 | struct alc_spec *spec = codec->spec; | ||
| 1072 | struct alc_jack *jacks = spec->jacks.list; | ||
| 1073 | |||
| 1074 | if (jacks) { | ||
| 1075 | int i; | ||
| 1076 | for (i = 0; i < spec->jacks.used; i++) { | ||
| 1077 | if (jacks->nid == nid) { | ||
| 1078 | unsigned int present; | ||
| 1079 | present = snd_hda_jack_detect(codec, nid); | ||
| 1080 | |||
| 1081 | present = (present) ? jacks->type : 0; | ||
| 1082 | |||
| 1083 | snd_jack_report(jacks->jack, present); | ||
| 1084 | } | ||
| 1085 | jacks++; | ||
| 1086 | } | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | static int alc_init_jacks(struct hda_codec *codec) | 1027 | static int alc_init_jacks(struct hda_codec *codec) |
| 1091 | { | 1028 | { |
| 1029 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 1092 | struct alc_spec *spec = codec->spec; | 1030 | struct alc_spec *spec = codec->spec; |
| 1093 | int err; | 1031 | int err; |
| 1094 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | 1032 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; |
| 1095 | unsigned int mic_nid = spec->ext_mic.pin; | 1033 | unsigned int mic_nid = spec->ext_mic.pin; |
| 1096 | 1034 | ||
| 1097 | if (hp_nid) { | 1035 | if (hp_nid) { |
| 1098 | err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); | 1036 | err = snd_hda_input_jack_add(codec, hp_nid, |
| 1037 | SND_JACK_HEADPHONE, NULL); | ||
| 1099 | if (err < 0) | 1038 | if (err < 0) |
| 1100 | return err; | 1039 | return err; |
| 1101 | alc_report_jack(codec, hp_nid); | 1040 | snd_hda_input_jack_report(codec, hp_nid); |
| 1102 | } | 1041 | } |
| 1103 | 1042 | ||
| 1104 | if (mic_nid) { | 1043 | if (mic_nid) { |
| 1105 | err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); | 1044 | err = snd_hda_input_jack_add(codec, mic_nid, |
| 1045 | SND_JACK_MICROPHONE, NULL); | ||
| 1106 | if (err < 0) | 1046 | if (err < 0) |
| 1107 | return err; | 1047 | return err; |
| 1108 | alc_report_jack(codec, mic_nid); | 1048 | snd_hda_input_jack_report(codec, mic_nid); |
| 1109 | } | 1049 | } |
| 1110 | 1050 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | |
| 1111 | return 0; | ||
| 1112 | } | ||
| 1113 | #else | ||
| 1114 | static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
| 1115 | { | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | static inline int alc_init_jacks(struct hda_codec *codec) | ||
| 1119 | { | ||
| 1120 | return 0; | 1051 | return 0; |
| 1121 | } | 1052 | } |
| 1122 | #endif | ||
| 1123 | 1053 | ||
| 1124 | static void alc_automute_speaker(struct hda_codec *codec, int pinctl) | 1054 | static void alc_automute_speaker(struct hda_codec *codec, int pinctl) |
| 1125 | { | 1055 | { |
| @@ -1133,7 +1063,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl) | |||
| 1133 | nid = spec->autocfg.hp_pins[i]; | 1063 | nid = spec->autocfg.hp_pins[i]; |
| 1134 | if (!nid) | 1064 | if (!nid) |
| 1135 | break; | 1065 | break; |
| 1136 | alc_report_jack(codec, nid); | 1066 | snd_hda_input_jack_report(codec, nid); |
| 1137 | spec->jack_present |= snd_hda_jack_detect(codec, nid); | 1067 | spec->jack_present |= snd_hda_jack_detect(codec, nid); |
| 1138 | } | 1068 | } |
| 1139 | 1069 | ||
| @@ -1240,7 +1170,7 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
| 1240 | AC_VERB_SET_CONNECT_SEL, | 1170 | AC_VERB_SET_CONNECT_SEL, |
| 1241 | alive->mux_idx); | 1171 | alive->mux_idx); |
| 1242 | } | 1172 | } |
| 1243 | alc_report_jack(codec, spec->ext_mic.pin); | 1173 | snd_hda_input_jack_report(codec, spec->ext_mic.pin); |
| 1244 | 1174 | ||
| 1245 | /* FIXME: analog mixer */ | 1175 | /* FIXME: analog mixer */ |
| 1246 | } | 1176 | } |
| @@ -2292,13 +2222,13 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { | |||
| 2292 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2222 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
| 2293 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2223 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
| 2294 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 2224 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
| 2295 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0, | 2225 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, |
| 2296 | HDA_OUTPUT), | 2226 | HDA_OUTPUT), |
| 2297 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT), | 2227 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
| 2298 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), | 2228 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
| 2299 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), | 2229 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
| 2300 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | 2230 | HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), |
| 2301 | HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT), | 2231 | HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), |
| 2302 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 2232 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
| 2303 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 2233 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
| 2304 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 2234 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
| @@ -2309,7 +2239,6 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { | |||
| 2309 | { } /* end */ | 2239 | { } /* end */ |
| 2310 | }; | 2240 | }; |
| 2311 | 2241 | ||
| 2312 | |||
| 2313 | static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { | 2242 | static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { |
| 2314 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2243 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
| 2315 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2244 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
| @@ -3919,6 +3848,8 @@ static struct hda_amp_list alc880_lg_loopbacks[] = { | |||
| 3919 | * Common callbacks | 3848 | * Common callbacks |
| 3920 | */ | 3849 | */ |
| 3921 | 3850 | ||
| 3851 | static void alc_init_special_input_src(struct hda_codec *codec); | ||
| 3852 | |||
| 3922 | static int alc_init(struct hda_codec *codec) | 3853 | static int alc_init(struct hda_codec *codec) |
| 3923 | { | 3854 | { |
| 3924 | struct alc_spec *spec = codec->spec; | 3855 | struct alc_spec *spec = codec->spec; |
| @@ -3929,6 +3860,7 @@ static int alc_init(struct hda_codec *codec) | |||
| 3929 | 3860 | ||
| 3930 | for (i = 0; i < spec->num_init_verbs; i++) | 3861 | for (i = 0; i < spec->num_init_verbs; i++) |
| 3931 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 3862 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
| 3863 | alc_init_special_input_src(codec); | ||
| 3932 | 3864 | ||
| 3933 | if (spec->init_hook) | 3865 | if (spec->init_hook) |
| 3934 | spec->init_hook(codec); | 3866 | spec->init_hook(codec); |
| @@ -4284,6 +4216,7 @@ static void alc_free(struct hda_codec *codec) | |||
| 4284 | return; | 4216 | return; |
| 4285 | 4217 | ||
| 4286 | alc_shutup(codec); | 4218 | alc_shutup(codec); |
| 4219 | snd_hda_input_jack_free(codec); | ||
| 4287 | alc_free_kctls(codec); | 4220 | alc_free_kctls(codec); |
| 4288 | kfree(spec); | 4221 | kfree(spec); |
| 4289 | snd_hda_detach_beep_device(codec); | 4222 | snd_hda_detach_beep_device(codec); |
| @@ -5151,7 +5084,9 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, | |||
| 5151 | 5084 | ||
| 5152 | switch (cfg->line_out_type) { | 5085 | switch (cfg->line_out_type) { |
| 5153 | case AUTO_PIN_SPEAKER_OUT: | 5086 | case AUTO_PIN_SPEAKER_OUT: |
| 5154 | return "Speaker"; | 5087 | if (cfg->line_outs == 1) |
| 5088 | return "Speaker"; | ||
| 5089 | break; | ||
| 5155 | case AUTO_PIN_HP_OUT: | 5090 | case AUTO_PIN_HP_OUT: |
| 5156 | return "Headphone"; | 5091 | return "Headphone"; |
| 5157 | default: | 5092 | default: |
| @@ -5205,16 +5140,19 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
| 5205 | return err; | 5140 | return err; |
| 5206 | } else { | 5141 | } else { |
| 5207 | const char *name = pfx; | 5142 | const char *name = pfx; |
| 5208 | if (!name) | 5143 | int index = i; |
| 5144 | if (!name) { | ||
| 5209 | name = chname[i]; | 5145 | name = chname[i]; |
| 5146 | index = 0; | ||
| 5147 | } | ||
| 5210 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, | 5148 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
| 5211 | name, i, | 5149 | name, index, |
| 5212 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | 5150 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
| 5213 | HDA_OUTPUT)); | 5151 | HDA_OUTPUT)); |
| 5214 | if (err < 0) | 5152 | if (err < 0) |
| 5215 | return err; | 5153 | return err; |
| 5216 | err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, | 5154 | err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
| 5217 | name, i, | 5155 | name, index, |
| 5218 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, | 5156 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, |
| 5219 | HDA_INPUT)); | 5157 | HDA_INPUT)); |
| 5220 | if (err < 0) | 5158 | if (err < 0) |
| @@ -5585,6 +5523,7 @@ static void fixup_single_adc(struct hda_codec *codec) | |||
| 5585 | spec->capsrc_nids += i; | 5523 | spec->capsrc_nids += i; |
| 5586 | spec->adc_nids += i; | 5524 | spec->adc_nids += i; |
| 5587 | spec->num_adc_nids = 1; | 5525 | spec->num_adc_nids = 1; |
| 5526 | spec->single_input_src = 1; | ||
| 5588 | } | 5527 | } |
| 5589 | } | 5528 | } |
| 5590 | 5529 | ||
| @@ -5596,6 +5535,16 @@ static void fixup_dual_adc_switch(struct hda_codec *codec) | |||
| 5596 | init_capsrc_for_pin(codec, spec->int_mic.pin); | 5535 | init_capsrc_for_pin(codec, spec->int_mic.pin); |
| 5597 | } | 5536 | } |
| 5598 | 5537 | ||
| 5538 | /* initialize some special cases for input sources */ | ||
| 5539 | static void alc_init_special_input_src(struct hda_codec *codec) | ||
| 5540 | { | ||
| 5541 | struct alc_spec *spec = codec->spec; | ||
| 5542 | if (spec->dual_adc_switch) | ||
| 5543 | fixup_dual_adc_switch(codec); | ||
| 5544 | else if (spec->single_input_src) | ||
| 5545 | init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); | ||
| 5546 | } | ||
| 5547 | |||
| 5599 | static void set_capture_mixer(struct hda_codec *codec) | 5548 | static void set_capture_mixer(struct hda_codec *codec) |
| 5600 | { | 5549 | { |
| 5601 | struct alc_spec *spec = codec->spec; | 5550 | struct alc_spec *spec = codec->spec; |
| @@ -5611,7 +5560,7 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
| 5611 | int mux = 0; | 5560 | int mux = 0; |
| 5612 | int num_adcs = spec->num_adc_nids; | 5561 | int num_adcs = spec->num_adc_nids; |
| 5613 | if (spec->dual_adc_switch) | 5562 | if (spec->dual_adc_switch) |
| 5614 | fixup_dual_adc_switch(codec); | 5563 | num_adcs = 1; |
| 5615 | else if (spec->auto_mic) | 5564 | else if (spec->auto_mic) |
| 5616 | fixup_automic_adc(codec); | 5565 | fixup_automic_adc(codec); |
| 5617 | else if (spec->input_mux) { | 5566 | else if (spec->input_mux) { |
| @@ -5620,8 +5569,6 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
| 5620 | else if (spec->input_mux->num_items == 1) | 5569 | else if (spec->input_mux->num_items == 1) |
| 5621 | fixup_single_adc(codec); | 5570 | fixup_single_adc(codec); |
| 5622 | } | 5571 | } |
| 5623 | if (spec->dual_adc_switch) | ||
| 5624 | num_adcs = 1; | ||
| 5625 | spec->cap_mixer = caps[mux][num_adcs - 1]; | 5572 | spec->cap_mixer = caps[mux][num_adcs - 1]; |
| 5626 | } | 5573 | } |
| 5627 | } | 5574 | } |
| @@ -10748,6 +10695,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
| 10748 | */ | 10695 | */ |
| 10749 | enum { | 10696 | enum { |
| 10750 | PINFIX_ABIT_AW9D_MAX, | 10697 | PINFIX_ABIT_AW9D_MAX, |
| 10698 | PINFIX_LENOVO_Y530, | ||
| 10751 | PINFIX_PB_M5210, | 10699 | PINFIX_PB_M5210, |
| 10752 | PINFIX_ACER_ASPIRE_7736, | 10700 | PINFIX_ACER_ASPIRE_7736, |
| 10753 | }; | 10701 | }; |
| @@ -10762,6 +10710,14 @@ static const struct alc_fixup alc882_fixups[] = { | |||
| 10762 | { } | 10710 | { } |
| 10763 | } | 10711 | } |
| 10764 | }, | 10712 | }, |
| 10713 | [PINFIX_LENOVO_Y530] = { | ||
| 10714 | .type = ALC_FIXUP_PINS, | ||
| 10715 | .v.pins = (const struct alc_pincfg[]) { | ||
| 10716 | { 0x15, 0x99130112 }, /* rear int speakers */ | ||
| 10717 | { 0x16, 0x99130111 }, /* subwoofer */ | ||
| 10718 | { } | ||
| 10719 | } | ||
| 10720 | }, | ||
| 10765 | [PINFIX_PB_M5210] = { | 10721 | [PINFIX_PB_M5210] = { |
| 10766 | .type = ALC_FIXUP_VERBS, | 10722 | .type = ALC_FIXUP_VERBS, |
| 10767 | .v.verbs = (const struct hda_verb[]) { | 10723 | .v.verbs = (const struct hda_verb[]) { |
| @@ -10777,6 +10733,7 @@ static const struct alc_fixup alc882_fixups[] = { | |||
| 10777 | 10733 | ||
| 10778 | static struct snd_pci_quirk alc882_fixup_tbl[] = { | 10734 | static struct snd_pci_quirk alc882_fixup_tbl[] = { |
| 10779 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | 10735 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), |
| 10736 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), | ||
| 10780 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 10737 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), |
| 10781 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), | 10738 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), |
| 10782 | {} | 10739 | {} |
| @@ -10829,23 +10786,28 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) | |||
| 10829 | hda_nid_t pin, dac; | 10786 | hda_nid_t pin, dac; |
| 10830 | int i; | 10787 | int i; |
| 10831 | 10788 | ||
| 10832 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { | 10789 | if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { |
| 10833 | pin = spec->autocfg.hp_pins[i]; | 10790 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { |
| 10834 | if (!pin) | 10791 | pin = spec->autocfg.hp_pins[i]; |
| 10835 | break; | 10792 | if (!pin) |
| 10836 | dac = spec->multiout.hp_nid; | 10793 | break; |
| 10837 | if (!dac) | 10794 | dac = spec->multiout.hp_nid; |
| 10838 | dac = spec->multiout.dac_nids[0]; /* to front */ | 10795 | if (!dac) |
| 10839 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); | 10796 | dac = spec->multiout.dac_nids[0]; /* to front */ |
| 10797 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); | ||
| 10798 | } | ||
| 10840 | } | 10799 | } |
| 10841 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | 10800 | |
| 10842 | pin = spec->autocfg.speaker_pins[i]; | 10801 | if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { |
| 10843 | if (!pin) | 10802 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
| 10844 | break; | 10803 | pin = spec->autocfg.speaker_pins[i]; |
| 10845 | dac = spec->multiout.extra_out_nid[0]; | 10804 | if (!pin) |
| 10846 | if (!dac) | 10805 | break; |
| 10847 | dac = spec->multiout.dac_nids[0]; /* to front */ | 10806 | dac = spec->multiout.extra_out_nid[0]; |
| 10848 | alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); | 10807 | if (!dac) |
| 10808 | dac = spec->multiout.dac_nids[0]; /* to front */ | ||
| 10809 | alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); | ||
| 10810 | } | ||
| 10849 | } | 10811 | } |
| 10850 | } | 10812 | } |
| 10851 | 10813 | ||
| @@ -13796,6 +13758,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
| 13796 | } | 13758 | } |
| 13797 | 13759 | ||
| 13798 | #define alc268_auto_init_analog_input alc882_auto_init_analog_input | 13760 | #define alc268_auto_init_analog_input alc882_auto_init_analog_input |
| 13761 | #define alc268_auto_init_input_src alc882_auto_init_input_src | ||
| 13799 | 13762 | ||
| 13800 | /* init callback for auto-configuration model -- overriding the default init */ | 13763 | /* init callback for auto-configuration model -- overriding the default init */ |
| 13801 | static void alc268_auto_init(struct hda_codec *codec) | 13764 | static void alc268_auto_init(struct hda_codec *codec) |
| @@ -13805,6 +13768,7 @@ static void alc268_auto_init(struct hda_codec *codec) | |||
| 13805 | alc268_auto_init_hp_out(codec); | 13768 | alc268_auto_init_hp_out(codec); |
| 13806 | alc268_auto_init_mono_speaker_out(codec); | 13769 | alc268_auto_init_mono_speaker_out(codec); |
| 13807 | alc268_auto_init_analog_input(codec); | 13770 | alc268_auto_init_analog_input(codec); |
| 13771 | alc268_auto_init_input_src(codec); | ||
| 13808 | alc_auto_init_digital(codec); | 13772 | alc_auto_init_digital(codec); |
| 13809 | if (spec->unsol_event) | 13773 | if (spec->unsol_event) |
| 13810 | alc_inithook(codec); | 13774 | alc_inithook(codec); |
| @@ -14092,7 +14056,6 @@ static int patch_alc268(struct hda_codec *codec) | |||
| 14092 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 14056 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { |
| 14093 | /* check whether NID 0x07 is valid */ | 14057 | /* check whether NID 0x07 is valid */ |
| 14094 | unsigned int wcap = get_wcaps(codec, 0x07); | 14058 | unsigned int wcap = get_wcaps(codec, 0x07); |
| 14095 | int i; | ||
| 14096 | 14059 | ||
| 14097 | spec->capsrc_nids = alc268_capsrc_nids; | 14060 | spec->capsrc_nids = alc268_capsrc_nids; |
| 14098 | /* get type */ | 14061 | /* get type */ |
| @@ -14112,13 +14075,6 @@ static int patch_alc268(struct hda_codec *codec) | |||
| 14112 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); | 14075 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); |
| 14113 | add_mixer(spec, alc268_capture_mixer); | 14076 | add_mixer(spec, alc268_capture_mixer); |
| 14114 | } | 14077 | } |
| 14115 | /* set default input source */ | ||
| 14116 | for (i = 0; i < spec->num_adc_nids; i++) | ||
| 14117 | snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], | ||
| 14118 | 0, AC_VERB_SET_CONNECT_SEL, | ||
| 14119 | i < spec->num_mux_defs ? | ||
| 14120 | spec->input_mux[i].items[0].index : | ||
| 14121 | spec->input_mux->items[0].index); | ||
| 14122 | } | 14078 | } |
| 14123 | 14079 | ||
| 14124 | spec->vmaster_nid = 0x02; | 14080 | spec->vmaster_nid = 0x02; |
| @@ -14495,7 +14451,7 @@ static void alc269_speaker_automute(struct hda_codec *codec) | |||
| 14495 | HDA_AMP_MUTE, bits); | 14451 | HDA_AMP_MUTE, bits); |
| 14496 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 14452 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
| 14497 | HDA_AMP_MUTE, bits); | 14453 | HDA_AMP_MUTE, bits); |
| 14498 | alc_report_jack(codec, nid); | 14454 | snd_hda_input_jack_report(codec, nid); |
| 14499 | } | 14455 | } |
| 14500 | 14456 | ||
| 14501 | /* unsolicited event for HP jack sensing */ | 14457 | /* unsolicited event for HP jack sensing */ |
| @@ -14807,11 +14763,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
| 14807 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | 14763 | fillup_priv_adc_nids(codec, alc269_adc_candidates, |
| 14808 | sizeof(alc269_adc_candidates)); | 14764 | sizeof(alc269_adc_candidates)); |
| 14809 | 14765 | ||
| 14810 | /* set default input source */ | ||
| 14811 | if (!spec->dual_adc_switch) | ||
| 14812 | select_or_unmute_capsrc(codec, spec->capsrc_nids[0], | ||
| 14813 | spec->input_mux->items[0].index); | ||
| 14814 | |||
| 14815 | err = alc_auto_add_mic_boost(codec); | 14766 | err = alc_auto_add_mic_boost(codec); |
| 14816 | if (err < 0) | 14767 | if (err < 0) |
| 14817 | return err; | 14768 | return err; |
| @@ -14825,6 +14776,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
| 14825 | #define alc269_auto_init_multi_out alc268_auto_init_multi_out | 14776 | #define alc269_auto_init_multi_out alc268_auto_init_multi_out |
| 14826 | #define alc269_auto_init_hp_out alc268_auto_init_hp_out | 14777 | #define alc269_auto_init_hp_out alc268_auto_init_hp_out |
| 14827 | #define alc269_auto_init_analog_input alc882_auto_init_analog_input | 14778 | #define alc269_auto_init_analog_input alc882_auto_init_analog_input |
| 14779 | #define alc269_auto_init_input_src alc882_auto_init_input_src | ||
| 14828 | 14780 | ||
| 14829 | 14781 | ||
| 14830 | /* init callback for auto-configuration model -- overriding the default init */ | 14782 | /* init callback for auto-configuration model -- overriding the default init */ |
| @@ -14834,6 +14786,8 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
| 14834 | alc269_auto_init_multi_out(codec); | 14786 | alc269_auto_init_multi_out(codec); |
| 14835 | alc269_auto_init_hp_out(codec); | 14787 | alc269_auto_init_hp_out(codec); |
| 14836 | alc269_auto_init_analog_input(codec); | 14788 | alc269_auto_init_analog_input(codec); |
| 14789 | if (!spec->dual_adc_switch) | ||
| 14790 | alc269_auto_init_input_src(codec); | ||
| 14837 | alc_auto_init_digital(codec); | 14791 | alc_auto_init_digital(codec); |
| 14838 | if (spec->unsol_event) | 14792 | if (spec->unsol_event) |
| 14839 | alc_inithook(codec); | 14793 | alc_inithook(codec); |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index bd7b123f6440..05fcd60cc46f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -180,18 +180,16 @@ struct sigmatel_event { | |||
| 180 | int data; | 180 | int data; |
| 181 | }; | 181 | }; |
| 182 | 182 | ||
| 183 | struct sigmatel_jack { | ||
| 184 | hda_nid_t nid; | ||
| 185 | int type; | ||
| 186 | struct snd_jack *jack; | ||
| 187 | }; | ||
| 188 | |||
| 189 | struct sigmatel_mic_route { | 183 | struct sigmatel_mic_route { |
| 190 | hda_nid_t pin; | 184 | hda_nid_t pin; |
| 191 | signed char mux_idx; | 185 | signed char mux_idx; |
| 192 | signed char dmux_idx; | 186 | signed char dmux_idx; |
| 193 | }; | 187 | }; |
| 194 | 188 | ||
| 189 | #define MAX_PINS_NUM 16 | ||
| 190 | #define MAX_ADCS_NUM 4 | ||
| 191 | #define MAX_DMICS_NUM 4 | ||
| 192 | |||
| 195 | struct sigmatel_spec { | 193 | struct sigmatel_spec { |
| 196 | struct snd_kcontrol_new *mixers[4]; | 194 | struct snd_kcontrol_new *mixers[4]; |
| 197 | unsigned int num_mixers; | 195 | unsigned int num_mixers; |
| @@ -229,9 +227,6 @@ struct sigmatel_spec { | |||
| 229 | hda_nid_t *pwr_nids; | 227 | hda_nid_t *pwr_nids; |
| 230 | hda_nid_t *dac_list; | 228 | hda_nid_t *dac_list; |
| 231 | 229 | ||
| 232 | /* jack detection */ | ||
| 233 | struct snd_array jacks; | ||
| 234 | |||
| 235 | /* events */ | 230 | /* events */ |
| 236 | struct snd_array events; | 231 | struct snd_array events; |
| 237 | 232 | ||
| @@ -309,6 +304,17 @@ struct sigmatel_spec { | |||
| 309 | struct hda_input_mux private_imux; | 304 | struct hda_input_mux private_imux; |
| 310 | struct hda_input_mux private_smux; | 305 | struct hda_input_mux private_smux; |
| 311 | struct hda_input_mux private_mono_mux; | 306 | struct hda_input_mux private_mono_mux; |
| 307 | |||
| 308 | /* auto spec */ | ||
| 309 | unsigned auto_pin_cnt; | ||
| 310 | hda_nid_t auto_pin_nids[MAX_PINS_NUM]; | ||
| 311 | unsigned auto_adc_cnt; | ||
| 312 | hda_nid_t auto_adc_nids[MAX_ADCS_NUM]; | ||
| 313 | hda_nid_t auto_mux_nids[MAX_ADCS_NUM]; | ||
| 314 | hda_nid_t auto_dmux_nids[MAX_ADCS_NUM]; | ||
| 315 | unsigned long auto_capvols[MAX_ADCS_NUM]; | ||
| 316 | unsigned auto_dmic_cnt; | ||
| 317 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; | ||
| 312 | }; | 318 | }; |
| 313 | 319 | ||
| 314 | static hda_nid_t stac9200_adc_nids[1] = { | 320 | static hda_nid_t stac9200_adc_nids[1] = { |
| @@ -364,14 +370,6 @@ static unsigned long stac92hd73xx_capvols[] = { | |||
| 364 | 370 | ||
| 365 | #define STAC92HD83_DAC_COUNT 3 | 371 | #define STAC92HD83_DAC_COUNT 3 |
| 366 | 372 | ||
| 367 | static hda_nid_t stac92hd83xxx_mux_nids[2] = { | ||
| 368 | 0x17, 0x18, | ||
| 369 | }; | ||
| 370 | |||
| 371 | static hda_nid_t stac92hd83xxx_adc_nids[2] = { | ||
| 372 | 0x15, 0x16, | ||
| 373 | }; | ||
| 374 | |||
| 375 | static hda_nid_t stac92hd83xxx_pwr_nids[4] = { | 373 | static hda_nid_t stac92hd83xxx_pwr_nids[4] = { |
| 376 | 0xa, 0xb, 0xd, 0xe, | 374 | 0xa, 0xb, 0xd, 0xe, |
| 377 | }; | 375 | }; |
| @@ -384,25 +382,9 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { | |||
| 384 | 0x03, 0x0c, 0x20, 0x40, | 382 | 0x03, 0x0c, 0x20, 0x40, |
| 385 | }; | 383 | }; |
| 386 | 384 | ||
| 387 | #define STAC92HD83XXX_NUM_DMICS 2 | 385 | static hda_nid_t stac92hd83xxx_dmic_nids[] = { |
| 388 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | 386 | 0x11, 0x20, |
| 389 | 0x11, 0x20, 0 | ||
| 390 | }; | ||
| 391 | |||
| 392 | #define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS | ||
| 393 | #define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids | ||
| 394 | |||
| 395 | #define STAC92HD87B_NUM_DMICS 1 | ||
| 396 | static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { | ||
| 397 | 0x11, 0 | ||
| 398 | }; | ||
| 399 | |||
| 400 | #define STAC92HD83XXX_NUM_CAPS 2 | ||
| 401 | static unsigned long stac92hd83xxx_capvols[] = { | ||
| 402 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
| 403 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT), | ||
| 404 | }; | 387 | }; |
| 405 | #define stac92hd83xxx_capsws stac92hd83xxx_capvols | ||
| 406 | 388 | ||
| 407 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 389 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
| 408 | 0x0a, 0x0d, 0x0f | 390 | 0x0a, 0x0d, 0x0f |
| @@ -581,21 +563,6 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { | |||
| 581 | 0x14, 0x22, 0x23 | 563 | 0x14, 0x22, 0x23 |
| 582 | }; | 564 | }; |
| 583 | 565 | ||
| 584 | static hda_nid_t stac92hd83xxx_pin_nids[10] = { | ||
| 585 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | ||
| 586 | 0x0f, 0x10, 0x11, 0x1f, 0x20, | ||
| 587 | }; | ||
| 588 | |||
| 589 | static hda_nid_t stac92hd87xxx_pin_nids[6] = { | ||
| 590 | 0x0a, 0x0b, 0x0c, 0x0d, | ||
| 591 | 0x0f, 0x11, | ||
| 592 | }; | ||
| 593 | |||
| 594 | static hda_nid_t stac92hd88xxx_pin_nids[8] = { | ||
| 595 | 0x0a, 0x0b, 0x0c, 0x0d, | ||
| 596 | 0x0f, 0x11, 0x1f, 0x20, | ||
| 597 | }; | ||
| 598 | |||
| 599 | #define STAC92HD71BXX_NUM_PINS 13 | 566 | #define STAC92HD71BXX_NUM_PINS 13 |
| 600 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | 567 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { |
| 601 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | 568 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, |
| @@ -757,7 +724,7 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
| 757 | struct sigmatel_spec *spec = codec->spec; | 724 | struct sigmatel_spec *spec = codec->spec; |
| 758 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 725 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
| 759 | const struct hda_input_mux *imux = spec->input_mux; | 726 | const struct hda_input_mux *imux = spec->input_mux; |
| 760 | unsigned int idx, prev_idx; | 727 | unsigned int idx, prev_idx, didx; |
| 761 | 728 | ||
| 762 | idx = ucontrol->value.enumerated.item[0]; | 729 | idx = ucontrol->value.enumerated.item[0]; |
| 763 | if (idx >= imux->num_items) | 730 | if (idx >= imux->num_items) |
| @@ -769,7 +736,8 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
| 769 | snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, | 736 | snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, |
| 770 | AC_VERB_SET_CONNECT_SEL, | 737 | AC_VERB_SET_CONNECT_SEL, |
| 771 | imux->items[idx].index); | 738 | imux->items[idx].index); |
| 772 | if (prev_idx >= spec->num_analog_muxes) { | 739 | if (prev_idx >= spec->num_analog_muxes && |
| 740 | spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) { | ||
| 773 | imux = spec->dinput_mux; | 741 | imux = spec->dinput_mux; |
| 774 | /* 0 = analog */ | 742 | /* 0 = analog */ |
| 775 | snd_hda_codec_write_cache(codec, | 743 | snd_hda_codec_write_cache(codec, |
| @@ -779,9 +747,13 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
| 779 | } | 747 | } |
| 780 | } else { | 748 | } else { |
| 781 | imux = spec->dinput_mux; | 749 | imux = spec->dinput_mux; |
| 750 | /* first dimux item is hardcoded to select analog imux, | ||
| 751 | * so lets skip it | ||
| 752 | */ | ||
| 753 | didx = idx - spec->num_analog_muxes + 1; | ||
| 782 | snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, | 754 | snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, |
| 783 | AC_VERB_SET_CONNECT_SEL, | 755 | AC_VERB_SET_CONNECT_SEL, |
| 784 | imux->items[idx - 1].index); | 756 | imux->items[didx].index); |
| 785 | } | 757 | } |
| 786 | spec->cur_mux[adc_idx] = idx; | 758 | spec->cur_mux[adc_idx] = idx; |
| 787 | return 1; | 759 | return 1; |
| @@ -3419,6 +3391,17 @@ static const char * const stac92xx_dmic_labels[5] = { | |||
| 3419 | "Digital Mic 3", "Digital Mic 4" | 3391 | "Digital Mic 3", "Digital Mic 4" |
| 3420 | }; | 3392 | }; |
| 3421 | 3393 | ||
| 3394 | static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux, | ||
| 3395 | int idx) | ||
| 3396 | { | ||
| 3397 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
| 3398 | int nums; | ||
| 3399 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
| 3400 | if (idx >= 0 && idx < nums) | ||
| 3401 | return conn[idx]; | ||
| 3402 | return 0; | ||
| 3403 | } | ||
| 3404 | |||
| 3422 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | 3405 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
| 3423 | hda_nid_t nid) | 3406 | hda_nid_t nid) |
| 3424 | { | 3407 | { |
| @@ -3429,6 +3412,15 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | |||
| 3429 | for (i = 0; i < nums; i++) | 3412 | for (i = 0; i < nums; i++) |
| 3430 | if (conn[i] == nid) | 3413 | if (conn[i] == nid) |
| 3431 | return i; | 3414 | return i; |
| 3415 | |||
| 3416 | for (i = 0; i < nums; i++) { | ||
| 3417 | unsigned int wid_caps = get_wcaps(codec, conn[i]); | ||
| 3418 | unsigned int wid_type = get_wcaps_type(wid_caps); | ||
| 3419 | |||
| 3420 | if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX) | ||
| 3421 | if (get_connection_index(codec, conn[i], nid) >= 0) | ||
| 3422 | return i; | ||
| 3423 | } | ||
| 3432 | return -1; | 3424 | return -1; |
| 3433 | } | 3425 | } |
| 3434 | 3426 | ||
| @@ -3501,6 +3493,16 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
| 3501 | type_idx, HDA_OUTPUT); | 3493 | type_idx, HDA_OUTPUT); |
| 3502 | if (err < 0) | 3494 | if (err < 0) |
| 3503 | return err; | 3495 | return err; |
| 3496 | if (!err) { | ||
| 3497 | nid = get_connected_node(codec, | ||
| 3498 | spec->dmux_nids[0], index); | ||
| 3499 | if (nid) | ||
| 3500 | err = create_elem_capture_vol(codec, | ||
| 3501 | nid, label, | ||
| 3502 | type_idx, HDA_INPUT); | ||
| 3503 | if (err < 0) | ||
| 3504 | return err; | ||
| 3505 | } | ||
| 3504 | } | 3506 | } |
| 3505 | } | 3507 | } |
| 3506 | 3508 | ||
| @@ -4054,21 +4056,10 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | |||
| 4054 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ | 4056 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ |
| 4055 | } | 4057 | } |
| 4056 | 4058 | ||
| 4057 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 4058 | static void stac92xx_free_jack_priv(struct snd_jack *jack) | ||
| 4059 | { | ||
| 4060 | struct sigmatel_jack *jacks = jack->private_data; | ||
| 4061 | jacks->nid = 0; | ||
| 4062 | jacks->jack = NULL; | ||
| 4063 | } | ||
| 4064 | #endif | ||
| 4065 | |||
| 4066 | static int stac92xx_add_jack(struct hda_codec *codec, | 4059 | static int stac92xx_add_jack(struct hda_codec *codec, |
| 4067 | hda_nid_t nid, int type) | 4060 | hda_nid_t nid, int type) |
| 4068 | { | 4061 | { |
| 4069 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 4062 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
| 4070 | struct sigmatel_spec *spec = codec->spec; | ||
| 4071 | struct sigmatel_jack *jack; | ||
| 4072 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4063 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
| 4073 | int connectivity = get_defcfg_connect(def_conf); | 4064 | int connectivity = get_defcfg_connect(def_conf); |
| 4074 | char name[32]; | 4065 | char name[32]; |
| @@ -4077,26 +4068,15 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
| 4077 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) | 4068 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) |
| 4078 | return 0; | 4069 | return 0; |
| 4079 | 4070 | ||
| 4080 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | ||
| 4081 | jack = snd_array_new(&spec->jacks); | ||
| 4082 | if (!jack) | ||
| 4083 | return -ENOMEM; | ||
| 4084 | jack->nid = nid; | ||
| 4085 | jack->type = type; | ||
| 4086 | |||
| 4087 | snprintf(name, sizeof(name), "%s at %s %s Jack", | 4071 | snprintf(name, sizeof(name), "%s at %s %s Jack", |
| 4088 | snd_hda_get_jack_type(def_conf), | 4072 | snd_hda_get_jack_type(def_conf), |
| 4089 | snd_hda_get_jack_connectivity(def_conf), | 4073 | snd_hda_get_jack_connectivity(def_conf), |
| 4090 | snd_hda_get_jack_location(def_conf)); | 4074 | snd_hda_get_jack_location(def_conf)); |
| 4091 | 4075 | ||
| 4092 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | 4076 | err = snd_hda_input_jack_add(codec, nid, type, name); |
| 4093 | if (err < 0) { | 4077 | if (err < 0) |
| 4094 | jack->nid = 0; | ||
| 4095 | return err; | 4078 | return err; |
| 4096 | } | 4079 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ |
| 4097 | jack->jack->private_data = jack; | ||
| 4098 | jack->jack->private_free = stac92xx_free_jack_priv; | ||
| 4099 | #endif | ||
| 4100 | return 0; | 4080 | return 0; |
| 4101 | } | 4081 | } |
| 4102 | 4082 | ||
| @@ -4399,23 +4379,6 @@ static int stac92xx_init(struct hda_codec *codec) | |||
| 4399 | return 0; | 4379 | return 0; |
| 4400 | } | 4380 | } |
| 4401 | 4381 | ||
| 4402 | static void stac92xx_free_jacks(struct hda_codec *codec) | ||
| 4403 | { | ||
| 4404 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
| 4405 | /* free jack instances manually when clearing/reconfiguring */ | ||
| 4406 | struct sigmatel_spec *spec = codec->spec; | ||
| 4407 | if (!codec->bus->shutdown && spec->jacks.list) { | ||
| 4408 | struct sigmatel_jack *jacks = spec->jacks.list; | ||
| 4409 | int i; | ||
| 4410 | for (i = 0; i < spec->jacks.used; i++, jacks++) { | ||
| 4411 | if (jacks->jack) | ||
| 4412 | snd_device_free(codec->bus->card, jacks->jack); | ||
| 4413 | } | ||
| 4414 | } | ||
| 4415 | snd_array_free(&spec->jacks); | ||
| 4416 | #endif | ||
| 4417 | } | ||
| 4418 | |||
| 4419 | static void stac92xx_free_kctls(struct hda_codec *codec) | 4382 | static void stac92xx_free_kctls(struct hda_codec *codec) |
| 4420 | { | 4383 | { |
| 4421 | struct sigmatel_spec *spec = codec->spec; | 4384 | struct sigmatel_spec *spec = codec->spec; |
| @@ -4449,7 +4412,7 @@ static void stac92xx_free(struct hda_codec *codec) | |||
| 4449 | return; | 4412 | return; |
| 4450 | 4413 | ||
| 4451 | stac92xx_shutup(codec); | 4414 | stac92xx_shutup(codec); |
| 4452 | stac92xx_free_jacks(codec); | 4415 | snd_hda_input_jack_free(codec); |
| 4453 | snd_array_free(&spec->events); | 4416 | snd_array_free(&spec->events); |
| 4454 | 4417 | ||
| 4455 | kfree(spec); | 4418 | kfree(spec); |
| @@ -4667,33 +4630,6 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) | |||
| 4667 | stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); | 4630 | stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); |
| 4668 | } | 4631 | } |
| 4669 | 4632 | ||
| 4670 | static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) | ||
| 4671 | { | ||
| 4672 | struct sigmatel_spec *spec = codec->spec; | ||
| 4673 | struct sigmatel_jack *jacks = spec->jacks.list; | ||
| 4674 | |||
| 4675 | if (jacks) { | ||
| 4676 | int i; | ||
| 4677 | for (i = 0; i < spec->jacks.used; i++) { | ||
| 4678 | if (jacks->nid == nid) { | ||
| 4679 | unsigned int pin_ctl = | ||
| 4680 | snd_hda_codec_read(codec, nid, | ||
| 4681 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
| 4682 | 0x00); | ||
| 4683 | int type = jacks->type; | ||
| 4684 | if (type == (SND_JACK_LINEOUT | ||
| 4685 | | SND_JACK_HEADPHONE)) | ||
| 4686 | type = (pin_ctl & AC_PINCTL_HP_EN) | ||
| 4687 | ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT; | ||
| 4688 | snd_jack_report(jacks->jack, | ||
| 4689 | get_pin_presence(codec, nid) | ||
| 4690 | ? type : 0); | ||
| 4691 | } | ||
| 4692 | jacks++; | ||
| 4693 | } | ||
| 4694 | } | ||
| 4695 | } | ||
| 4696 | |||
| 4697 | /* get the pin connection (fixed, none, etc) */ | 4633 | /* get the pin connection (fixed, none, etc) */ |
| 4698 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | 4634 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) |
| 4699 | { | 4635 | { |
| @@ -4782,7 +4718,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
| 4782 | case STAC_PWR_EVENT: | 4718 | case STAC_PWR_EVENT: |
| 4783 | if (spec->num_pwrs > 0) | 4719 | if (spec->num_pwrs > 0) |
| 4784 | stac92xx_pin_sense(codec, event->nid); | 4720 | stac92xx_pin_sense(codec, event->nid); |
| 4785 | stac92xx_report_jack(codec, event->nid); | 4721 | snd_hda_input_jack_report(codec, event->nid); |
| 4786 | 4722 | ||
| 4787 | switch (codec->subsystem_id) { | 4723 | switch (codec->subsystem_id) { |
| 4788 | case 0x103c308f: | 4724 | case 0x103c308f: |
| @@ -5378,6 +5314,105 @@ static int hp_bnb2011_with_dock(struct hda_codec *codec) | |||
| 5378 | return 0; | 5314 | return 0; |
| 5379 | } | 5315 | } |
| 5380 | 5316 | ||
| 5317 | static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid) | ||
| 5318 | { | ||
| 5319 | struct sigmatel_spec *spec = codec->spec; | ||
| 5320 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
| 5321 | int i; | ||
| 5322 | |||
| 5323 | spec->auto_pin_nids[spec->auto_pin_cnt] = nid; | ||
| 5324 | spec->auto_pin_cnt++; | ||
| 5325 | |||
| 5326 | if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN && | ||
| 5327 | get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) { | ||
| 5328 | for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) { | ||
| 5329 | if (nid == stac92hd83xxx_dmic_nids[i]) { | ||
| 5330 | spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid; | ||
| 5331 | spec->auto_dmic_cnt++; | ||
| 5332 | } | ||
| 5333 | } | ||
| 5334 | } | ||
| 5335 | } | ||
| 5336 | |||
| 5337 | static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid) | ||
| 5338 | { | ||
| 5339 | struct sigmatel_spec *spec = codec->spec; | ||
| 5340 | |||
| 5341 | spec->auto_adc_nids[spec->auto_adc_cnt] = nid; | ||
| 5342 | spec->auto_adc_cnt++; | ||
| 5343 | } | ||
| 5344 | |||
| 5345 | static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid) | ||
| 5346 | { | ||
| 5347 | int i, j; | ||
| 5348 | struct sigmatel_spec *spec = codec->spec; | ||
| 5349 | |||
| 5350 | for (i = 0; i < spec->auto_adc_cnt; i++) { | ||
| 5351 | if (get_connection_index(codec, | ||
| 5352 | spec->auto_adc_nids[i], nid) >= 0) { | ||
| 5353 | /* mux and volume for adc_nids[i] */ | ||
| 5354 | if (!spec->auto_mux_nids[i]) { | ||
| 5355 | spec->auto_mux_nids[i] = nid; | ||
| 5356 | /* 92hd codecs capture volume is in mux */ | ||
| 5357 | spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid, | ||
| 5358 | 3, 0, HDA_OUTPUT); | ||
| 5359 | } | ||
| 5360 | for (j = 0; j < spec->auto_dmic_cnt; j++) { | ||
| 5361 | if (get_connection_index(codec, nid, | ||
| 5362 | spec->auto_dmic_nids[j]) >= 0) { | ||
| 5363 | /* dmux for adc_nids[i] */ | ||
| 5364 | if (!spec->auto_dmux_nids[i]) | ||
| 5365 | spec->auto_dmux_nids[i] = nid; | ||
| 5366 | break; | ||
| 5367 | } | ||
| 5368 | } | ||
| 5369 | break; | ||
| 5370 | } | ||
| 5371 | } | ||
| 5372 | } | ||
| 5373 | |||
| 5374 | static void stac92hd8x_fill_auto_spec(struct hda_codec *codec) | ||
| 5375 | { | ||
| 5376 | hda_nid_t nid, end_nid; | ||
| 5377 | unsigned int wid_caps, wid_type; | ||
| 5378 | struct sigmatel_spec *spec = codec->spec; | ||
| 5379 | |||
| 5380 | end_nid = codec->start_nid + codec->num_nodes; | ||
| 5381 | |||
| 5382 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
| 5383 | wid_caps = get_wcaps(codec, nid); | ||
| 5384 | wid_type = get_wcaps_type(wid_caps); | ||
| 5385 | |||
| 5386 | if (wid_type == AC_WID_PIN) | ||
| 5387 | stac92hd8x_add_pin(codec, nid); | ||
| 5388 | |||
| 5389 | if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL)) | ||
| 5390 | stac92hd8x_add_adc(codec, nid); | ||
| 5391 | } | ||
| 5392 | |||
| 5393 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
| 5394 | wid_caps = get_wcaps(codec, nid); | ||
| 5395 | wid_type = get_wcaps_type(wid_caps); | ||
| 5396 | |||
| 5397 | if (wid_type == AC_WID_AUD_SEL) | ||
| 5398 | stac92hd8x_add_mux(codec, nid); | ||
| 5399 | } | ||
| 5400 | |||
| 5401 | spec->pin_nids = spec->auto_pin_nids; | ||
| 5402 | spec->num_pins = spec->auto_pin_cnt; | ||
| 5403 | spec->adc_nids = spec->auto_adc_nids; | ||
| 5404 | spec->num_adcs = spec->auto_adc_cnt; | ||
| 5405 | spec->capvols = spec->auto_capvols; | ||
| 5406 | spec->capsws = spec->auto_capvols; | ||
| 5407 | spec->num_caps = spec->auto_adc_cnt; | ||
| 5408 | spec->mux_nids = spec->auto_mux_nids; | ||
| 5409 | spec->num_muxes = spec->auto_adc_cnt; | ||
| 5410 | spec->dmux_nids = spec->auto_dmux_nids; | ||
| 5411 | spec->num_dmuxes = spec->auto_adc_cnt; | ||
| 5412 | spec->dmic_nids = spec->auto_dmic_nids; | ||
| 5413 | spec->num_dmics = spec->auto_dmic_cnt; | ||
| 5414 | } | ||
| 5415 | |||
| 5381 | static int patch_stac92hd83xxx(struct hda_codec *codec) | 5416 | static int patch_stac92hd83xxx(struct hda_codec *codec) |
| 5382 | { | 5417 | { |
| 5383 | struct sigmatel_spec *spec; | 5418 | struct sigmatel_spec *spec; |
| @@ -5399,26 +5434,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
| 5399 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); | 5434 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); |
| 5400 | codec->no_trigger_sense = 1; | 5435 | codec->no_trigger_sense = 1; |
| 5401 | codec->spec = spec; | 5436 | codec->spec = spec; |
| 5437 | |||
| 5438 | stac92hd8x_fill_auto_spec(codec); | ||
| 5439 | |||
| 5402 | spec->linear_tone_beep = 0; | 5440 | spec->linear_tone_beep = 0; |
| 5403 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5441 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
| 5404 | spec->digbeep_nid = 0x21; | 5442 | spec->digbeep_nid = 0x21; |
| 5405 | spec->dmic_nids = stac92hd83xxx_dmic_nids; | ||
| 5406 | spec->dmux_nids = stac92hd83xxx_mux_nids; | ||
| 5407 | spec->mux_nids = stac92hd83xxx_mux_nids; | ||
| 5408 | spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); | ||
| 5409 | spec->adc_nids = stac92hd83xxx_adc_nids; | ||
| 5410 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | ||
| 5411 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 5443 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
| 5412 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | 5444 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; |
| 5413 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 5445 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
| 5414 | spec->multiout.dac_nids = spec->dac_nids; | 5446 | spec->multiout.dac_nids = spec->dac_nids; |
| 5415 | |||
| 5416 | spec->init = stac92hd83xxx_core_init; | 5447 | spec->init = stac92hd83xxx_core_init; |
| 5417 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | ||
| 5418 | spec->pin_nids = stac92hd83xxx_pin_nids; | ||
| 5419 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; | ||
| 5420 | spec->capvols = stac92hd83xxx_capvols; | ||
| 5421 | spec->capsws = stac92hd83xxx_capsws; | ||
| 5422 | 5448 | ||
| 5423 | spec->board_config = snd_hda_check_board_config(codec, | 5449 | spec->board_config = snd_hda_check_board_config(codec, |
| 5424 | STAC_92HD83XXX_MODELS, | 5450 | STAC_92HD83XXX_MODELS, |
| @@ -5436,28 +5462,11 @@ again: | |||
| 5436 | case 0x111d76d1: | 5462 | case 0x111d76d1: |
| 5437 | case 0x111d76d9: | 5463 | case 0x111d76d9: |
| 5438 | case 0x111d76e5: | 5464 | case 0x111d76e5: |
| 5439 | spec->dmic_nids = stac92hd87b_dmic_nids; | ||
| 5440 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
| 5441 | stac92hd87b_dmic_nids, | ||
| 5442 | STAC92HD87B_NUM_DMICS); | ||
| 5443 | spec->num_pins = ARRAY_SIZE(stac92hd87xxx_pin_nids); | ||
| 5444 | spec->pin_nids = stac92hd87xxx_pin_nids; | ||
| 5445 | spec->mono_nid = 0; | ||
| 5446 | spec->num_pwrs = 0; | ||
| 5447 | break; | ||
| 5448 | case 0x111d7666: | 5465 | case 0x111d7666: |
| 5449 | case 0x111d7667: | 5466 | case 0x111d7667: |
| 5450 | case 0x111d7668: | 5467 | case 0x111d7668: |
| 5451 | case 0x111d7669: | 5468 | case 0x111d7669: |
| 5452 | case 0x111d76e3: | 5469 | case 0x111d76e3: |
| 5453 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
| 5454 | stac92hd88xxx_dmic_nids, | ||
| 5455 | STAC92HD88XXX_NUM_DMICS); | ||
| 5456 | spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); | ||
| 5457 | spec->pin_nids = stac92hd88xxx_pin_nids; | ||
| 5458 | spec->mono_nid = 0; | ||
| 5459 | spec->num_pwrs = 0; | ||
| 5460 | break; | ||
| 5461 | case 0x111d7604: | 5470 | case 0x111d7604: |
| 5462 | case 0x111d76d4: | 5471 | case 0x111d76d4: |
| 5463 | case 0x111d7605: | 5472 | case 0x111d7605: |
| @@ -5466,9 +5475,6 @@ again: | |||
| 5466 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | 5475 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) |
| 5467 | break; | 5476 | break; |
| 5468 | spec->num_pwrs = 0; | 5477 | spec->num_pwrs = 0; |
| 5469 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
| 5470 | stac92hd83xxx_dmic_nids, | ||
| 5471 | STAC92HD83XXX_NUM_DMICS); | ||
| 5472 | break; | 5478 | break; |
| 5473 | } | 5479 | } |
| 5474 | 5480 | ||
