mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-09 22:24:04 +08:00
ASoC: DaVinci: i2s toggle clock to complete reset
Add toggle_clock function to complete i2s reset earlier. Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
35cf63583d
commit
c392bec716
@ -104,6 +104,7 @@ static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
|
|||||||
|
|
||||||
struct davinci_mcbsp_dev {
|
struct davinci_mcbsp_dev {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
u32 pcr;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct davinci_pcm_dma_params *dma_params[2];
|
struct davinci_pcm_dma_params *dma_params[2];
|
||||||
};
|
};
|
||||||
@ -119,17 +120,34 @@ static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
|
|||||||
return __raw_readl(dev->base + reg);
|
return __raw_readl(dev->base + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
|
||||||
|
{
|
||||||
|
u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
|
||||||
|
/* The clock needs to toggle to complete reset.
|
||||||
|
* So, fake it by toggling the clk polarity.
|
||||||
|
*/
|
||||||
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
|
||||||
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
|
||||||
|
}
|
||||||
|
|
||||||
static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
|
static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
|
struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
|
||||||
struct snd_soc_device *socdev = rtd->socdev;
|
struct snd_soc_device *socdev = rtd->socdev;
|
||||||
struct snd_soc_platform *platform = socdev->card->platform;
|
struct snd_soc_platform *platform = socdev->card->platform;
|
||||||
|
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||||
u32 spcr;
|
u32 spcr;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
|
||||||
/* Start the sample generator and enable transmitter/receiver */
|
|
||||||
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
|
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
|
||||||
|
if (spcr & mask) {
|
||||||
|
/* start off disabled */
|
||||||
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
|
||||||
|
spcr & ~mask);
|
||||||
|
toggle_clock(dev, playback);
|
||||||
|
}
|
||||||
|
/* Start the sample generator and enable transmitter/receiver */
|
||||||
spcr |= DAVINCI_MCBSP_SPCR_GRST;
|
spcr |= DAVINCI_MCBSP_SPCR_GRST;
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
|
||||||
|
|
||||||
@ -155,6 +173,7 @@ static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
|
|||||||
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
|
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
|
||||||
spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
|
spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
|
||||||
|
toggle_clock(dev, playback);
|
||||||
|
|
||||||
/* Restart the DMA */
|
/* Restart the DMA */
|
||||||
if (platform->pcm_ops->trigger) {
|
if (platform->pcm_ops->trigger) {
|
||||||
@ -188,15 +207,14 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream)
|
|||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
|
struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
|
||||||
u32 spcr;
|
u32 spcr;
|
||||||
|
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||||
|
|
||||||
/* Reset transmitter/receiver and sample rate/frame sync generators */
|
/* Reset transmitter/receiver and sample rate/frame sync generators */
|
||||||
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
|
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
|
||||||
spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
|
spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST;
|
||||||
spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
|
|
||||||
else
|
|
||||||
spcr &= ~DAVINCI_MCBSP_SPCR_RRST;
|
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
|
||||||
|
toggle_clock(dev, playback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int davinci_i2s_startup(struct snd_pcm_substream *substream,
|
static int davinci_i2s_startup(struct snd_pcm_substream *substream,
|
||||||
@ -334,6 +352,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
|
||||||
|
dev->pcr = pcr;
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
|
||||||
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
|
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
|
||||||
|
Loading…
Reference in New Issue
Block a user