aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
authorTroy Kisky <troy.kisky@boundarydevices.com>2009-07-04 22:29:52 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-05 07:59:06 -0400
commitc392bec716431d77e503345117a3e7ad3face677 (patch)
tree54f0269e87bb9aa6aeaf3fab937aa90c22df8cad /sound/soc/davinci
parent35cf63583d8d81d8ac261e944db9eeb44a60692d (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.c31
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
105struct davinci_mcbsp_dev { 105struct 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
123static 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
122static void davinci_mcbsp_start(struct snd_pcm_substream *substream) 133static 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
202static int davinci_i2s_startup(struct snd_pcm_substream *substream, 220static 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);