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;
|
struct regmap_config config;
|
||||||
|
|
||||||
config = cs42l51_regmap;
|
config = cs42l51_regmap;
|
||||||
config.val_bits = 8;
|
|
||||||
config.reg_bits = 8;
|
|
||||||
|
|
||||||
return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config));
|
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);
|
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 = {
|
static struct i2c_driver cs42l51_i2c_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "cs42l51",
|
.name = "cs42l51",
|
||||||
.of_match_table = cs42l51_of_match,
|
.of_match_table = cs42l51_of_match,
|
||||||
|
.pm = &cs42l51_pm_ops,
|
||||||
},
|
},
|
||||||
.probe = cs42l51_i2c_probe,
|
.probe = cs42l51_i2c_probe,
|
||||||
.remove = cs42l51_i2c_remove,
|
.remove = cs42l51_i2c_remove,
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct cs42l51_private {
|
||||||
enum master_slave_mode func;
|
enum master_slave_mode func;
|
||||||
struct regulator_bulk_data supplies[ARRAY_SIZE(cs42l51_supply_names)];
|
struct regulator_bulk_data supplies[ARRAY_SIZE(cs42l51_supply_names)];
|
||||||
struct gpio_desc *reset_gpio;
|
struct gpio_desc *reset_gpio;
|
||||||
|
struct regmap *regmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CS42L51_FORMATS ( \
|
#define CS42L51_FORMATS ( \
|
||||||
|
@ -575,7 +576,106 @@ static const struct snd_soc_component_driver soc_component_device_cs42l51 = {
|
||||||
.non_legacy_dai_naming = 1,
|
.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 = {
|
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,
|
.max_register = CS42L51_CHARGE_FREQ,
|
||||||
.cache_type = REGCACHE_RBTREE,
|
.cache_type = REGCACHE_RBTREE,
|
||||||
};
|
};
|
||||||
|
@ -596,6 +696,7 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dev_set_drvdata(dev, cs42l51);
|
dev_set_drvdata(dev, cs42l51);
|
||||||
|
cs42l51->regmap = regmap;
|
||||||
|
|
||||||
cs42l51->mclk_handle = devm_clk_get(dev, "MCLK");
|
cs42l51->mclk_handle = devm_clk_get(dev, "MCLK");
|
||||||
if (IS_ERR(cs42l51->mclk_handle)) {
|
if (IS_ERR(cs42l51->mclk_handle)) {
|
||||||
|
@ -673,6 +774,27 @@ int cs42l51_remove(struct device *dev)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cs42l51_remove);
|
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[] = {
|
const struct of_device_id cs42l51_of_match[] = {
|
||||||
{ .compatible = "cirrus,cs42l51", },
|
{ .compatible = "cirrus,cs42l51", },
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -23,6 +23,8 @@ struct device;
|
||||||
extern const struct regmap_config cs42l51_regmap;
|
extern const struct regmap_config cs42l51_regmap;
|
||||||
int cs42l51_probe(struct device *dev, struct regmap *regmap);
|
int cs42l51_probe(struct device *dev, struct regmap *regmap);
|
||||||
int cs42l51_remove(struct device *dev);
|
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[];
|
extern const struct of_device_id cs42l51_of_match[];
|
||||||
|
|
||||||
#define CS42L51_CHIP_ID 0x1B
|
#define CS42L51_CHIP_ID 0x1B
|
||||||
|
|
Загрузка…
Ссылка в новой задаче