aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2015-04-27 16:13:23 -0400
committerMark Brown <broonie@kernel.org>2015-04-27 16:34:45 -0400
commitfa880775ab0d5a8d540972f7b6800fad1af16b75 (patch)
tree201bcfeaaccfb233e674bd10ac8d834520bc7025
parent39ed68c8cd3aff417603a95d0594308598b9f469 (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.h34
-rw-r--r--include/sound/soc.h40
-rw-r--r--sound/soc/soc-dapm.c35
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,
444struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( 444struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
445 struct snd_kcontrol *kcontrol); 445 struct snd_kcontrol *kcontrol);
446 446
447int 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 */
448enum snd_soc_dapm_type { 451enum 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 */
642static 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 */
654static 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 */
1291static 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 */
1303static 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 */
1317static 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 */
545int 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}
555EXPORT_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;