Loading sound/soc/fsl/fsl_esai.c +88 −0 Original line number Diff line number Diff line Loading @@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = { .name = "fsl-esai", }; static const struct reg_default fsl_esai_reg_defaults[] = { {0x8, 0x00000000}, {0x10, 0x00000000}, {0x18, 0x00000000}, {0x98, 0x00000000}, {0xd0, 0x00000000}, {0xd4, 0x00000000}, {0xd8, 0x00000000}, {0xdc, 0x00000000}, {0xe0, 0x00000000}, {0xe4, 0x0000ffff}, {0xe8, 0x0000ffff}, {0xec, 0x0000ffff}, {0xf0, 0x0000ffff}, {0xf8, 0x00000000}, {0xfc, 0x00000000}, }; static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) { switch (reg) { Loading Loading @@ -684,6 +702,31 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) } } static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case REG_ESAI_ETDR: case REG_ESAI_ERDR: case REG_ESAI_ESR: case REG_ESAI_TFSR: case REG_ESAI_RFSR: case REG_ESAI_TX0: case REG_ESAI_TX1: case REG_ESAI_TX2: case REG_ESAI_TX3: case REG_ESAI_TX4: case REG_ESAI_TX5: case REG_ESAI_RX0: case REG_ESAI_RX1: case REG_ESAI_RX2: case REG_ESAI_RX3: case REG_ESAI_SAISR: return true; default: return false; } } static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { Loading Loading @@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = { .val_bits = 32, .max_register = REG_ESAI_PCRC, .reg_defaults = fsl_esai_reg_defaults, .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults), .readable_reg = fsl_esai_readable_reg, .volatile_reg = fsl_esai_volatile_reg, .writeable_reg = fsl_esai_writeable_reg, .cache_type = REGCACHE_RBTREE, }; static int fsl_esai_probe(struct platform_device *pdev) Loading Loading @@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); #if CONFIG_PM_SLEEP static int fsl_esai_suspend(struct device *dev) { struct fsl_esai *esai = dev_get_drvdata(dev); regcache_cache_only(esai->regmap, true); regcache_mark_dirty(esai->regmap); return 0; } static int fsl_esai_resume(struct device *dev) { struct fsl_esai *esai = dev_get_drvdata(dev); int ret; regcache_cache_only(esai->regmap, false); /* FIFO reset for safety */ regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, ESAI_xFCR_xFR); regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, ESAI_xFCR_xFR); ret = regcache_sync(esai->regmap); if (ret) return ret; /* FIFO reset done */ regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0); regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0); return 0; } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops fsl_esai_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume) }; static struct platform_driver fsl_esai_driver = { .probe = fsl_esai_probe, .driver = { .name = "fsl-esai-dai", .pm = &fsl_esai_pm_ops, .of_match_table = fsl_esai_dt_ids, }, }; Loading sound/soc/fsl/fsl_sai.c +33 −0 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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) Loading Loading @@ -803,10 +806,40 @@ static const struct of_device_id fsl_sai_ids[] = { }; MODULE_DEVICE_TABLE(of, fsl_sai_ids); #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, }, }; Loading sound/soc/fsl/fsl_spdif.c +73 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ struct fsl_spdif_priv { struct clk *sysclk; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; /* regcache for SRPC */ u32 regcache_srpc; }; /* DPLL locked and lock loss interrupt handler */ Loading Loading @@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) struct regmap *regmap = spdif_priv->regmap; u32 val, cycle = 1000; regcache_cache_bypass(regmap, true); regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); /* Loading @@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) regmap_read(regmap, REG_SPDIF_SCR, &val); } while ((val & SCR_SOFT_RESET) && cycle--); regcache_cache_bypass(regmap, false); regcache_mark_dirty(regmap); regcache_sync(regmap); if (cycle) return 0; else Loading Loading @@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = { }; /* FSL SPDIF REGMAP */ static const struct reg_default fsl_spdif_reg_defaults[] = { {0x0, 0x00000400}, {0x4, 0x00000000}, {0xc, 0x00000000}, {0x34, 0x00000000}, {0x38, 0x00000000}, {0x50, 0x00020f00}, }; static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) { Loading @@ -1022,6 +1038,26 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) } } static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case REG_SPDIF_SRPC: case REG_SPDIF_SIS: case REG_SPDIF_SRL: case REG_SPDIF_SRR: case REG_SPDIF_SRCSH: case REG_SPDIF_SRCSL: case REG_SPDIF_SRU: case REG_SPDIF_SRQ: case REG_SPDIF_STL: case REG_SPDIF_STR: case REG_SPDIF_SRFM: return true; default: return false; } } static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { Loading @@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = { .val_bits = 32, .max_register = REG_SPDIF_STC, .reg_defaults = fsl_spdif_reg_defaults, .num_reg_defaults = ARRAY_SIZE(fsl_spdif_reg_defaults), .readable_reg = fsl_spdif_readable_reg, .volatile_reg = fsl_spdif_volatile_reg, .writeable_reg = fsl_spdif_writeable_reg, .cache_type = REGCACHE_RBTREE, }; static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, Loading Loading @@ -1271,6 +1311,38 @@ static int fsl_spdif_probe(struct platform_device *pdev) return ret; } #ifdef CONFIG_PM_SLEEP static int fsl_spdif_suspend(struct device *dev) { struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev); regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC, &spdif_priv->regcache_srpc); regcache_cache_only(spdif_priv->regmap, true); regcache_mark_dirty(spdif_priv->regmap); return 0; } static int fsl_spdif_resume(struct device *dev) { struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev); regcache_cache_only(spdif_priv->regmap, false); regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC, SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK, spdif_priv->regcache_srpc); return regcache_sync(spdif_priv->regmap); } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops fsl_spdif_pm = { SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume) }; static const struct of_device_id fsl_spdif_dt_ids[] = { { .compatible = "fsl,imx35-spdif", }, { .compatible = "fsl,vf610-spdif", }, Loading @@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = { .driver = { .name = "fsl-spdif-dai", .of_match_table = fsl_spdif_dt_ids, .pm = &fsl_spdif_pm, }, .probe = fsl_spdif_probe, }; Loading sound/soc/fsl/fsl_ssi.c +102 −0 Original line number Diff line number Diff line Loading @@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val { struct fsl_ssi_reg_val rx; struct fsl_ssi_reg_val tx; }; static const struct reg_default fsl_ssi_reg_defaults[] = { {0x10, 0x00000000}, {0x18, 0x00003003}, {0x1c, 0x00000200}, {0x20, 0x00000200}, {0x24, 0x00040000}, {0x28, 0x00040000}, {0x38, 0x00000000}, {0x48, 0x00000000}, {0x4c, 0x00000000}, {0x54, 0x00000000}, {0x58, 0x00000000}, }; static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) { switch (reg) { case CCSR_SSI_SACCEN: case CCSR_SSI_SACCDIS: return false; default: return true; } } static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case CCSR_SSI_STX0: case CCSR_SSI_STX1: case CCSR_SSI_SRX0: case CCSR_SSI_SRX1: case CCSR_SSI_SISR: case CCSR_SSI_SFCSR: case CCSR_SSI_SACADD: case CCSR_SSI_SACDAT: case CCSR_SSI_SATAG: case CCSR_SSI_SACCST: return true; default: return false; } } static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { case CCSR_SSI_SRX0: case CCSR_SSI_SRX1: case CCSR_SSI_SACCST: return false; default: return true; } } static const struct regmap_config fsl_ssi_regconfig = { .max_register = CCSR_SSI_SACCDIS, .reg_bits = 32, .val_bits = 32, .reg_stride = 4, .val_format_endian = REGMAP_ENDIAN_NATIVE, .reg_defaults = fsl_ssi_reg_defaults, .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults), .readable_reg = fsl_ssi_readable_reg, .volatile_reg = fsl_ssi_volatile_reg, .writeable_reg = fsl_ssi_writeable_reg, .cache_type = REGCACHE_RBTREE, }; struct fsl_ssi_soc_data { Loading Loading @@ -176,6 +239,9 @@ struct fsl_ssi_private { unsigned int baudclk_streams; unsigned int bitclk_freq; /*regcache for SFCSR*/ u32 regcache_sfcsr; /* DMA params */ struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; Loading Loading @@ -1513,10 +1579,46 @@ static int fsl_ssi_remove(struct platform_device *pdev) return 0; } #ifdef CONFIG_PM_SLEEP static int fsl_ssi_suspend(struct device *dev) { struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); struct regmap *regs = ssi_private->regs; regmap_read(regs, CCSR_SSI_SFCSR, &ssi_private->regcache_sfcsr); regcache_cache_only(regs, true); regcache_mark_dirty(regs); return 0; } static int fsl_ssi_resume(struct device *dev) { struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); struct regmap *regs = ssi_private->regs; regcache_cache_only(regs, false); regmap_update_bits(regs, CCSR_SSI_SFCSR, CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK | CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK, ssi_private->regcache_sfcsr); return regcache_sync(regs); } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops fsl_ssi_pm = { SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume) }; static struct platform_driver fsl_ssi_driver = { .driver = { .name = "fsl-ssi-dai", .of_match_table = fsl_ssi_ids, .pm = &fsl_ssi_pm, }, .probe = fsl_ssi_probe, .remove = fsl_ssi_remove, Loading Loading
sound/soc/fsl/fsl_esai.c +88 −0 Original line number Diff line number Diff line Loading @@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = { .name = "fsl-esai", }; static const struct reg_default fsl_esai_reg_defaults[] = { {0x8, 0x00000000}, {0x10, 0x00000000}, {0x18, 0x00000000}, {0x98, 0x00000000}, {0xd0, 0x00000000}, {0xd4, 0x00000000}, {0xd8, 0x00000000}, {0xdc, 0x00000000}, {0xe0, 0x00000000}, {0xe4, 0x0000ffff}, {0xe8, 0x0000ffff}, {0xec, 0x0000ffff}, {0xf0, 0x0000ffff}, {0xf8, 0x00000000}, {0xfc, 0x00000000}, }; static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) { switch (reg) { Loading Loading @@ -684,6 +702,31 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) } } static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case REG_ESAI_ETDR: case REG_ESAI_ERDR: case REG_ESAI_ESR: case REG_ESAI_TFSR: case REG_ESAI_RFSR: case REG_ESAI_TX0: case REG_ESAI_TX1: case REG_ESAI_TX2: case REG_ESAI_TX3: case REG_ESAI_TX4: case REG_ESAI_TX5: case REG_ESAI_RX0: case REG_ESAI_RX1: case REG_ESAI_RX2: case REG_ESAI_RX3: case REG_ESAI_SAISR: return true; default: return false; } } static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { Loading Loading @@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = { .val_bits = 32, .max_register = REG_ESAI_PCRC, .reg_defaults = fsl_esai_reg_defaults, .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults), .readable_reg = fsl_esai_readable_reg, .volatile_reg = fsl_esai_volatile_reg, .writeable_reg = fsl_esai_writeable_reg, .cache_type = REGCACHE_RBTREE, }; static int fsl_esai_probe(struct platform_device *pdev) Loading Loading @@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); #if CONFIG_PM_SLEEP static int fsl_esai_suspend(struct device *dev) { struct fsl_esai *esai = dev_get_drvdata(dev); regcache_cache_only(esai->regmap, true); regcache_mark_dirty(esai->regmap); return 0; } static int fsl_esai_resume(struct device *dev) { struct fsl_esai *esai = dev_get_drvdata(dev); int ret; regcache_cache_only(esai->regmap, false); /* FIFO reset for safety */ regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, ESAI_xFCR_xFR); regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, ESAI_xFCR_xFR); ret = regcache_sync(esai->regmap); if (ret) return ret; /* FIFO reset done */ regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0); regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0); return 0; } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops fsl_esai_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume) }; static struct platform_driver fsl_esai_driver = { .probe = fsl_esai_probe, .driver = { .name = "fsl-esai-dai", .pm = &fsl_esai_pm_ops, .of_match_table = fsl_esai_dt_ids, }, }; Loading
sound/soc/fsl/fsl_sai.c +33 −0 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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) Loading Loading @@ -803,10 +806,40 @@ static const struct of_device_id fsl_sai_ids[] = { }; MODULE_DEVICE_TABLE(of, fsl_sai_ids); #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, }, }; Loading
sound/soc/fsl/fsl_spdif.c +73 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ struct fsl_spdif_priv { struct clk *sysclk; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; /* regcache for SRPC */ u32 regcache_srpc; }; /* DPLL locked and lock loss interrupt handler */ Loading Loading @@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) struct regmap *regmap = spdif_priv->regmap; u32 val, cycle = 1000; regcache_cache_bypass(regmap, true); regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); /* Loading @@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) regmap_read(regmap, REG_SPDIF_SCR, &val); } while ((val & SCR_SOFT_RESET) && cycle--); regcache_cache_bypass(regmap, false); regcache_mark_dirty(regmap); regcache_sync(regmap); if (cycle) return 0; else Loading Loading @@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = { }; /* FSL SPDIF REGMAP */ static const struct reg_default fsl_spdif_reg_defaults[] = { {0x0, 0x00000400}, {0x4, 0x00000000}, {0xc, 0x00000000}, {0x34, 0x00000000}, {0x38, 0x00000000}, {0x50, 0x00020f00}, }; static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) { Loading @@ -1022,6 +1038,26 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) } } static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case REG_SPDIF_SRPC: case REG_SPDIF_SIS: case REG_SPDIF_SRL: case REG_SPDIF_SRR: case REG_SPDIF_SRCSH: case REG_SPDIF_SRCSL: case REG_SPDIF_SRU: case REG_SPDIF_SRQ: case REG_SPDIF_STL: case REG_SPDIF_STR: case REG_SPDIF_SRFM: return true; default: return false; } } static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { Loading @@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = { .val_bits = 32, .max_register = REG_SPDIF_STC, .reg_defaults = fsl_spdif_reg_defaults, .num_reg_defaults = ARRAY_SIZE(fsl_spdif_reg_defaults), .readable_reg = fsl_spdif_readable_reg, .volatile_reg = fsl_spdif_volatile_reg, .writeable_reg = fsl_spdif_writeable_reg, .cache_type = REGCACHE_RBTREE, }; static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, Loading Loading @@ -1271,6 +1311,38 @@ static int fsl_spdif_probe(struct platform_device *pdev) return ret; } #ifdef CONFIG_PM_SLEEP static int fsl_spdif_suspend(struct device *dev) { struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev); regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC, &spdif_priv->regcache_srpc); regcache_cache_only(spdif_priv->regmap, true); regcache_mark_dirty(spdif_priv->regmap); return 0; } static int fsl_spdif_resume(struct device *dev) { struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev); regcache_cache_only(spdif_priv->regmap, false); regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC, SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK, spdif_priv->regcache_srpc); return regcache_sync(spdif_priv->regmap); } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops fsl_spdif_pm = { SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume) }; static const struct of_device_id fsl_spdif_dt_ids[] = { { .compatible = "fsl,imx35-spdif", }, { .compatible = "fsl,vf610-spdif", }, Loading @@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = { .driver = { .name = "fsl-spdif-dai", .of_match_table = fsl_spdif_dt_ids, .pm = &fsl_spdif_pm, }, .probe = fsl_spdif_probe, }; Loading
sound/soc/fsl/fsl_ssi.c +102 −0 Original line number Diff line number Diff line Loading @@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val { struct fsl_ssi_reg_val rx; struct fsl_ssi_reg_val tx; }; static const struct reg_default fsl_ssi_reg_defaults[] = { {0x10, 0x00000000}, {0x18, 0x00003003}, {0x1c, 0x00000200}, {0x20, 0x00000200}, {0x24, 0x00040000}, {0x28, 0x00040000}, {0x38, 0x00000000}, {0x48, 0x00000000}, {0x4c, 0x00000000}, {0x54, 0x00000000}, {0x58, 0x00000000}, }; static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) { switch (reg) { case CCSR_SSI_SACCEN: case CCSR_SSI_SACCDIS: return false; default: return true; } } static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case CCSR_SSI_STX0: case CCSR_SSI_STX1: case CCSR_SSI_SRX0: case CCSR_SSI_SRX1: case CCSR_SSI_SISR: case CCSR_SSI_SFCSR: case CCSR_SSI_SACADD: case CCSR_SSI_SACDAT: case CCSR_SSI_SATAG: case CCSR_SSI_SACCST: return true; default: return false; } } static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { case CCSR_SSI_SRX0: case CCSR_SSI_SRX1: case CCSR_SSI_SACCST: return false; default: return true; } } static const struct regmap_config fsl_ssi_regconfig = { .max_register = CCSR_SSI_SACCDIS, .reg_bits = 32, .val_bits = 32, .reg_stride = 4, .val_format_endian = REGMAP_ENDIAN_NATIVE, .reg_defaults = fsl_ssi_reg_defaults, .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults), .readable_reg = fsl_ssi_readable_reg, .volatile_reg = fsl_ssi_volatile_reg, .writeable_reg = fsl_ssi_writeable_reg, .cache_type = REGCACHE_RBTREE, }; struct fsl_ssi_soc_data { Loading Loading @@ -176,6 +239,9 @@ struct fsl_ssi_private { unsigned int baudclk_streams; unsigned int bitclk_freq; /*regcache for SFCSR*/ u32 regcache_sfcsr; /* DMA params */ struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; Loading Loading @@ -1513,10 +1579,46 @@ static int fsl_ssi_remove(struct platform_device *pdev) return 0; } #ifdef CONFIG_PM_SLEEP static int fsl_ssi_suspend(struct device *dev) { struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); struct regmap *regs = ssi_private->regs; regmap_read(regs, CCSR_SSI_SFCSR, &ssi_private->regcache_sfcsr); regcache_cache_only(regs, true); regcache_mark_dirty(regs); return 0; } static int fsl_ssi_resume(struct device *dev) { struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); struct regmap *regs = ssi_private->regs; regcache_cache_only(regs, false); regmap_update_bits(regs, CCSR_SSI_SFCSR, CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK | CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK, ssi_private->regcache_sfcsr); return regcache_sync(regs); } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops fsl_ssi_pm = { SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume) }; static struct platform_driver fsl_ssi_driver = { .driver = { .name = "fsl-ssi-dai", .of_match_table = fsl_ssi_ids, .pm = &fsl_ssi_pm, }, .probe = fsl_ssi_probe, .remove = fsl_ssi_remove, Loading