aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa/pxa2xx-i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa/pxa2xx-i2s.c')
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 2f4b6e489b78..4743e262895d 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -106,10 +106,8 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
106 if (IS_ERR(clk_i2s)) 106 if (IS_ERR(clk_i2s))
107 return PTR_ERR(clk_i2s); 107 return PTR_ERR(clk_i2s);
108 108
109 if (!cpu_dai->active) { 109 if (!cpu_dai->active)
110 SACR0 |= SACR0_RST;
111 SACR0 = 0; 110 SACR0 = 0;
112 }
113 111
114 return 0; 112 return 0;
115} 113}
@@ -178,9 +176,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
178 176
179 /* is port used by another stream */ 177 /* is port used by another stream */
180 if (!(SACR0 & SACR0_ENB)) { 178 if (!(SACR0 & SACR0_ENB)) {
181
182 SACR0 = 0; 179 SACR0 = 0;
183 SACR1 = 0;
184 if (pxa_i2s.master) 180 if (pxa_i2s.master)
185 SACR0 |= SACR0_BCKD; 181 SACR0 |= SACR0_BCKD;
186 182
@@ -226,6 +222,10 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
226 222
227 switch (cmd) { 223 switch (cmd) {
228 case SNDRV_PCM_TRIGGER_START: 224 case SNDRV_PCM_TRIGGER_START:
225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
226 SACR1 &= ~SACR1_DRPL;
227 else
228 SACR1 &= ~SACR1_DREC;
229 SACR0 |= SACR0_ENB; 229 SACR0 |= SACR0_ENB;
230 break; 230 break;
231 case SNDRV_PCM_TRIGGER_RESUME: 231 case SNDRV_PCM_TRIGGER_RESUME:
@@ -252,21 +252,16 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
252 SAIMR &= ~SAIMR_RFS; 252 SAIMR &= ~SAIMR_RFS;
253 } 253 }
254 254
255 if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { 255 if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
256 SACR0 &= ~SACR0_ENB; 256 SACR0 &= ~SACR0_ENB;
257 pxa_i2s_wait(); 257 pxa_i2s_wait();
258 clk_disable(clk_i2s); 258 clk_disable(clk_i2s);
259 } 259 }
260
261 clk_put(clk_i2s);
262} 260}
263 261
264#ifdef CONFIG_PM 262#ifdef CONFIG_PM
265static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai) 263static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
266{ 264{
267 if (!dai->active)
268 return 0;
269
270 /* store registers */ 265 /* store registers */
271 pxa_i2s.sacr0 = SACR0; 266 pxa_i2s.sacr0 = SACR0;
272 pxa_i2s.sacr1 = SACR1; 267 pxa_i2s.sacr1 = SACR1;
@@ -281,16 +276,14 @@ static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
281 276
282static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) 277static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
283{ 278{
284 if (!dai->active)
285 return 0;
286
287 pxa_i2s_wait(); 279 pxa_i2s_wait();
288 280
289 SACR0 = pxa_i2s.sacr0 &= ~SACR0_ENB; 281 SACR0 = pxa_i2s.sacr0 & ~SACR0_ENB;
290 SACR1 = pxa_i2s.sacr1; 282 SACR1 = pxa_i2s.sacr1;
291 SAIMR = pxa_i2s.saimr; 283 SAIMR = pxa_i2s.saimr;
292 SADIV = pxa_i2s.sadiv; 284 SADIV = pxa_i2s.sadiv;
293 SACR0 |= SACR0_ENB; 285
286 SACR0 = pxa_i2s.sacr0;
294 287
295 return 0; 288 return 0;
296} 289}
@@ -329,6 +322,7 @@ struct snd_soc_dai pxa_i2s_dai = {
329 .rates = PXA2XX_I2S_RATES, 322 .rates = PXA2XX_I2S_RATES,
330 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 323 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
331 .ops = &pxa_i2s_dai_ops, 324 .ops = &pxa_i2s_dai_ops,
325 .symmetric_rates = 1,
332}; 326};
333 327
334EXPORT_SYMBOL_GPL(pxa_i2s_dai); 328EXPORT_SYMBOL_GPL(pxa_i2s_dai);
@@ -346,6 +340,19 @@ static int pxa2xx_i2s_probe(struct platform_device *dev)
346 if (ret != 0) 340 if (ret != 0)
347 clk_put(clk_i2s); 341 clk_put(clk_i2s);
348 342
343 /*
344 * PXA Developer's Manual:
345 * If SACR0[ENB] is toggled in the middle of a normal operation,
346 * the SACR0[RST] bit must also be set and cleared to reset all
347 * I2S controller registers.
348 */
349 SACR0 = SACR0_RST;
350 SACR0 = 0;
351 /* Make sure RPL and REC are disabled */
352 SACR1 = SACR1_DRPL | SACR1_DREC;
353 /* Along with FIFO servicing */
354 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
355
349 return ret; 356 return ret;
350} 357}
351 358