提交 20feb881 编写于 作者: L Lars-Peter Clausen 提交者: Mark Brown

ASoC: Add helper functions for deferred regmap setup

Some drivers (most notably the AC'97 drivers) do not have access to their
regmap struct when the component/codec is registered. For those drivers the
automatic regmap setup will not work and needs to be done manually,
typically from the component/CODEC drivers probe callback.

This patch adds a set of helper function to handle deferred regmap
initialization as well as early regmap tear-down.
Signed-off-by: NLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: NMark Brown <broonie@kernel.org>
上级 f114040e
...@@ -1277,6 +1277,41 @@ void snd_soc_component_async_complete(struct snd_soc_component *component); ...@@ -1277,6 +1277,41 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
int snd_soc_component_test_bits(struct snd_soc_component *component, int snd_soc_component_test_bits(struct snd_soc_component *component,
unsigned int reg, unsigned int mask, unsigned int value); unsigned int reg, unsigned int mask, unsigned int value);
void snd_soc_component_init_regmap(struct snd_soc_component *component,
struct regmap *regmap);
void snd_soc_component_exit_regmap(struct snd_soc_component *component);
/**
* snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC
* @codec: The CODEC for which to initialize the regmap instance
* @regmap: The regmap instance that should be used by the CODEC
*
* This function allows deferred assignment of the regmap instance that is
* associated with the CODEC. Only use this if the regmap instance is not yet
* ready when the CODEC is registered. The function must also be called before
* the first IO attempt of the CODEC.
*/
static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec,
struct regmap *regmap)
{
snd_soc_component_init_regmap(&codec->component, regmap);
}
/**
* snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC
* @codec: The CODEC for which to de-initialize the regmap instance
*
* Calls regmap_exit() on the regmap instance associated to the CODEC and
* removes the regmap instance from the CODEC.
*
* This function should only be used if snd_soc_codec_init_regmap() was used to
* initialize the regmap instance.
*/
static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec)
{
snd_soc_component_exit_regmap(&codec->component);
}
/* device driver data */ /* device driver data */
static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
......
...@@ -3996,22 +3996,58 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, ...@@ -3996,22 +3996,58 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
return 0; return 0;
} }
static void snd_soc_component_init_regmap(struct snd_soc_component *component) static void snd_soc_component_setup_regmap(struct snd_soc_component *component)
{ {
if (!component->regmap)
component->regmap = dev_get_regmap(component->dev, NULL);
if (component->regmap) {
int val_bytes = regmap_get_val_bytes(component->regmap); int val_bytes = regmap_get_val_bytes(component->regmap);
/* Errors are legitimate for non-integer byte multiples */ /* Errors are legitimate for non-integer byte multiples */
if (val_bytes > 0) if (val_bytes > 0)
component->val_bytes = val_bytes; component->val_bytes = val_bytes;
}
} }
/**
* snd_soc_component_init_regmap() - Initialize regmap instance for the component
* @component: The component for which to initialize the regmap instance
* @regmap: The regmap instance that should be used by the component
*
* This function allows deferred assignment of the regmap instance that is
* associated with the component. Only use this if the regmap instance is not
* yet ready when the component is registered. The function must also be called
* before the first IO attempt of the component.
*/
void snd_soc_component_init_regmap(struct snd_soc_component *component,
struct regmap *regmap)
{
component->regmap = regmap;
snd_soc_component_setup_regmap(component);
}
EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
/**
* snd_soc_component_exit_regmap() - De-initialize regmap instance for the component
* @component: The component for which to de-initialize the regmap instance
*
* Calls regmap_exit() on the regmap instance associated to the component and
* removes the regmap instance from the component.
*
* This function should only be used if snd_soc_component_init_regmap() was used
* to initialize the regmap instance.
*/
void snd_soc_component_exit_regmap(struct snd_soc_component *component)
{
regmap_exit(component->regmap);
component->regmap = NULL;
}
EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
static void snd_soc_component_add_unlocked(struct snd_soc_component *component) static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
{ {
if (!component->write && !component->read) if (!component->write && !component->read) {
snd_soc_component_init_regmap(component); if (!component->regmap)
component->regmap = dev_get_regmap(component->dev, NULL);
if (component->regmap)
snd_soc_component_setup_regmap(component);
}
list_add(&component->list, &component_list); list_add(&component->list, &component_list);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册