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>
This commit is contained in:
parent
39ed68c8cd
commit
fa880775ab
|
@ -444,6 +444,9 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
|
|||
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
|
||||
struct snd_kcontrol *kcontrol);
|
||||
|
||||
int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
|
||||
enum snd_soc_bias_level level);
|
||||
|
||||
/* dapm widget types */
|
||||
enum snd_soc_dapm_type {
|
||||
snd_soc_dapm_input = 0, /* input pin */
|
||||
|
@ -623,4 +626,35 @@ struct snd_soc_dapm_stats {
|
|||
int neighbour_checks;
|
||||
};
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
|
||||
* @dapm: The DAPM context to initialize
|
||||
* @level: The DAPM level to initialize to
|
||||
*
|
||||
* This function only sets the driver internal state of the DAPM level and will
|
||||
* not modify the state of the device. Hence it should not be used during normal
|
||||
* operation, but only to synchronize the internal state to the device state.
|
||||
* E.g. during driver probe to set the DAPM level to the one corresponding with
|
||||
* the power-on reset state of the device.
|
||||
*
|
||||
* To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
|
||||
*/
|
||||
static inline void snd_soc_dapm_init_bias_level(
|
||||
struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
|
||||
{
|
||||
dapm->bias_level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_get_bias_level() - Get current DAPM bias level
|
||||
* @dapm: The context for which to get the bias level
|
||||
*
|
||||
* Returns: The current bias level of the passed DAPM context.
|
||||
*/
|
||||
static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
|
||||
struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
return dapm->bias_level;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1281,6 +1281,46 @@ static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
|
|||
return &codec->dapm;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
|
||||
* @dapm: The CODEC for which to initialize the DAPM bias level
|
||||
* @level: The DAPM level to initialize to
|
||||
*
|
||||
* Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
|
||||
*/
|
||||
static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
|
||||
* @codec: The CODEC for which to get the DAPM bias level
|
||||
*
|
||||
* Returns: The current DAPM bias level of the CODEC.
|
||||
*/
|
||||
static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
|
||||
struct snd_soc_codec *codec)
|
||||
{
|
||||
return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
|
||||
* @codec: The CODEC for which to set the level
|
||||
* @level: The level to set to
|
||||
*
|
||||
* Forces the CODEC bias level to a specific state. See
|
||||
* snd_soc_dapm_force_bias_level().
|
||||
*/
|
||||
static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
|
||||
level);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
|
||||
* @kcontrol: The kcontrol
|
||||
|
|
|
@ -525,6 +525,35 @@ static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
|
|||
snd_soc_component_async_complete(dapm->component);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_force_bias_level() - Sets the DAPM bias level
|
||||
* @dapm: The DAPM context for which to set the level
|
||||
* @level: The level to set
|
||||
*
|
||||
* Forces the DAPM bias level to a specific state. It will call the bias level
|
||||
* callback of DAPM context with the specified level. This will even happen if
|
||||
* the context is already at the same level. Furthermore it will not go through
|
||||
* the normal bias level sequencing, meaning any intermediate states between the
|
||||
* current and the target state will not be entered.
|
||||
*
|
||||
* Note that the change in bias level is only temporary and the next time
|
||||
* snd_soc_dapm_sync() is called the state will be set to the level as
|
||||
* determined by the DAPM core. The function is mainly intended to be used to
|
||||
* used during probe or resume from suspend to power up the device so
|
||||
* initialization can be done, before the DAPM core takes over.
|
||||
*/
|
||||
int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (dapm->set_bias_level)
|
||||
ret = dapm->set_bias_level(dapm, level);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_bias_level);
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_set_bias_level - set the bias level for the system
|
||||
* @dapm: DAPM context
|
||||
|
@ -547,10 +576,8 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
|
|||
if (ret != 0)
|
||||
goto out;
|
||||
|
||||
if (dapm->set_bias_level)
|
||||
ret = dapm->set_bias_level(dapm, level);
|
||||
else if (!card || dapm != &card->dapm)
|
||||
dapm->bias_level = level;
|
||||
if (!card || dapm != &card->dapm)
|
||||
ret = snd_soc_dapm_force_bias_level(dapm, level);
|
||||
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
|
|
Loading…
Reference in New Issue