diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2015-04-27 16:13:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-04-27 16:34:45 -0400 |
commit | fa880775ab0d5a8d540972f7b6800fad1af16b75 (patch) | |
tree | 201bcfeaaccfb233e674bd10ac8d834520bc7025 | |
parent | 39ed68c8cd3aff417603a95d0594308598b9f469 (diff) |
ASoC: Add helper functions bias level management
Currently drivers are responsible for managing the bias_level field of
their DAPM context. The DAPM state itself is managed by the DAPM core
though and the core has certain expectations on how and when the bias_level
field should be updated. If drivers don't adhere to these undefined
behavior can occur.
This patch adds a few helper functions for manipulating the DAPM context
state, each function with a description on when it should be used and what
its effects are. This will also help us to move more of the bias_level
management from drivers to the DAPM core.
For convenience also add snd_soc_codec_* wrappers around these helpers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | include/sound/soc-dapm.h | 34 | ||||
-rw-r--r-- | include/sound/soc.h | 40 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 35 |
3 files changed, 105 insertions, 4 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 0bc83647d3fa..70216d20e897 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -444,6 +444,9 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, | |||
444 | struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( | 444 | struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( |
445 | struct snd_kcontrol *kcontrol); | 445 | struct snd_kcontrol *kcontrol); |
446 | 446 | ||
447 | int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, | ||
448 | enum snd_soc_bias_level level); | ||
449 | |||
447 | /* dapm widget types */ | 450 | /* dapm widget types */ |
448 | enum snd_soc_dapm_type { | 451 | enum snd_soc_dapm_type { |
449 | snd_soc_dapm_input = 0, /* input pin */ | 452 | snd_soc_dapm_input = 0, /* input pin */ |
@@ -623,4 +626,35 @@ struct snd_soc_dapm_stats { | |||
623 | int neighbour_checks; | 626 | int neighbour_checks; |
624 | }; | 627 | }; |
625 | 628 | ||
629 | /** | ||
630 | * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level | ||
631 | * @dapm: The DAPM context to initialize | ||
632 | * @level: The DAPM level to initialize to | ||
633 | * | ||
634 | * This function only sets the driver internal state of the DAPM level and will | ||
635 | * not modify the state of the device. Hence it should not be used during normal | ||
636 | * operation, but only to synchronize the internal state to the device state. | ||
637 | * E.g. during driver probe to set the DAPM level to the one corresponding with | ||
638 | * the power-on reset state of the device. | ||
639 | * | ||
640 | * To change the DAPM state of the device use snd_soc_dapm_set_bias_level(). | ||
641 | */ | ||
642 | static inline void snd_soc_dapm_init_bias_level( | ||
643 | struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) | ||
644 | { | ||
645 | dapm->bias_level = level; | ||
646 | } | ||
647 | |||
648 | /** | ||
649 | * snd_soc_dapm_get_bias_level() - Get current DAPM bias level | ||
650 | * @dapm: The context for which to get the bias level | ||
651 | * | ||
652 | * Returns: The current bias level of the passed DAPM context. | ||
653 | */ | ||
654 | static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level( | ||
655 | struct snd_soc_dapm_context *dapm) | ||
656 | { | ||
657 | return dapm->bias_level; | ||
658 | } | ||
659 | |||
626 | #endif | 660 | #endif |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 2f742009da4b..7781bfe85c5d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -1282,6 +1282,46 @@ static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm( | |||
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /** | 1284 | /** |
1285 | * snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level | ||
1286 | * @dapm: The CODEC for which to initialize the DAPM bias level | ||
1287 | * @level: The DAPM level to initialize to | ||
1288 | * | ||
1289 | * Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level(). | ||
1290 | */ | ||
1291 | static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec, | ||
1292 | enum snd_soc_bias_level level) | ||
1293 | { | ||
1294 | snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level); | ||
1295 | } | ||
1296 | |||
1297 | /** | ||
1298 | * snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level | ||
1299 | * @codec: The CODEC for which to get the DAPM bias level | ||
1300 | * | ||
1301 | * Returns: The current DAPM bias level of the CODEC. | ||
1302 | */ | ||
1303 | static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level( | ||
1304 | struct snd_soc_codec *codec) | ||
1305 | { | ||
1306 | return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec)); | ||
1307 | } | ||
1308 | |||
1309 | /** | ||
1310 | * snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level | ||
1311 | * @codec: The CODEC for which to set the level | ||
1312 | * @level: The level to set to | ||
1313 | * | ||
1314 | * Forces the CODEC bias level to a specific state. See | ||
1315 | * snd_soc_dapm_force_bias_level(). | ||
1316 | */ | ||
1317 | static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec, | ||
1318 | enum snd_soc_bias_level level) | ||
1319 | { | ||
1320 | return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec), | ||
1321 | level); | ||
1322 | } | ||
1323 | |||
1324 | /** | ||
1285 | * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol | 1325 | * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol |
1286 | * @kcontrol: The kcontrol | 1326 | * @kcontrol: The kcontrol |
1287 | * | 1327 | * |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index defe0f0082b5..b24782b50809 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -526,6 +526,35 @@ static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) | |||
526 | } | 526 | } |
527 | 527 | ||
528 | /** | 528 | /** |
529 | * snd_soc_dapm_force_bias_level() - Sets the DAPM bias level | ||
530 | * @dapm: The DAPM context for which to set the level | ||
531 | * @level: The level to set | ||
532 | * | ||
533 | * Forces the DAPM bias level to a specific state. It will call the bias level | ||
534 | * callback of DAPM context with the specified level. This will even happen if | ||
535 | * the context is already at the same level. Furthermore it will not go through | ||
536 | * the normal bias level sequencing, meaning any intermediate states between the | ||
537 | * current and the target state will not be entered. | ||
538 | * | ||
539 | * Note that the change in bias level is only temporary and the next time | ||
540 | * snd_soc_dapm_sync() is called the state will be set to the level as | ||
541 | * determined by the DAPM core. The function is mainly intended to be used to | ||
542 | * used during probe or resume from suspend to power up the device so | ||
543 | * initialization can be done, before the DAPM core takes over. | ||
544 | */ | ||
545 | int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, | ||
546 | enum snd_soc_bias_level level) | ||
547 | { | ||
548 | int ret = 0; | ||
549 | |||
550 | if (dapm->set_bias_level) | ||
551 | ret = dapm->set_bias_level(dapm, level); | ||
552 | |||
553 | return ret; | ||
554 | } | ||
555 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_bias_level); | ||
556 | |||
557 | /** | ||
529 | * snd_soc_dapm_set_bias_level - set the bias level for the system | 558 | * snd_soc_dapm_set_bias_level - set the bias level for the system |
530 | * @dapm: DAPM context | 559 | * @dapm: DAPM context |
531 | * @level: level to configure | 560 | * @level: level to configure |
@@ -547,10 +576,8 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm, | |||
547 | if (ret != 0) | 576 | if (ret != 0) |
548 | goto out; | 577 | goto out; |
549 | 578 | ||
550 | if (dapm->set_bias_level) | 579 | if (!card || dapm != &card->dapm) |
551 | ret = dapm->set_bias_level(dapm, level); | 580 | ret = snd_soc_dapm_force_bias_level(dapm, level); |
552 | else if (!card || dapm != &card->dapm) | ||
553 | dapm->bias_level = level; | ||
554 | 581 | ||
555 | if (ret != 0) | 582 | if (ret != 0) |
556 | goto out; | 583 | goto out; |