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; |
