Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a85e419e authored by Daniel Mack's avatar Daniel Mack Committed by Mark Brown
Browse files

ASoC: davinci-mcasp: add support for suspend and resume



When the system returns from suspend, it looses its configuration. Most
of it is restored by running a normal audio stream startup, but the DAI
format is left unset as that's configured on the audio device creation.

Hence, it suffices here to care for the registers which are touched by
davinci_mcasp_set_dai_fmt() and restore them when the system is resumed.

Signed-off-by: default avatarDaniel Mack <zonque@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent bcf25567
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -1251,12 +1251,51 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int davinci_mcasp_suspend(struct device *dev)
{
	struct davinci_audio_dev *a = dev_get_drvdata(dev);
	void __iomem *base = a->base;

	a->context.txfmtctl = mcasp_get_reg(base + DAVINCI_MCASP_TXFMCTL_REG);
	a->context.rxfmtctl = mcasp_get_reg(base + DAVINCI_MCASP_RXFMCTL_REG);
	a->context.txfmt = mcasp_get_reg(base + DAVINCI_MCASP_TXFMT_REG);
	a->context.rxfmt = mcasp_get_reg(base + DAVINCI_MCASP_RXFMT_REG);
	a->context.aclkxctl = mcasp_get_reg(base + DAVINCI_MCASP_ACLKXCTL_REG);
	a->context.aclkrctl = mcasp_get_reg(base + DAVINCI_MCASP_ACLKRCTL_REG);
	a->context.pdir = mcasp_get_reg(base + DAVINCI_MCASP_PDIR_REG);

	return 0;
}

static int davinci_mcasp_resume(struct device *dev)
{
	struct davinci_audio_dev *a = dev_get_drvdata(dev);
	void __iomem *base = a->base;

	mcasp_set_reg(base + DAVINCI_MCASP_TXFMCTL_REG, a->context.txfmtctl);
	mcasp_set_reg(base + DAVINCI_MCASP_RXFMCTL_REG, a->context.rxfmtctl);
	mcasp_set_reg(base + DAVINCI_MCASP_TXFMT_REG, a->context.txfmt);
	mcasp_set_reg(base + DAVINCI_MCASP_RXFMT_REG, a->context.rxfmt);
	mcasp_set_reg(base + DAVINCI_MCASP_ACLKXCTL_REG, a->context.aclkxctl);
	mcasp_set_reg(base + DAVINCI_MCASP_ACLKRCTL_REG, a->context.aclkrctl);
	mcasp_set_reg(base + DAVINCI_MCASP_PDIR_REG, a->context.pdir);

	return 0;
}
#endif

SIMPLE_DEV_PM_OPS(davinci_mcasp_pm_ops,
		  davinci_mcasp_suspend,
		  davinci_mcasp_resume);

static struct platform_driver davinci_mcasp_driver = {
	.probe		= davinci_mcasp_probe,
	.remove		= davinci_mcasp_remove,
	.driver		= {
		.name	= "davinci-mcasp",
		.owner	= THIS_MODULE,
		.pm	= &davinci_mcasp_pm_ops,
		.of_match_table = mcasp_dt_ids,
	},
};
+12 −0
Original line number Diff line number Diff line
@@ -43,6 +43,18 @@ struct davinci_audio_dev {
	/* McASP FIFO related */
	u8	txnumevt;
	u8	rxnumevt;

#ifdef CONFIG_PM_SLEEP
	struct {
		u32	txfmtctl;
		u32	rxfmtctl;
		u32	txfmt;
		u32	rxfmt;
		u32	aclkxctl;
		u32	aclkrctl;
		u32	pdir;
	} context;
#endif
};

#endif	/* DAVINCI_MCASP_H */