diff options
author | Mark Brown <broonie@kernel.org> | 2015-10-25 22:07:40 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-10-25 22:07:40 -0400 |
commit | ce247b45a3289f88008c13ca26ccde0db5fea690 (patch) | |
tree | 3f02183a34c6bb6aa71f165334a89b9597823b4b /sound/soc/fsl | |
parent | 444c37aeee46db70ce01199863dc046fa68e88b7 (diff) | |
parent | c64c60763b4e3c72a3520c8d51be858cd67bacb5 (diff) |
Merge branch 'topic/fsl-mega-fast' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-fsl
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 88 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 33 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 73 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 102 |
4 files changed, 296 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 | ||
655 | static 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 | |||
655 | static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) | 673 | static 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 | ||
705 | static 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 | |||
687 | static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) | 730 | static 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 | ||
728 | static int fsl_esai_probe(struct platform_device *pdev) | 775 | static int fsl_esai_probe(struct platform_device *pdev) |
@@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = { | |||
853 | }; | 900 | }; |
854 | MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); | 901 | MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); |
855 | 902 | ||
903 | #if CONFIG_PM_SLEEP | ||
904 | static 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 | |||
914 | static 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 | |||
939 | static const struct dev_pm_ops fsl_esai_pm_ops = { | ||
940 | SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume) | ||
941 | }; | ||
942 | |||
856 | static struct platform_driver fsl_esai_driver = { | 943 | static 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 | }; |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 2150f5aaba7a..38505f32ebe6 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -637,6 +637,8 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) | |||
637 | static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) | 637 | static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) |
638 | { | 638 | { |
639 | switch (reg) { | 639 | switch (reg) { |
640 | case FSL_SAI_TCSR: | ||
641 | case FSL_SAI_RCSR: | ||
640 | case FSL_SAI_TFR: | 642 | case FSL_SAI_TFR: |
641 | case FSL_SAI_RFR: | 643 | case FSL_SAI_RFR: |
642 | case FSL_SAI_TDR: | 644 | case FSL_SAI_TDR: |
@@ -681,6 +683,7 @@ static const struct regmap_config fsl_sai_regmap_config = { | |||
681 | .readable_reg = fsl_sai_readable_reg, | 683 | .readable_reg = fsl_sai_readable_reg, |
682 | .volatile_reg = fsl_sai_volatile_reg, | 684 | .volatile_reg = fsl_sai_volatile_reg, |
683 | .writeable_reg = fsl_sai_writeable_reg, | 685 | .writeable_reg = fsl_sai_writeable_reg, |
686 | .cache_type = REGCACHE_FLAT, | ||
684 | }; | 687 | }; |
685 | 688 | ||
686 | static int fsl_sai_probe(struct platform_device *pdev) | 689 | static int fsl_sai_probe(struct platform_device *pdev) |
@@ -803,10 +806,40 @@ static const struct of_device_id fsl_sai_ids[] = { | |||
803 | }; | 806 | }; |
804 | MODULE_DEVICE_TABLE(of, fsl_sai_ids); | 807 | MODULE_DEVICE_TABLE(of, fsl_sai_ids); |
805 | 808 | ||
809 | #if CONFIG_PM_SLEEP | ||
810 | static int fsl_sai_suspend(struct device *dev) | ||
811 | { | ||
812 | struct fsl_sai *sai = dev_get_drvdata(dev); | ||
813 | |||
814 | regcache_cache_only(sai->regmap, true); | ||
815 | regcache_mark_dirty(sai->regmap); | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | static int fsl_sai_resume(struct device *dev) | ||
821 | { | ||
822 | struct fsl_sai *sai = dev_get_drvdata(dev); | ||
823 | |||
824 | regcache_cache_only(sai->regmap, false); | ||
825 | regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); | ||
826 | regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); | ||
827 | msleep(1); | ||
828 | regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | ||
829 | regmap_write(sai->regmap, FSL_SAI_RCSR, 0); | ||
830 | return regcache_sync(sai->regmap); | ||
831 | } | ||
832 | #endif /* CONFIG_PM_SLEEP */ | ||
833 | |||
834 | static const struct dev_pm_ops fsl_sai_pm_ops = { | ||
835 | SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume) | ||
836 | }; | ||
837 | |||
806 | static struct platform_driver fsl_sai_driver = { | 838 | static struct platform_driver fsl_sai_driver = { |
807 | .probe = fsl_sai_probe, | 839 | .probe = fsl_sai_probe, |
808 | .driver = { | 840 | .driver = { |
809 | .name = "fsl-sai", | 841 | .name = "fsl-sai", |
842 | .pm = &fsl_sai_pm_ops, | ||
810 | .of_match_table = fsl_sai_ids, | 843 | .of_match_table = fsl_sai_ids, |
811 | }, | 844 | }, |
812 | }; | 845 | }; |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index ab729f2426fe..3d59bb6719f2 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -108,6 +108,8 @@ struct fsl_spdif_priv { | |||
108 | struct clk *sysclk; | 108 | struct clk *sysclk; |
109 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 109 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
110 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 110 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
111 | /* regcache for SRPC */ | ||
112 | u32 regcache_srpc; | ||
111 | }; | 113 | }; |
112 | 114 | ||
113 | /* DPLL locked and lock loss interrupt handler */ | 115 | /* DPLL locked and lock loss interrupt handler */ |
@@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) | |||
300 | struct regmap *regmap = spdif_priv->regmap; | 302 | struct regmap *regmap = spdif_priv->regmap; |
301 | u32 val, cycle = 1000; | 303 | u32 val, cycle = 1000; |
302 | 304 | ||
305 | regcache_cache_bypass(regmap, true); | ||
306 | |||
303 | regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); | 307 | regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); |
304 | 308 | ||
305 | /* | 309 | /* |
@@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) | |||
310 | regmap_read(regmap, REG_SPDIF_SCR, &val); | 314 | regmap_read(regmap, REG_SPDIF_SCR, &val); |
311 | } while ((val & SCR_SOFT_RESET) && cycle--); | 315 | } while ((val & SCR_SOFT_RESET) && cycle--); |
312 | 316 | ||
317 | regcache_cache_bypass(regmap, false); | ||
318 | regcache_mark_dirty(regmap); | ||
319 | regcache_sync(regmap); | ||
320 | |||
313 | if (cycle) | 321 | if (cycle) |
314 | return 0; | 322 | return 0; |
315 | else | 323 | else |
@@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = { | |||
997 | }; | 1005 | }; |
998 | 1006 | ||
999 | /* FSL SPDIF REGMAP */ | 1007 | /* FSL SPDIF REGMAP */ |
1008 | static const struct reg_default fsl_spdif_reg_defaults[] = { | ||
1009 | {0x0, 0x00000400}, | ||
1010 | {0x4, 0x00000000}, | ||
1011 | {0xc, 0x00000000}, | ||
1012 | {0x34, 0x00000000}, | ||
1013 | {0x38, 0x00000000}, | ||
1014 | {0x50, 0x00020f00}, | ||
1015 | }; | ||
1000 | 1016 | ||
1001 | static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) | 1017 | static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) |
1002 | { | 1018 | { |
@@ -1022,6 +1038,26 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) | |||
1022 | } | 1038 | } |
1023 | } | 1039 | } |
1024 | 1040 | ||
1041 | static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg) | ||
1042 | { | ||
1043 | switch (reg) { | ||
1044 | case REG_SPDIF_SRPC: | ||
1045 | case REG_SPDIF_SIS: | ||
1046 | case REG_SPDIF_SRL: | ||
1047 | case REG_SPDIF_SRR: | ||
1048 | case REG_SPDIF_SRCSH: | ||
1049 | case REG_SPDIF_SRCSL: | ||
1050 | case REG_SPDIF_SRU: | ||
1051 | case REG_SPDIF_SRQ: | ||
1052 | case REG_SPDIF_STL: | ||
1053 | case REG_SPDIF_STR: | ||
1054 | case REG_SPDIF_SRFM: | ||
1055 | return true; | ||
1056 | default: | ||
1057 | return false; | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1025 | static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) | 1061 | static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) |
1026 | { | 1062 | { |
1027 | switch (reg) { | 1063 | switch (reg) { |
@@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = { | |||
1047 | .val_bits = 32, | 1083 | .val_bits = 32, |
1048 | 1084 | ||
1049 | .max_register = REG_SPDIF_STC, | 1085 | .max_register = REG_SPDIF_STC, |
1086 | .reg_defaults = fsl_spdif_reg_defaults, | ||
1087 | .num_reg_defaults = ARRAY_SIZE(fsl_spdif_reg_defaults), | ||
1050 | .readable_reg = fsl_spdif_readable_reg, | 1088 | .readable_reg = fsl_spdif_readable_reg, |
1089 | .volatile_reg = fsl_spdif_volatile_reg, | ||
1051 | .writeable_reg = fsl_spdif_writeable_reg, | 1090 | .writeable_reg = fsl_spdif_writeable_reg, |
1091 | .cache_type = REGCACHE_RBTREE, | ||
1052 | }; | 1092 | }; |
1053 | 1093 | ||
1054 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | 1094 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, |
@@ -1271,6 +1311,38 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1271 | return ret; | 1311 | return ret; |
1272 | } | 1312 | } |
1273 | 1313 | ||
1314 | #ifdef CONFIG_PM_SLEEP | ||
1315 | static int fsl_spdif_suspend(struct device *dev) | ||
1316 | { | ||
1317 | struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev); | ||
1318 | |||
1319 | regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC, | ||
1320 | &spdif_priv->regcache_srpc); | ||
1321 | |||
1322 | regcache_cache_only(spdif_priv->regmap, true); | ||
1323 | regcache_mark_dirty(spdif_priv->regmap); | ||
1324 | |||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | static int fsl_spdif_resume(struct device *dev) | ||
1329 | { | ||
1330 | struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev); | ||
1331 | |||
1332 | regcache_cache_only(spdif_priv->regmap, false); | ||
1333 | |||
1334 | regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC, | ||
1335 | SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK, | ||
1336 | spdif_priv->regcache_srpc); | ||
1337 | |||
1338 | return regcache_sync(spdif_priv->regmap); | ||
1339 | } | ||
1340 | #endif /* CONFIG_PM_SLEEP */ | ||
1341 | |||
1342 | static const struct dev_pm_ops fsl_spdif_pm = { | ||
1343 | SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume) | ||
1344 | }; | ||
1345 | |||
1274 | static const struct of_device_id fsl_spdif_dt_ids[] = { | 1346 | static const struct of_device_id fsl_spdif_dt_ids[] = { |
1275 | { .compatible = "fsl,imx35-spdif", }, | 1347 | { .compatible = "fsl,imx35-spdif", }, |
1276 | { .compatible = "fsl,vf610-spdif", }, | 1348 | { .compatible = "fsl,vf610-spdif", }, |
@@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = { | |||
1282 | .driver = { | 1354 | .driver = { |
1283 | .name = "fsl-spdif-dai", | 1355 | .name = "fsl-spdif-dai", |
1284 | .of_match_table = fsl_spdif_dt_ids, | 1356 | .of_match_table = fsl_spdif_dt_ids, |
1357 | .pm = &fsl_spdif_pm, | ||
1285 | }, | 1358 | }, |
1286 | .probe = fsl_spdif_probe, | 1359 | .probe = fsl_spdif_probe, |
1287 | }; | 1360 | }; |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 8ec6fb208ea0..7c495d3d188a 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val { | |||
111 | struct fsl_ssi_reg_val rx; | 111 | struct fsl_ssi_reg_val rx; |
112 | struct fsl_ssi_reg_val tx; | 112 | struct fsl_ssi_reg_val tx; |
113 | }; | 113 | }; |
114 | |||
115 | static const struct reg_default fsl_ssi_reg_defaults[] = { | ||
116 | {0x10, 0x00000000}, | ||
117 | {0x18, 0x00003003}, | ||
118 | {0x1c, 0x00000200}, | ||
119 | {0x20, 0x00000200}, | ||
120 | {0x24, 0x00040000}, | ||
121 | {0x28, 0x00040000}, | ||
122 | {0x38, 0x00000000}, | ||
123 | {0x48, 0x00000000}, | ||
124 | {0x4c, 0x00000000}, | ||
125 | {0x54, 0x00000000}, | ||
126 | {0x58, 0x00000000}, | ||
127 | }; | ||
128 | |||
129 | static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) | ||
130 | { | ||
131 | switch (reg) { | ||
132 | case CCSR_SSI_SACCEN: | ||
133 | case CCSR_SSI_SACCDIS: | ||
134 | return false; | ||
135 | default: | ||
136 | return true; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) | ||
141 | { | ||
142 | switch (reg) { | ||
143 | case CCSR_SSI_STX0: | ||
144 | case CCSR_SSI_STX1: | ||
145 | case CCSR_SSI_SRX0: | ||
146 | case CCSR_SSI_SRX1: | ||
147 | case CCSR_SSI_SISR: | ||
148 | case CCSR_SSI_SFCSR: | ||
149 | case CCSR_SSI_SACADD: | ||
150 | case CCSR_SSI_SACDAT: | ||
151 | case CCSR_SSI_SATAG: | ||
152 | case CCSR_SSI_SACCST: | ||
153 | return true; | ||
154 | default: | ||
155 | return false; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) | ||
160 | { | ||
161 | switch (reg) { | ||
162 | case CCSR_SSI_SRX0: | ||
163 | case CCSR_SSI_SRX1: | ||
164 | case CCSR_SSI_SACCST: | ||
165 | return false; | ||
166 | default: | ||
167 | return true; | ||
168 | } | ||
169 | } | ||
170 | |||
114 | static const struct regmap_config fsl_ssi_regconfig = { | 171 | static const struct regmap_config fsl_ssi_regconfig = { |
115 | .max_register = CCSR_SSI_SACCDIS, | 172 | .max_register = CCSR_SSI_SACCDIS, |
116 | .reg_bits = 32, | 173 | .reg_bits = 32, |
117 | .val_bits = 32, | 174 | .val_bits = 32, |
118 | .reg_stride = 4, | 175 | .reg_stride = 4, |
119 | .val_format_endian = REGMAP_ENDIAN_NATIVE, | 176 | .val_format_endian = REGMAP_ENDIAN_NATIVE, |
177 | .reg_defaults = fsl_ssi_reg_defaults, | ||
178 | .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults), | ||
179 | .readable_reg = fsl_ssi_readable_reg, | ||
180 | .volatile_reg = fsl_ssi_volatile_reg, | ||
181 | .writeable_reg = fsl_ssi_writeable_reg, | ||
182 | .cache_type = REGCACHE_RBTREE, | ||
120 | }; | 183 | }; |
121 | 184 | ||
122 | struct fsl_ssi_soc_data { | 185 | struct fsl_ssi_soc_data { |
@@ -176,6 +239,9 @@ struct fsl_ssi_private { | |||
176 | unsigned int baudclk_streams; | 239 | unsigned int baudclk_streams; |
177 | unsigned int bitclk_freq; | 240 | unsigned int bitclk_freq; |
178 | 241 | ||
242 | /*regcache for SFCSR*/ | ||
243 | u32 regcache_sfcsr; | ||
244 | |||
179 | /* DMA params */ | 245 | /* DMA params */ |
180 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 246 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
181 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 247 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
@@ -1513,10 +1579,46 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1513 | return 0; | 1579 | return 0; |
1514 | } | 1580 | } |
1515 | 1581 | ||
1582 | #ifdef CONFIG_PM_SLEEP | ||
1583 | static int fsl_ssi_suspend(struct device *dev) | ||
1584 | { | ||
1585 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); | ||
1586 | struct regmap *regs = ssi_private->regs; | ||
1587 | |||
1588 | regmap_read(regs, CCSR_SSI_SFCSR, | ||
1589 | &ssi_private->regcache_sfcsr); | ||
1590 | |||
1591 | regcache_cache_only(regs, true); | ||
1592 | regcache_mark_dirty(regs); | ||
1593 | |||
1594 | return 0; | ||
1595 | } | ||
1596 | |||
1597 | static int fsl_ssi_resume(struct device *dev) | ||
1598 | { | ||
1599 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); | ||
1600 | struct regmap *regs = ssi_private->regs; | ||
1601 | |||
1602 | regcache_cache_only(regs, false); | ||
1603 | |||
1604 | regmap_update_bits(regs, CCSR_SSI_SFCSR, | ||
1605 | CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK | | ||
1606 | CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK, | ||
1607 | ssi_private->regcache_sfcsr); | ||
1608 | |||
1609 | return regcache_sync(regs); | ||
1610 | } | ||
1611 | #endif /* CONFIG_PM_SLEEP */ | ||
1612 | |||
1613 | static const struct dev_pm_ops fsl_ssi_pm = { | ||
1614 | SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume) | ||
1615 | }; | ||
1616 | |||
1516 | static struct platform_driver fsl_ssi_driver = { | 1617 | static struct platform_driver fsl_ssi_driver = { |
1517 | .driver = { | 1618 | .driver = { |
1518 | .name = "fsl-ssi-dai", | 1619 | .name = "fsl-ssi-dai", |
1519 | .of_match_table = fsl_ssi_ids, | 1620 | .of_match_table = fsl_ssi_ids, |
1621 | .pm = &fsl_ssi_pm, | ||
1520 | }, | 1622 | }, |
1521 | .probe = fsl_ssi_probe, | 1623 | .probe = fsl_ssi_probe, |
1522 | .remove = fsl_ssi_remove, | 1624 | .remove = fsl_ssi_remove, |