ASoC: cs42l51: add power management
Add sleep PM callbacks to support system low power modes. Signed-off-by: Olivier Moysan <olivier.moysan@st.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
2f7c4ce09a
Коммит
75a714823e
|
@ -29,8 +29,6 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c,
|
|||
struct regmap_config config;
|
||||
|
||||
config = cs42l51_regmap;
|
||||
config.val_bits = 8;
|
||||
config.reg_bits = 8;
|
||||
|
||||
return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config));
|
||||
}
|
||||
|
@ -40,10 +38,15 @@ static int cs42l51_i2c_remove(struct i2c_client *i2c)
|
|||
return cs42l51_remove(&i2c->dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops cs42l51_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(cs42l51_suspend, cs42l51_resume)
|
||||
};
|
||||
|
||||
static struct i2c_driver cs42l51_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs42l51",
|
||||
.of_match_table = cs42l51_of_match,
|
||||
.pm = &cs42l51_pm_ops,
|
||||
},
|
||||
.probe = cs42l51_i2c_probe,
|
||||
.remove = cs42l51_i2c_remove,
|
||||
|
|
|
@ -56,6 +56,7 @@ struct cs42l51_private {
|
|||
enum master_slave_mode func;
|
||||
struct regulator_bulk_data supplies[ARRAY_SIZE(cs42l51_supply_names)];
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
#define CS42L51_FORMATS ( \
|
||||
|
@ -575,7 +576,106 @@ static const struct snd_soc_component_driver soc_component_device_cs42l51 = {
|
|||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static bool cs42l51_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case CS42L51_POWER_CTL1:
|
||||
case CS42L51_MIC_POWER_CTL:
|
||||
case CS42L51_INTF_CTL:
|
||||
case CS42L51_MIC_CTL:
|
||||
case CS42L51_ADC_CTL:
|
||||
case CS42L51_ADC_INPUT:
|
||||
case CS42L51_DAC_OUT_CTL:
|
||||
case CS42L51_DAC_CTL:
|
||||
case CS42L51_ALC_PGA_CTL:
|
||||
case CS42L51_ALC_PGB_CTL:
|
||||
case CS42L51_ADCA_ATT:
|
||||
case CS42L51_ADCB_ATT:
|
||||
case CS42L51_ADCA_VOL:
|
||||
case CS42L51_ADCB_VOL:
|
||||
case CS42L51_PCMA_VOL:
|
||||
case CS42L51_PCMB_VOL:
|
||||
case CS42L51_BEEP_FREQ:
|
||||
case CS42L51_BEEP_VOL:
|
||||
case CS42L51_BEEP_CONF:
|
||||
case CS42L51_TONE_CTL:
|
||||
case CS42L51_AOUTA_VOL:
|
||||
case CS42L51_AOUTB_VOL:
|
||||
case CS42L51_PCM_MIXER:
|
||||
case CS42L51_LIMIT_THRES_DIS:
|
||||
case CS42L51_LIMIT_REL:
|
||||
case CS42L51_LIMIT_ATT:
|
||||
case CS42L51_ALC_EN:
|
||||
case CS42L51_ALC_REL:
|
||||
case CS42L51_ALC_THRES:
|
||||
case CS42L51_NOISE_CONF:
|
||||
case CS42L51_CHARGE_FREQ:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool cs42l51_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case CS42L51_STATUS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool cs42l51_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case CS42L51_CHIP_REV_ID:
|
||||
case CS42L51_POWER_CTL1:
|
||||
case CS42L51_MIC_POWER_CTL:
|
||||
case CS42L51_INTF_CTL:
|
||||
case CS42L51_MIC_CTL:
|
||||
case CS42L51_ADC_CTL:
|
||||
case CS42L51_ADC_INPUT:
|
||||
case CS42L51_DAC_OUT_CTL:
|
||||
case CS42L51_DAC_CTL:
|
||||
case CS42L51_ALC_PGA_CTL:
|
||||
case CS42L51_ALC_PGB_CTL:
|
||||
case CS42L51_ADCA_ATT:
|
||||
case CS42L51_ADCB_ATT:
|
||||
case CS42L51_ADCA_VOL:
|
||||
case CS42L51_ADCB_VOL:
|
||||
case CS42L51_PCMA_VOL:
|
||||
case CS42L51_PCMB_VOL:
|
||||
case CS42L51_BEEP_FREQ:
|
||||
case CS42L51_BEEP_VOL:
|
||||
case CS42L51_BEEP_CONF:
|
||||
case CS42L51_TONE_CTL:
|
||||
case CS42L51_AOUTA_VOL:
|
||||
case CS42L51_AOUTB_VOL:
|
||||
case CS42L51_PCM_MIXER:
|
||||
case CS42L51_LIMIT_THRES_DIS:
|
||||
case CS42L51_LIMIT_REL:
|
||||
case CS42L51_LIMIT_ATT:
|
||||
case CS42L51_ALC_EN:
|
||||
case CS42L51_ALC_REL:
|
||||
case CS42L51_ALC_THRES:
|
||||
case CS42L51_NOISE_CONF:
|
||||
case CS42L51_STATUS:
|
||||
case CS42L51_CHARGE_FREQ:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const struct regmap_config cs42l51_regmap = {
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
.use_single_write = true,
|
||||
.readable_reg = cs42l51_readable_reg,
|
||||
.volatile_reg = cs42l51_volatile_reg,
|
||||
.writeable_reg = cs42l51_writeable_reg,
|
||||
.max_register = CS42L51_CHARGE_FREQ,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
@ -596,6 +696,7 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
|
|||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, cs42l51);
|
||||
cs42l51->regmap = regmap;
|
||||
|
||||
cs42l51->mclk_handle = devm_clk_get(dev, "MCLK");
|
||||
if (IS_ERR(cs42l51->mclk_handle)) {
|
||||
|
@ -673,6 +774,27 @@ int cs42l51_remove(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cs42l51_remove);
|
||||
|
||||
int __maybe_unused cs42l51_suspend(struct device *dev)
|
||||
{
|
||||
struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(cs42l51->regmap, true);
|
||||
regcache_mark_dirty(cs42l51->regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cs42l51_suspend);
|
||||
|
||||
int __maybe_unused cs42l51_resume(struct device *dev)
|
||||
{
|
||||
struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(cs42l51->regmap, false);
|
||||
|
||||
return regcache_sync(cs42l51->regmap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cs42l51_resume);
|
||||
|
||||
const struct of_device_id cs42l51_of_match[] = {
|
||||
{ .compatible = "cirrus,cs42l51", },
|
||||
{ }
|
||||
|
|
|
@ -23,6 +23,8 @@ struct device;
|
|||
extern const struct regmap_config cs42l51_regmap;
|
||||
int cs42l51_probe(struct device *dev, struct regmap *regmap);
|
||||
int cs42l51_remove(struct device *dev);
|
||||
int __maybe_unused cs42l51_suspend(struct device *dev);
|
||||
int __maybe_unused cs42l51_resume(struct device *dev);
|
||||
extern const struct of_device_id cs42l51_of_match[];
|
||||
|
||||
#define CS42L51_CHIP_ID 0x1B
|
||||
|
|
Загрузка…
Ссылка в новой задаче