diff options
author | Troy Kisky <troy.kisky@boundarydevices.com> | 2009-07-04 22:29:52 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-07-05 07:59:06 -0400 |
commit | c392bec716431d77e503345117a3e7ad3face677 (patch) | |
tree | 54f0269e87bb9aa6aeaf3fab937aa90c22df8cad /sound/soc/davinci | |
parent | 35cf63583d8d81d8ac261e944db9eeb44a60692d (diff) |
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>
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r-- | sound/soc/davinci/davinci-i2s.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index bf5ec4b2f7f5..dd44167a90f0 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
@@ -104,6 +104,7 @@ static struct davinci_pcm_dma_params davinci_i2s_pcm_in = { | |||
104 | 104 | ||
105 | struct davinci_mcbsp_dev { | 105 | struct davinci_mcbsp_dev { |
106 | void __iomem *base; | 106 | void __iomem *base; |
107 | u32 pcr; | ||
107 | struct clk *clk; | 108 | struct clk *clk; |
108 | struct davinci_pcm_dma_params *dma_params[2]; | 109 | struct davinci_pcm_dma_params *dma_params[2]; |
109 | }; | 110 | }; |
@@ -119,17 +120,34 @@ static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg) | |||
119 | return __raw_readl(dev->base + reg); | 120 | return __raw_readl(dev->base + reg); |
120 | } | 121 | } |
121 | 122 | ||
123 | static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback) | ||
124 | { | ||
125 | u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP; | ||
126 | /* The clock needs to toggle to complete reset. | ||
127 | * So, fake it by toggling the clk polarity. | ||
128 | */ | ||
129 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m); | ||
130 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr); | ||
131 | } | ||
132 | |||
122 | static void davinci_mcbsp_start(struct snd_pcm_substream *substream) | 133 | static void davinci_mcbsp_start(struct snd_pcm_substream *substream) |
123 | { | 134 | { |
124 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 135 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
125 | struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; | 136 | struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; |
126 | struct snd_soc_device *socdev = rtd->socdev; | 137 | struct snd_soc_device *socdev = rtd->socdev; |
127 | struct snd_soc_platform *platform = socdev->card->platform; | 138 | struct snd_soc_platform *platform = socdev->card->platform; |
139 | int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | ||
128 | u32 spcr; | 140 | u32 spcr; |
129 | int ret; | 141 | int ret; |
130 | 142 | u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST; | |
131 | /* Start the sample generator and enable transmitter/receiver */ | ||
132 | spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); | 143 | spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); |
144 | if (spcr & mask) { | ||
145 | /* start off disabled */ | ||
146 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, | ||
147 | spcr & ~mask); | ||
148 | toggle_clock(dev, playback); | ||
149 | } | ||
150 | /* Start the sample generator and enable transmitter/receiver */ | ||
133 | spcr |= DAVINCI_MCBSP_SPCR_GRST; | 151 | spcr |= DAVINCI_MCBSP_SPCR_GRST; |
134 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); | 152 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); |
135 | 153 | ||
@@ -155,6 +173,7 @@ static void davinci_mcbsp_start(struct snd_pcm_substream *substream) | |||
155 | spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); | 173 | spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); |
156 | spcr &= ~DAVINCI_MCBSP_SPCR_XRST; | 174 | spcr &= ~DAVINCI_MCBSP_SPCR_XRST; |
157 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); | 175 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); |
176 | toggle_clock(dev, playback); | ||
158 | 177 | ||
159 | /* Restart the DMA */ | 178 | /* Restart the DMA */ |
160 | if (platform->pcm_ops->trigger) { | 179 | if (platform->pcm_ops->trigger) { |
@@ -188,15 +207,14 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream) | |||
188 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 207 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
189 | struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; | 208 | struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; |
190 | u32 spcr; | 209 | u32 spcr; |
210 | int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | ||
191 | 211 | ||
192 | /* Reset transmitter/receiver and sample rate/frame sync generators */ | 212 | /* Reset transmitter/receiver and sample rate/frame sync generators */ |
193 | spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); | 213 | spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); |
194 | spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST); | 214 | spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST); |
195 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 215 | spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST; |
196 | spcr &= ~DAVINCI_MCBSP_SPCR_XRST; | ||
197 | else | ||
198 | spcr &= ~DAVINCI_MCBSP_SPCR_RRST; | ||
199 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); | 216 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); |
217 | toggle_clock(dev, playback); | ||
200 | } | 218 | } |
201 | 219 | ||
202 | static int davinci_i2s_startup(struct snd_pcm_substream *substream, | 220 | 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, | |||
334 | return -EINVAL; | 352 | return -EINVAL; |
335 | } | 353 | } |
336 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); | 354 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); |
355 | dev->pcr = pcr; | ||
337 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); | 356 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); |
338 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); | 357 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); |
339 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); | 358 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); |