aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-10-25 22:07:40 -0400
committerMark Brown <broonie@kernel.org>2015-10-25 22:07:40 -0400
commitce247b45a3289f88008c13ca26ccde0db5fea690 (patch)
tree3f02183a34c6bb6aa71f165334a89b9597823b4b /sound/soc/fsl
parent444c37aeee46db70ce01199863dc046fa68e88b7 (diff)
parentc64c60763b4e3c72a3520c8d51be858cd67bacb5 (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.c88
-rw-r--r--sound/soc/fsl/fsl_sai.c33
-rw-r--r--sound/soc/fsl/fsl_spdif.c73
-rw-r--r--sound/soc/fsl/fsl_ssi.c102
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
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};
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)
637static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) 637static 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
686static int fsl_sai_probe(struct platform_device *pdev) 689static int fsl_sai_probe(struct platform_device *pdev)
@@ -803,10 +806,40 @@ static const struct of_device_id fsl_sai_ids[] = {
803}; 806};
804MODULE_DEVICE_TABLE(of, fsl_sai_ids); 807MODULE_DEVICE_TABLE(of, fsl_sai_ids);
805 808
809#if CONFIG_PM_SLEEP
810static 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
820static 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
834static const struct dev_pm_ops fsl_sai_pm_ops = {
835 SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume)
836};
837
806static struct platform_driver fsl_sai_driver = { 838static 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 */
1008static 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
1001static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 1017static 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
1041static 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
1025static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) 1061static 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
1054static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, 1094static 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
1315static 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
1328static 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
1342static const struct dev_pm_ops fsl_spdif_pm = {
1343 SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume)
1344};
1345
1274static const struct of_device_id fsl_spdif_dt_ids[] = { 1346static 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
115static 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
129static 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
140static 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
159static 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
114static const struct regmap_config fsl_ssi_regconfig = { 171static 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
122struct fsl_ssi_soc_data { 185struct 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
1583static 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
1597static 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
1613static const struct dev_pm_ops fsl_ssi_pm = {
1614 SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume)
1615};
1616
1516static struct platform_driver fsl_ssi_driver = { 1617static 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,