diff options
-rw-r--r-- | sound/pci/hda/hda_generic.c | 164 |
1 files changed, 135 insertions, 29 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 06d721085e72..63b69f750d8e 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -40,7 +40,12 @@ | |||
40 | #include "hda_generic.h" | 40 | #include "hda_generic.h" |
41 | 41 | ||
42 | 42 | ||
43 | /* initialize hda_gen_spec struct */ | 43 | /** |
44 | * snd_hda_gen_spec_init - initialize hda_gen_spec struct | ||
45 | * @spec: hda_gen_spec object to initialize | ||
46 | * | ||
47 | * Initialize the given hda_gen_spec object. | ||
48 | */ | ||
44 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec) | 49 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec) |
45 | { | 50 | { |
46 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | 51 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); |
@@ -51,6 +56,17 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec) | |||
51 | } | 56 | } |
52 | EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); | 57 | EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); |
53 | 58 | ||
59 | /** | ||
60 | * snd_hda_gen_add_kctl - Add a new kctl_new struct from the template | ||
61 | * @spec: hda_gen_spec object | ||
62 | * @name: name string to override the template, NULL if unchanged | ||
63 | * @temp: template for the new kctl | ||
64 | * | ||
65 | * Add a new kctl (actually snd_kcontrol_new to be instantiated later) | ||
66 | * element based on the given snd_kcontrol_new template @temp and the | ||
67 | * name string @name to the list in @spec. | ||
68 | * Returns the newly created object or NULL as error. | ||
69 | */ | ||
54 | struct snd_kcontrol_new * | 70 | struct snd_kcontrol_new * |
55 | snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, | 71 | snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, |
56 | const struct snd_kcontrol_new *temp) | 72 | const struct snd_kcontrol_new *temp) |
@@ -259,8 +275,14 @@ static struct nid_path *get_nid_path(struct hda_codec *codec, | |||
259 | return NULL; | 275 | return NULL; |
260 | } | 276 | } |
261 | 277 | ||
262 | /* get the path between the given NIDs; | 278 | /** |
263 | * passing 0 to either @pin or @dac behaves as a wildcard | 279 | * snd_hda_get_nid_path - get the path between the given NIDs |
280 | * @codec: the HDA codec | ||
281 | * @from_nid: the NID where the path start from | ||
282 | * @to_nid: the NID where the path ends at | ||
283 | * | ||
284 | * Return the found nid_path object or NULL for error. | ||
285 | * Passing 0 to either @from_nid or @to_nid behaves as a wildcard. | ||
264 | */ | 286 | */ |
265 | struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, | 287 | struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, |
266 | hda_nid_t from_nid, hda_nid_t to_nid) | 288 | hda_nid_t from_nid, hda_nid_t to_nid) |
@@ -269,8 +291,14 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, | |||
269 | } | 291 | } |
270 | EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); | 292 | EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); |
271 | 293 | ||
272 | /* get the index number corresponding to the path instance; | 294 | /** |
273 | * the index starts from 1, for easier checking the invalid value | 295 | * snd_hda_get_path_idx - get the index number corresponding to the path |
296 | * instance | ||
297 | * @codec: the HDA codec | ||
298 | * @path: nid_path object | ||
299 | * | ||
300 | * The returned index starts from 1, i.e. the actual array index with offset 1, | ||
301 | * and zero is handled as an invalid path | ||
274 | */ | 302 | */ |
275 | int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) | 303 | int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) |
276 | { | 304 | { |
@@ -287,7 +315,12 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) | |||
287 | } | 315 | } |
288 | EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); | 316 | EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); |
289 | 317 | ||
290 | /* get the path instance corresponding to the given index number */ | 318 | /** |
319 | * snd_hda_get_path_from_idx - get the path instance corresponding to the | ||
320 | * given index number | ||
321 | * @codec: the HDA codec | ||
322 | * @idx: the path index | ||
323 | */ | ||
291 | struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) | 324 | struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) |
292 | { | 325 | { |
293 | struct hda_gen_spec *spec = codec->spec; | 326 | struct hda_gen_spec *spec = codec->spec; |
@@ -415,7 +448,18 @@ static bool __parse_nid_path(struct hda_codec *codec, | |||
415 | return true; | 448 | return true; |
416 | } | 449 | } |
417 | 450 | ||
418 | /* parse the widget path from the given nid to the target nid; | 451 | /** |
452 | * snd_hda_parse_nid_path - parse the widget path from the given nid to | ||
453 | * the target nid | ||
454 | * @codec: the HDA codec | ||
455 | * @from_nid: the NID where the path start from | ||
456 | * @to_nid: the NID where the path ends at | ||
457 | * @anchor_nid: the anchor indication | ||
458 | * @path: the path object to store the result | ||
459 | * | ||
460 | * Returns true if a matching path is found. | ||
461 | * | ||
462 | * The parsing behavior depends on parameters: | ||
419 | * when @from_nid is 0, try to find an empty DAC; | 463 | * when @from_nid is 0, try to find an empty DAC; |
420 | * when @anchor_nid is set to a positive value, only paths through the widget | 464 | * when @anchor_nid is set to a positive value, only paths through the widget |
421 | * with the given value are evaluated. | 465 | * with the given value are evaluated. |
@@ -436,9 +480,15 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, | |||
436 | } | 480 | } |
437 | EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); | 481 | EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); |
438 | 482 | ||
439 | /* | 483 | /** |
440 | * parse the path between the given NIDs and add to the path list. | 484 | * snd_hda_add_new_path - parse the path between the given NIDs and |
441 | * if no valid path is found, return NULL | 485 | * add to the path list |
486 | * @codec: the HDA codec | ||
487 | * @from_nid: the NID where the path start from | ||
488 | * @to_nid: the NID where the path ends at | ||
489 | * @anchor_nid: the anchor indication, see snd_hda_parse_nid_path() | ||
490 | * | ||
491 | * If no valid path is found, returns NULL. | ||
442 | */ | 492 | */ |
443 | struct nid_path * | 493 | struct nid_path * |
444 | snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, | 494 | snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, |
@@ -724,8 +774,14 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, | |||
724 | } | 774 | } |
725 | } | 775 | } |
726 | 776 | ||
727 | /* activate or deactivate the given path | 777 | /** |
728 | * if @add_aamix is set, enable the input from aa-mix NID as well (if any) | 778 | * snd_hda_activate_path - activate or deactivate the given path |
779 | * @codec: the HDA codec | ||
780 | * @path: the path to activate/deactivate | ||
781 | * @enable: flag to activate or not | ||
782 | * @add_aamix: enable the input from aamix NID | ||
783 | * | ||
784 | * If @add_aamix is set, enable the input from aa-mix NID as well (if any). | ||
729 | */ | 785 | */ |
730 | void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, | 786 | void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, |
731 | bool enable, bool add_aamix) | 787 | bool enable, bool add_aamix) |
@@ -3883,7 +3939,12 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
3883 | } | 3939 | } |
3884 | } | 3940 | } |
3885 | 3941 | ||
3886 | /* Toggle outputs muting */ | 3942 | /** |
3943 | * snd_hda_gen_update_outputs - Toggle outputs muting | ||
3944 | * @codec: the HDA codec | ||
3945 | * | ||
3946 | * Update the mute status of all outputs based on the current jack states. | ||
3947 | */ | ||
3887 | void snd_hda_gen_update_outputs(struct hda_codec *codec) | 3948 | void snd_hda_gen_update_outputs(struct hda_codec *codec) |
3888 | { | 3949 | { |
3889 | struct hda_gen_spec *spec = codec->spec; | 3950 | struct hda_gen_spec *spec = codec->spec; |
@@ -3944,7 +4005,11 @@ static void call_update_outputs(struct hda_codec *codec) | |||
3944 | snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false); | 4005 | snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false); |
3945 | } | 4006 | } |
3946 | 4007 | ||
3947 | /* standard HP-automute helper */ | 4008 | /** |
4009 | * snd_hda_gen_hp_automute - standard HP-automute helper | ||
4010 | * @codec: the HDA codec | ||
4011 | * @jack: jack object, NULL for the whole | ||
4012 | */ | ||
3948 | void snd_hda_gen_hp_automute(struct hda_codec *codec, | 4013 | void snd_hda_gen_hp_automute(struct hda_codec *codec, |
3949 | struct hda_jack_callback *jack) | 4014 | struct hda_jack_callback *jack) |
3950 | { | 4015 | { |
@@ -3965,7 +4030,11 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, | |||
3965 | } | 4030 | } |
3966 | EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); | 4031 | EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); |
3967 | 4032 | ||
3968 | /* standard line-out-automute helper */ | 4033 | /** |
4034 | * snd_hda_gen_line_automute - standard line-out-automute helper | ||
4035 | * @codec: the HDA codec | ||
4036 | * @jack: jack object, NULL for the whole | ||
4037 | */ | ||
3969 | void snd_hda_gen_line_automute(struct hda_codec *codec, | 4038 | void snd_hda_gen_line_automute(struct hda_codec *codec, |
3970 | struct hda_jack_callback *jack) | 4039 | struct hda_jack_callback *jack) |
3971 | { | 4040 | { |
@@ -3986,7 +4055,11 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, | |||
3986 | } | 4055 | } |
3987 | EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); | 4056 | EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); |
3988 | 4057 | ||
3989 | /* standard mic auto-switch helper */ | 4058 | /** |
4059 | * snd_hda_gen_mic_autoswitch - standard mic auto-switch helper | ||
4060 | * @codec: the HDA codec | ||
4061 | * @jack: jack object, NULL for the whole | ||
4062 | */ | ||
3990 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, | 4063 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, |
3991 | struct hda_jack_callback *jack) | 4064 | struct hda_jack_callback *jack) |
3992 | { | 4065 | { |
@@ -4318,7 +4391,13 @@ static int check_auto_mic_availability(struct hda_codec *codec) | |||
4318 | return 0; | 4391 | return 0; |
4319 | } | 4392 | } |
4320 | 4393 | ||
4321 | /* power_filter hook; make inactive widgets into power down */ | 4394 | /** |
4395 | * snd_hda_gen_path_power_filter - power_filter hook to make inactive widgets | ||
4396 | * into power down | ||
4397 | * @codec: the HDA codec | ||
4398 | * @nid: NID to evalute | ||
4399 | * @power_state: target power state | ||
4400 | */ | ||
4322 | unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | 4401 | unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, |
4323 | hda_nid_t nid, | 4402 | hda_nid_t nid, |
4324 | unsigned int power_state) | 4403 | unsigned int power_state) |
@@ -4354,8 +4433,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) | |||
4354 | } | 4433 | } |
4355 | } | 4434 | } |
4356 | 4435 | ||
4357 | /* | 4436 | /** |
4358 | * Parse the given BIOS configuration and set up the hda_gen_spec | 4437 | * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and |
4438 | * set up the hda_gen_spec | ||
4439 | * @codec: the HDA codec | ||
4440 | * @cfg: Parsed pin configuration | ||
4359 | * | 4441 | * |
4360 | * return 1 if successful, 0 if the proper config is not found, | 4442 | * return 1 if successful, 0 if the proper config is not found, |
4361 | * or a negative error code | 4443 | * or a negative error code |
@@ -4541,6 +4623,12 @@ static const char * const slave_pfxs[] = { | |||
4541 | NULL, | 4623 | NULL, |
4542 | }; | 4624 | }; |
4543 | 4625 | ||
4626 | /** | ||
4627 | * snd_hda_gen_build_controls - Build controls from the parsed results | ||
4628 | * @codec: the HDA codec | ||
4629 | * | ||
4630 | * Pass this to build_controls patch_ops. | ||
4631 | */ | ||
4544 | int snd_hda_gen_build_controls(struct hda_codec *codec) | 4632 | int snd_hda_gen_build_controls(struct hda_codec *codec) |
4545 | { | 4633 | { |
4546 | struct hda_gen_spec *spec = codec->spec; | 4634 | struct hda_gen_spec *spec = codec->spec; |
@@ -5018,7 +5106,12 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, | |||
5018 | strlcat(str, sfx, len); | 5106 | strlcat(str, sfx, len); |
5019 | } | 5107 | } |
5020 | 5108 | ||
5021 | /* build PCM streams based on the parsed results */ | 5109 | /** |
5110 | * snd_hda_gen_build_pcms - build PCM streams based on the parsed results | ||
5111 | * @codec: the HDA codec | ||
5112 | * | ||
5113 | * Pass this to build_pcms patch_ops. | ||
5114 | */ | ||
5022 | int snd_hda_gen_build_pcms(struct hda_codec *codec) | 5115 | int snd_hda_gen_build_pcms(struct hda_codec *codec) |
5023 | { | 5116 | { |
5024 | struct hda_gen_spec *spec = codec->spec; | 5117 | struct hda_gen_spec *spec = codec->spec; |
@@ -5313,9 +5406,11 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec) | |||
5313 | } | 5406 | } |
5314 | } | 5407 | } |
5315 | 5408 | ||
5316 | /* | 5409 | /** |
5317 | * initialize the generic spec; | 5410 | * snd_hda_gen_init - initialize the generic spec |
5318 | * this can be put as patch_ops.init function | 5411 | * @codec: the HDA codec |
5412 | * | ||
5413 | * This can be put as patch_ops init function. | ||
5319 | */ | 5414 | */ |
5320 | int snd_hda_gen_init(struct hda_codec *codec) | 5415 | int snd_hda_gen_init(struct hda_codec *codec) |
5321 | { | 5416 | { |
@@ -5351,9 +5446,11 @@ int snd_hda_gen_init(struct hda_codec *codec) | |||
5351 | } | 5446 | } |
5352 | EXPORT_SYMBOL_GPL(snd_hda_gen_init); | 5447 | EXPORT_SYMBOL_GPL(snd_hda_gen_init); |
5353 | 5448 | ||
5354 | /* | 5449 | /** |
5355 | * free the generic spec; | 5450 | * snd_hda_gen_free - free the generic spec |
5356 | * this can be put as patch_ops.free function | 5451 | * @codec: the HDA codec |
5452 | * | ||
5453 | * This can be put as patch_ops free function. | ||
5357 | */ | 5454 | */ |
5358 | void snd_hda_gen_free(struct hda_codec *codec) | 5455 | void snd_hda_gen_free(struct hda_codec *codec) |
5359 | { | 5456 | { |
@@ -5365,9 +5462,12 @@ void snd_hda_gen_free(struct hda_codec *codec) | |||
5365 | EXPORT_SYMBOL_GPL(snd_hda_gen_free); | 5462 | EXPORT_SYMBOL_GPL(snd_hda_gen_free); |
5366 | 5463 | ||
5367 | #ifdef CONFIG_PM | 5464 | #ifdef CONFIG_PM |
5368 | /* | 5465 | /** |
5369 | * check the loopback power save state; | 5466 | * snd_hda_gen_check_power_status - check the loopback power save state |
5370 | * this can be put as patch_ops.check_power_status function | 5467 | * @codec: the HDA codec |
5468 | * @nid: NID to inspect | ||
5469 | * | ||
5470 | * This can be put as patch_ops check_power_status function. | ||
5371 | */ | 5471 | */ |
5372 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 5472 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
5373 | { | 5473 | { |
@@ -5393,6 +5493,12 @@ static const struct hda_codec_ops generic_patch_ops = { | |||
5393 | #endif | 5493 | #endif |
5394 | }; | 5494 | }; |
5395 | 5495 | ||
5496 | /** | ||
5497 | * snd_hda_parse_generic_codec - Generic codec parser | ||
5498 | * @codec: the HDA codec | ||
5499 | * | ||
5500 | * This should be called from the HDA codec core. | ||
5501 | */ | ||
5396 | int snd_hda_parse_generic_codec(struct hda_codec *codec) | 5502 | int snd_hda_parse_generic_codec(struct hda_codec *codec) |
5397 | { | 5503 | { |
5398 | struct hda_gen_spec *spec; | 5504 | struct hda_gen_spec *spec; |