aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorZidan Wang <zidan.wang@freescale.com>2015-09-17 23:09:13 -0400
committerMark Brown <broonie@kernel.org>2015-10-05 12:26:19 -0400
commitc64c60763b4e3c72a3520c8d51be858cd67bacb5 (patch)
treec8f2fac74dd64642c782707adbc20b77ede76196 /sound/soc/fsl
parent05cf237972fe65eb537ea4f10e5627ceeb8f89b6 (diff)
ASoC: fsl_esai: Add driver suspend and resume to support MEGA Fast
For i.MX6 SoloX, there is a mode of the SoC to shutdown all power source of modules during system suspend and resume procedure. Thus, ESAI needs to save all the values of registers before the system suspend and restore them after the system resume. Signed-off-by: Zidan Wang <zidan.wang@freescale.com> Acked-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_esai.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 837979ea5c92..aab675a9d3f1 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = {
652 .name = "fsl-esai", 652 .name = "fsl-esai",
653}; 653};
654 654
655static const struct reg_default fsl_esai_reg_defaults[] = {
656 {0x8, 0x00000000},
657 {0x10, 0x00000000},
658 {0x18, 0x00000000},
659 {0x98, 0x00000000},
660 {0xd0, 0x00000000},
661 {0xd4, 0x00000000},
662 {0xd8, 0x00000000},
663 {0xdc, 0x00000000},
664 {0xe0, 0x00000000},
665 {0xe4, 0x0000ffff},
666 {0xe8, 0x0000ffff},
667 {0xec, 0x0000ffff},
668 {0xf0, 0x0000ffff},
669 {0xf8, 0x00000000},
670 {0xfc, 0x00000000},
671};
672
655static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) 673static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
656{ 674{
657 switch (reg) { 675 switch (reg) {
@@ -684,6 +702,31 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
684 } 702 }
685} 703}
686 704
705static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
706{
707 switch (reg) {
708 case REG_ESAI_ETDR:
709 case REG_ESAI_ERDR:
710 case REG_ESAI_ESR:
711 case REG_ESAI_TFSR:
712 case REG_ESAI_RFSR:
713 case REG_ESAI_TX0:
714 case REG_ESAI_TX1:
715 case REG_ESAI_TX2:
716 case REG_ESAI_TX3:
717 case REG_ESAI_TX4:
718 case REG_ESAI_TX5:
719 case REG_ESAI_RX0:
720 case REG_ESAI_RX1:
721 case REG_ESAI_RX2:
722 case REG_ESAI_RX3:
723 case REG_ESAI_SAISR:
724 return true;
725 default:
726 return false;
727 }
728}
729
687static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) 730static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
688{ 731{
689 switch (reg) { 732 switch (reg) {
@@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = {
721 .val_bits = 32, 764 .val_bits = 32,
722 765
723 .max_register = REG_ESAI_PCRC, 766 .max_register = REG_ESAI_PCRC,
767 .reg_defaults = fsl_esai_reg_defaults,
768 .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
724 .readable_reg = fsl_esai_readable_reg, 769 .readable_reg = fsl_esai_readable_reg,
770 .volatile_reg = fsl_esai_volatile_reg,
725 .writeable_reg = fsl_esai_writeable_reg, 771 .writeable_reg = fsl_esai_writeable_reg,
772 .cache_type = REGCACHE_RBTREE,
726}; 773};
727 774
728static int fsl_esai_probe(struct platform_device *pdev) 775static int fsl_esai_probe(struct platform_device *pdev)
@@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
853}; 900};
854MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); 901MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
855 902
903#if CONFIG_PM_SLEEP
904static int fsl_esai_suspend(struct device *dev)
905{
906 struct fsl_esai *esai = dev_get_drvdata(dev);
907
908 regcache_cache_only(esai->regmap, true);
909 regcache_mark_dirty(esai->regmap);
910
911 return 0;
912}
913
914static int fsl_esai_resume(struct device *dev)
915{
916 struct fsl_esai *esai = dev_get_drvdata(dev);
917 int ret;
918
919 regcache_cache_only(esai->regmap, false);
920
921 /* FIFO reset for safety */
922 regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
923 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
924 regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
925 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
926
927 ret = regcache_sync(esai->regmap);
928 if (ret)
929 return ret;
930
931 /* FIFO reset done */
932 regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
933 regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
934
935 return 0;
936}
937#endif /* CONFIG_PM_SLEEP */
938
939static const struct dev_pm_ops fsl_esai_pm_ops = {
940 SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
941};
942
856static struct platform_driver fsl_esai_driver = { 943static struct platform_driver fsl_esai_driver = {
857 .probe = fsl_esai_probe, 944 .probe = fsl_esai_probe,
858 .driver = { 945 .driver = {
859 .name = "fsl-esai-dai", 946 .name = "fsl-esai-dai",
947 .pm = &fsl_esai_pm_ops,
860 .of_match_table = fsl_esai_dt_ids, 948 .of_match_table = fsl_esai_dt_ids,
861 }, 949 },
862}; 950};