|
@@ -637,6 +637,8 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
|
|
|
static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
|
|
|
{
|
|
|
switch (reg) {
|
|
|
+ case FSL_SAI_TCSR:
|
|
|
+ case FSL_SAI_RCSR:
|
|
|
case FSL_SAI_TFR:
|
|
|
case FSL_SAI_RFR:
|
|
|
case FSL_SAI_TDR:
|
|
@@ -681,6 +683,7 @@ static const struct regmap_config fsl_sai_regmap_config = {
|
|
|
.readable_reg = fsl_sai_readable_reg,
|
|
|
.volatile_reg = fsl_sai_volatile_reg,
|
|
|
.writeable_reg = fsl_sai_writeable_reg,
|
|
|
+ .cache_type = REGCACHE_FLAT,
|
|
|
};
|
|
|
|
|
|
static int fsl_sai_probe(struct platform_device *pdev)
|
|
@@ -802,10 +805,40 @@ static const struct of_device_id fsl_sai_ids[] = {
|
|
|
{ /* sentinel */ }
|
|
|
};
|
|
|
|
|
|
+#if CONFIG_PM_SLEEP
|
|
|
+static int fsl_sai_suspend(struct device *dev)
|
|
|
+{
|
|
|
+ struct fsl_sai *sai = dev_get_drvdata(dev);
|
|
|
+
|
|
|
+ regcache_cache_only(sai->regmap, true);
|
|
|
+ regcache_mark_dirty(sai->regmap);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int fsl_sai_resume(struct device *dev)
|
|
|
+{
|
|
|
+ struct fsl_sai *sai = dev_get_drvdata(dev);
|
|
|
+
|
|
|
+ regcache_cache_only(sai->regmap, false);
|
|
|
+ regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
|
|
|
+ regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
|
|
|
+ msleep(1);
|
|
|
+ regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
|
|
|
+ regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
|
|
|
+ return regcache_sync(sai->regmap);
|
|
|
+}
|
|
|
+#endif /* CONFIG_PM_SLEEP */
|
|
|
+
|
|
|
+static const struct dev_pm_ops fsl_sai_pm_ops = {
|
|
|
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume)
|
|
|
+};
|
|
|
+
|
|
|
static struct platform_driver fsl_sai_driver = {
|
|
|
.probe = fsl_sai_probe,
|
|
|
.driver = {
|
|
|
.name = "fsl-sai",
|
|
|
+ .pm = &fsl_sai_pm_ops,
|
|
|
.of_match_table = fsl_sai_ids,
|
|
|
},
|
|
|
};
|