Commit ce247b45 authored by Mark Brown's avatar Mark Brown

Merge branch 'topic/fsl-mega-fast' of...

Merge branch 'topic/fsl-mega-fast' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-fsl
parents 444c37ae c64c6076
...@@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = { ...@@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = {
.name = "fsl-esai", .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) static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {
...@@ -684,6 +702,31 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) ...@@ -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) static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {
...@@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = { ...@@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = {
.val_bits = 32, .val_bits = 32,
.max_register = REG_ESAI_PCRC, .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, .readable_reg = fsl_esai_readable_reg,
.volatile_reg = fsl_esai_volatile_reg,
.writeable_reg = fsl_esai_writeable_reg, .writeable_reg = fsl_esai_writeable_reg,
.cache_type = REGCACHE_RBTREE,
}; };
static int fsl_esai_probe(struct platform_device *pdev) static int fsl_esai_probe(struct platform_device *pdev)
...@@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = { ...@@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, 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 = { static struct platform_driver fsl_esai_driver = {
.probe = fsl_esai_probe, .probe = fsl_esai_probe,
.driver = { .driver = {
.name = "fsl-esai-dai", .name = "fsl-esai-dai",
.pm = &fsl_esai_pm_ops,
.of_match_table = fsl_esai_dt_ids, .of_match_table = fsl_esai_dt_ids,
}, },
}; };
......
...@@ -637,6 +637,8 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) ...@@ -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) static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {
case FSL_SAI_TCSR:
case FSL_SAI_RCSR:
case FSL_SAI_TFR: case FSL_SAI_TFR:
case FSL_SAI_RFR: case FSL_SAI_RFR:
case FSL_SAI_TDR: case FSL_SAI_TDR:
...@@ -681,6 +683,7 @@ static const struct regmap_config fsl_sai_regmap_config = { ...@@ -681,6 +683,7 @@ static const struct regmap_config fsl_sai_regmap_config = {
.readable_reg = fsl_sai_readable_reg, .readable_reg = fsl_sai_readable_reg,
.volatile_reg = fsl_sai_volatile_reg, .volatile_reg = fsl_sai_volatile_reg,
.writeable_reg = fsl_sai_writeable_reg, .writeable_reg = fsl_sai_writeable_reg,
.cache_type = REGCACHE_FLAT,
}; };
static int fsl_sai_probe(struct platform_device *pdev) static int fsl_sai_probe(struct platform_device *pdev)
...@@ -803,10 +806,40 @@ static const struct of_device_id fsl_sai_ids[] = { ...@@ -803,10 +806,40 @@ static const struct of_device_id fsl_sai_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, 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 = { static struct platform_driver fsl_sai_driver = {
.probe = fsl_sai_probe, .probe = fsl_sai_probe,
.driver = { .driver = {
.name = "fsl-sai", .name = "fsl-sai",
.pm = &fsl_sai_pm_ops,
.of_match_table = fsl_sai_ids, .of_match_table = fsl_sai_ids,
}, },
}; };
......
...@@ -108,6 +108,8 @@ struct fsl_spdif_priv { ...@@ -108,6 +108,8 @@ struct fsl_spdif_priv {
struct clk *sysclk; struct clk *sysclk;
struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_rx;
/* regcache for SRPC */
u32 regcache_srpc;
}; };
/* DPLL locked and lock loss interrupt handler */ /* DPLL locked and lock loss interrupt handler */
...@@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) ...@@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
struct regmap *regmap = spdif_priv->regmap; struct regmap *regmap = spdif_priv->regmap;
u32 val, cycle = 1000; u32 val, cycle = 1000;
regcache_cache_bypass(regmap, true);
regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET);
/* /*
...@@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) ...@@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
regmap_read(regmap, REG_SPDIF_SCR, &val); regmap_read(regmap, REG_SPDIF_SCR, &val);
} while ((val & SCR_SOFT_RESET) && cycle--); } while ((val & SCR_SOFT_RESET) && cycle--);
regcache_cache_bypass(regmap, false);
regcache_mark_dirty(regmap);
regcache_sync(regmap);
if (cycle) if (cycle)
return 0; return 0;
else else
...@@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = { ...@@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = {
}; };
/* FSL SPDIF REGMAP */ /* 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) static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
{ {
...@@ -1022,6 +1038,26 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) ...@@ -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) static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {
...@@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = { ...@@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = {
.val_bits = 32, .val_bits = 32,
.max_register = REG_SPDIF_STC, .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, .readable_reg = fsl_spdif_readable_reg,
.volatile_reg = fsl_spdif_volatile_reg,
.writeable_reg = fsl_spdif_writeable_reg, .writeable_reg = fsl_spdif_writeable_reg,
.cache_type = REGCACHE_RBTREE,
}; };
static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, 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,6 +1311,38 @@ static int fsl_spdif_probe(struct platform_device *pdev)
return ret; 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[] = { static const struct of_device_id fsl_spdif_dt_ids[] = {
{ .compatible = "fsl,imx35-spdif", }, { .compatible = "fsl,imx35-spdif", },
{ .compatible = "fsl,vf610-spdif", }, { .compatible = "fsl,vf610-spdif", },
...@@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = { ...@@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = {
.driver = { .driver = {
.name = "fsl-spdif-dai", .name = "fsl-spdif-dai",
.of_match_table = fsl_spdif_dt_ids, .of_match_table = fsl_spdif_dt_ids,
.pm = &fsl_spdif_pm,
}, },
.probe = fsl_spdif_probe, .probe = fsl_spdif_probe,
}; };
......
...@@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val { ...@@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val {
struct fsl_ssi_reg_val rx; struct fsl_ssi_reg_val rx;
struct fsl_ssi_reg_val tx; 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 = { static const struct regmap_config fsl_ssi_regconfig = {
.max_register = CCSR_SSI_SACCDIS, .max_register = CCSR_SSI_SACCDIS,
.reg_bits = 32, .reg_bits = 32,
.val_bits = 32, .val_bits = 32,
.reg_stride = 4, .reg_stride = 4,
.val_format_endian = REGMAP_ENDIAN_NATIVE, .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 { struct fsl_ssi_soc_data {
...@@ -176,6 +239,9 @@ struct fsl_ssi_private { ...@@ -176,6 +239,9 @@ struct fsl_ssi_private {
unsigned int baudclk_streams; unsigned int baudclk_streams;
unsigned int bitclk_freq; unsigned int bitclk_freq;
/*regcache for SFCSR*/
u32 regcache_sfcsr;
/* DMA params */ /* DMA params */
struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_rx;
...@@ -1513,10 +1579,46 @@ static int fsl_ssi_remove(struct platform_device *pdev) ...@@ -1513,10 +1579,46 @@ static int fsl_ssi_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver fsl_ssi_driver = {
.driver = { .driver = {
.name = "fsl-ssi-dai", .name = "fsl-ssi-dai",
.of_match_table = fsl_ssi_ids, .of_match_table = fsl_ssi_ids,
.pm = &fsl_ssi_pm,
}, },
.probe = fsl_ssi_probe, .probe = fsl_ssi_probe,
.remove = fsl_ssi_remove, .remove = fsl_ssi_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment