diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 302 |
1 files changed, 154 insertions, 148 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4562e9de6a1..4df72c0e8c3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <sound/jack.h> | 33 | #include <sound/jack.h> |
34 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | #include "hda_beep.h" | 35 | #include "hda_beep.h" |
36 | #include "hda_jack.h" | ||
36 | #include <sound/hda_hwdep.h> | 37 | #include <sound/hda_hwdep.h> |
37 | 38 | ||
38 | #define CREATE_TRACE_POINTS | 39 | #define CREATE_TRACE_POINTS |
@@ -1723,43 +1724,6 @@ int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, | |||
1723 | } | 1724 | } |
1724 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); | 1725 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); |
1725 | 1726 | ||
1726 | /** | ||
1727 | * snd_hda_pin_sense - execute pin sense measurement | ||
1728 | * @codec: the CODEC to sense | ||
1729 | * @nid: the pin NID to sense | ||
1730 | * | ||
1731 | * Execute necessary pin sense measurement and return its Presence Detect, | ||
1732 | * Impedance, ELD Valid etc. status bits. | ||
1733 | */ | ||
1734 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) | ||
1735 | { | ||
1736 | u32 pincap; | ||
1737 | |||
1738 | if (!codec->no_trigger_sense) { | ||
1739 | pincap = snd_hda_query_pin_caps(codec, nid); | ||
1740 | if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ | ||
1741 | snd_hda_codec_read(codec, nid, 0, | ||
1742 | AC_VERB_SET_PIN_SENSE, 0); | ||
1743 | } | ||
1744 | return snd_hda_codec_read(codec, nid, 0, | ||
1745 | AC_VERB_GET_PIN_SENSE, 0); | ||
1746 | } | ||
1747 | EXPORT_SYMBOL_HDA(snd_hda_pin_sense); | ||
1748 | |||
1749 | /** | ||
1750 | * snd_hda_jack_detect - query pin Presence Detect status | ||
1751 | * @codec: the CODEC to sense | ||
1752 | * @nid: the pin NID to sense | ||
1753 | * | ||
1754 | * Query and return the pin's Presence Detect status. | ||
1755 | */ | ||
1756 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) | ||
1757 | { | ||
1758 | u32 sense = snd_hda_pin_sense(codec, nid); | ||
1759 | return !!(sense & AC_PINSENSE_PRESENCE); | ||
1760 | } | ||
1761 | EXPORT_SYMBOL_HDA(snd_hda_jack_detect); | ||
1762 | |||
1763 | /* | 1727 | /* |
1764 | * read the current volume to info | 1728 | * read the current volume to info |
1765 | * if the cache exists, read the cache value. | 1729 | * if the cache exists, read the cache value. |
@@ -2308,6 +2272,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2308 | } | 2272 | } |
2309 | if (codec->patch_ops.free) | 2273 | if (codec->patch_ops.free) |
2310 | codec->patch_ops.free(codec); | 2274 | codec->patch_ops.free(codec); |
2275 | snd_hda_jack_tbl_clear(codec); | ||
2311 | codec->proc_widget_hook = NULL; | 2276 | codec->proc_widget_hook = NULL; |
2312 | codec->spec = NULL; | 2277 | codec->spec = NULL; |
2313 | free_hda_cache(&codec->amp_cache); | 2278 | free_hda_cache(&codec->amp_cache); |
@@ -3364,6 +3329,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3364 | restore_pincfgs(codec); /* restore all current pin configs */ | 3329 | restore_pincfgs(codec); /* restore all current pin configs */ |
3365 | restore_shutup_pins(codec); | 3330 | restore_shutup_pins(codec); |
3366 | hda_exec_init_verbs(codec); | 3331 | hda_exec_init_verbs(codec); |
3332 | snd_hda_jack_set_dirty_all(codec); | ||
3367 | if (codec->patch_ops.resume) | 3333 | if (codec->patch_ops.resume) |
3368 | codec->patch_ops.resume(codec); | 3334 | codec->patch_ops.resume(codec); |
3369 | else { | 3335 | else { |
@@ -3850,6 +3816,12 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type) | |||
3850 | if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) | 3816 | if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) |
3851 | return audio_idx[type][i]; | 3817 | return audio_idx[type][i]; |
3852 | 3818 | ||
3819 | /* non-fixed slots starting from 10 */ | ||
3820 | for (i = 10; i < 32; i++) { | ||
3821 | if (!test_and_set_bit(i, bus->pcm_dev_bits)) | ||
3822 | return i; | ||
3823 | } | ||
3824 | |||
3853 | snd_printk(KERN_WARNING "Too many %s devices\n", | 3825 | snd_printk(KERN_WARNING "Too many %s devices\n", |
3854 | snd_hda_pcm_type_name[type]); | 3826 | snd_hda_pcm_type_name[type]); |
3855 | return -EAGAIN; | 3827 | return -EAGAIN; |
@@ -5004,8 +4976,8 @@ EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); | |||
5004 | * "Rear", "Internal". | 4976 | * "Rear", "Internal". |
5005 | */ | 4977 | */ |
5006 | 4978 | ||
5007 | const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, | 4979 | static const char *hda_get_input_pin_label(struct hda_codec *codec, |
5008 | int check_location) | 4980 | hda_nid_t pin, bool check_location) |
5009 | { | 4981 | { |
5010 | unsigned int def_conf; | 4982 | unsigned int def_conf; |
5011 | static const char * const mic_names[] = { | 4983 | static const char * const mic_names[] = { |
@@ -5044,7 +5016,6 @@ const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, | |||
5044 | return "Misc"; | 5016 | return "Misc"; |
5045 | } | 5017 | } |
5046 | } | 5018 | } |
5047 | EXPORT_SYMBOL_HDA(hda_get_input_pin_label); | ||
5048 | 5019 | ||
5049 | /* Check whether the location prefix needs to be added to the label. | 5020 | /* Check whether the location prefix needs to be added to the label. |
5050 | * If all mic-jacks are in the same location (e.g. rear panel), we don't | 5021 | * If all mic-jacks are in the same location (e.g. rear panel), we don't |
@@ -5101,6 +5072,149 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec, | |||
5101 | } | 5072 | } |
5102 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | 5073 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); |
5103 | 5074 | ||
5075 | /* return the position of NID in the list, or -1 if not found */ | ||
5076 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
5077 | { | ||
5078 | int i; | ||
5079 | for (i = 0; i < nums; i++) | ||
5080 | if (list[i] == nid) | ||
5081 | return i; | ||
5082 | return -1; | ||
5083 | } | ||
5084 | |||
5085 | /* get a unique suffix or an index number */ | ||
5086 | static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, | ||
5087 | int num_pins, int *indexp) | ||
5088 | { | ||
5089 | static const char * const channel_sfx[] = { | ||
5090 | " Front", " Surround", " CLFE", " Side" | ||
5091 | }; | ||
5092 | int i; | ||
5093 | |||
5094 | i = find_idx_in_nid_list(nid, pins, num_pins); | ||
5095 | if (i < 0) | ||
5096 | return NULL; | ||
5097 | if (num_pins == 1) | ||
5098 | return ""; | ||
5099 | if (num_pins > ARRAY_SIZE(channel_sfx)) { | ||
5100 | if (indexp) | ||
5101 | *indexp = i; | ||
5102 | return ""; | ||
5103 | } | ||
5104 | return channel_sfx[i]; | ||
5105 | } | ||
5106 | |||
5107 | static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | ||
5108 | const struct auto_pin_cfg *cfg, | ||
5109 | const char *name, char *label, int maxlen, | ||
5110 | int *indexp) | ||
5111 | { | ||
5112 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5113 | int attr = snd_hda_get_input_pin_attr(def_conf); | ||
5114 | const char *pfx = "", *sfx = ""; | ||
5115 | |||
5116 | /* handle as a speaker if it's a fixed line-out */ | ||
5117 | if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) | ||
5118 | name = "Speaker"; | ||
5119 | /* check the location */ | ||
5120 | switch (attr) { | ||
5121 | case INPUT_PIN_ATTR_DOCK: | ||
5122 | pfx = "Dock "; | ||
5123 | break; | ||
5124 | case INPUT_PIN_ATTR_FRONT: | ||
5125 | pfx = "Front "; | ||
5126 | break; | ||
5127 | } | ||
5128 | if (cfg) { | ||
5129 | /* try to give a unique suffix if needed */ | ||
5130 | sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, | ||
5131 | indexp); | ||
5132 | if (!sfx) | ||
5133 | sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, | ||
5134 | indexp); | ||
5135 | if (!sfx) { | ||
5136 | /* don't add channel suffix for Headphone controls */ | ||
5137 | int idx = find_idx_in_nid_list(nid, cfg->hp_pins, | ||
5138 | cfg->hp_outs); | ||
5139 | if (idx >= 0) | ||
5140 | *indexp = idx; | ||
5141 | sfx = ""; | ||
5142 | } | ||
5143 | } | ||
5144 | snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); | ||
5145 | return 1; | ||
5146 | } | ||
5147 | |||
5148 | /** | ||
5149 | * snd_hda_get_pin_label - Get a label for the given I/O pin | ||
5150 | * | ||
5151 | * Get a label for the given pin. This function works for both input and | ||
5152 | * output pins. When @cfg is given as non-NULL, the function tries to get | ||
5153 | * an optimized label using hda_get_autocfg_input_label(). | ||
5154 | * | ||
5155 | * This function tries to give a unique label string for the pin as much as | ||
5156 | * possible. For example, when the multiple line-outs are present, it adds | ||
5157 | * the channel suffix like "Front", "Surround", etc (only when @cfg is given). | ||
5158 | * If no unique name with a suffix is available and @indexp is non-NULL, the | ||
5159 | * index number is stored in the pointer. | ||
5160 | */ | ||
5161 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | ||
5162 | const struct auto_pin_cfg *cfg, | ||
5163 | char *label, int maxlen, int *indexp) | ||
5164 | { | ||
5165 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5166 | const char *name = NULL; | ||
5167 | int i; | ||
5168 | |||
5169 | if (indexp) | ||
5170 | *indexp = 0; | ||
5171 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
5172 | return 0; | ||
5173 | |||
5174 | switch (get_defcfg_device(def_conf)) { | ||
5175 | case AC_JACK_LINE_OUT: | ||
5176 | return fill_audio_out_name(codec, nid, cfg, "Line-Out", | ||
5177 | label, maxlen, indexp); | ||
5178 | case AC_JACK_SPEAKER: | ||
5179 | return fill_audio_out_name(codec, nid, cfg, "Speaker", | ||
5180 | label, maxlen, indexp); | ||
5181 | case AC_JACK_HP_OUT: | ||
5182 | return fill_audio_out_name(codec, nid, cfg, "Headphone", | ||
5183 | label, maxlen, indexp); | ||
5184 | case AC_JACK_SPDIF_OUT: | ||
5185 | case AC_JACK_DIG_OTHER_OUT: | ||
5186 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) | ||
5187 | name = "HDMI"; | ||
5188 | else | ||
5189 | name = "SPDIF"; | ||
5190 | if (cfg && indexp) { | ||
5191 | i = find_idx_in_nid_list(nid, cfg->dig_out_pins, | ||
5192 | cfg->dig_outs); | ||
5193 | if (i >= 0) | ||
5194 | *indexp = i; | ||
5195 | } | ||
5196 | break; | ||
5197 | default: | ||
5198 | if (cfg) { | ||
5199 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5200 | if (cfg->inputs[i].pin != nid) | ||
5201 | continue; | ||
5202 | name = hda_get_autocfg_input_label(codec, cfg, i); | ||
5203 | if (name) | ||
5204 | break; | ||
5205 | } | ||
5206 | } | ||
5207 | if (!name) | ||
5208 | name = hda_get_input_pin_label(codec, nid, true); | ||
5209 | break; | ||
5210 | } | ||
5211 | if (!name) | ||
5212 | return 0; | ||
5213 | strlcpy(label, name, maxlen); | ||
5214 | return 1; | ||
5215 | } | ||
5216 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | ||
5217 | |||
5104 | /** | 5218 | /** |
5105 | * snd_hda_add_imux_item - Add an item to input_mux | 5219 | * snd_hda_add_imux_item - Add an item to input_mux |
5106 | * | 5220 | * |
@@ -5252,113 +5366,5 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) | |||
5252 | } | 5366 | } |
5253 | EXPORT_SYMBOL_HDA(snd_print_pcm_bits); | 5367 | EXPORT_SYMBOL_HDA(snd_print_pcm_bits); |
5254 | 5368 | ||
5255 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
5256 | /* | ||
5257 | * Input-jack notification support | ||
5258 | */ | ||
5259 | struct hda_jack_item { | ||
5260 | hda_nid_t nid; | ||
5261 | int type; | ||
5262 | struct snd_jack *jack; | ||
5263 | }; | ||
5264 | |||
5265 | static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, | ||
5266 | int type) | ||
5267 | { | ||
5268 | switch (type) { | ||
5269 | case SND_JACK_HEADPHONE: | ||
5270 | return "Headphone"; | ||
5271 | case SND_JACK_MICROPHONE: | ||
5272 | return "Mic"; | ||
5273 | case SND_JACK_LINEOUT: | ||
5274 | return "Line-out"; | ||
5275 | case SND_JACK_LINEIN: | ||
5276 | return "Line-in"; | ||
5277 | case SND_JACK_HEADSET: | ||
5278 | return "Headset"; | ||
5279 | case SND_JACK_VIDEOOUT: | ||
5280 | return "HDMI/DP"; | ||
5281 | default: | ||
5282 | return "Misc"; | ||
5283 | } | ||
5284 | } | ||
5285 | |||
5286 | static void hda_free_jack_priv(struct snd_jack *jack) | ||
5287 | { | ||
5288 | struct hda_jack_item *jacks = jack->private_data; | ||
5289 | jacks->nid = 0; | ||
5290 | jacks->jack = NULL; | ||
5291 | } | ||
5292 | |||
5293 | int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, | ||
5294 | const char *name) | ||
5295 | { | ||
5296 | struct hda_jack_item *jack; | ||
5297 | int err; | ||
5298 | |||
5299 | snd_array_init(&codec->jacks, sizeof(*jack), 32); | ||
5300 | jack = snd_array_new(&codec->jacks); | ||
5301 | if (!jack) | ||
5302 | return -ENOMEM; | ||
5303 | |||
5304 | jack->nid = nid; | ||
5305 | jack->type = type; | ||
5306 | if (!name) | ||
5307 | name = get_jack_default_name(codec, nid, type); | ||
5308 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | ||
5309 | if (err < 0) { | ||
5310 | jack->nid = 0; | ||
5311 | return err; | ||
5312 | } | ||
5313 | jack->jack->private_data = jack; | ||
5314 | jack->jack->private_free = hda_free_jack_priv; | ||
5315 | return 0; | ||
5316 | } | ||
5317 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); | ||
5318 | |||
5319 | void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) | ||
5320 | { | ||
5321 | struct hda_jack_item *jacks = codec->jacks.list; | ||
5322 | int i; | ||
5323 | |||
5324 | if (!jacks) | ||
5325 | return; | ||
5326 | |||
5327 | for (i = 0; i < codec->jacks.used; i++, jacks++) { | ||
5328 | unsigned int pin_ctl; | ||
5329 | unsigned int present; | ||
5330 | int type; | ||
5331 | |||
5332 | if (jacks->nid != nid) | ||
5333 | continue; | ||
5334 | present = snd_hda_jack_detect(codec, nid); | ||
5335 | type = jacks->type; | ||
5336 | if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { | ||
5337 | pin_ctl = snd_hda_codec_read(codec, nid, 0, | ||
5338 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5339 | type = (pin_ctl & AC_PINCTL_HP_EN) ? | ||
5340 | SND_JACK_HEADPHONE : SND_JACK_LINEOUT; | ||
5341 | } | ||
5342 | snd_jack_report(jacks->jack, present ? type : 0); | ||
5343 | } | ||
5344 | } | ||
5345 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); | ||
5346 | |||
5347 | /* free jack instances manually when clearing/reconfiguring */ | ||
5348 | void snd_hda_input_jack_free(struct hda_codec *codec) | ||
5349 | { | ||
5350 | if (!codec->bus->shutdown && codec->jacks.list) { | ||
5351 | struct hda_jack_item *jacks = codec->jacks.list; | ||
5352 | int i; | ||
5353 | for (i = 0; i < codec->jacks.used; i++, jacks++) { | ||
5354 | if (jacks->jack) | ||
5355 | snd_device_free(codec->bus->card, jacks->jack); | ||
5356 | } | ||
5357 | } | ||
5358 | snd_array_free(&codec->jacks); | ||
5359 | } | ||
5360 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_free); | ||
5361 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
5362 | |||
5363 | MODULE_DESCRIPTION("HDA codec core"); | 5369 | MODULE_DESCRIPTION("HDA codec core"); |
5364 | MODULE_LICENSE("GPL"); | 5370 | MODULE_LICENSE("GPL"); |