diff options
Diffstat (limited to 'sound/soc/pxa/pxa2xx-i2s.c')
-rw-r--r-- | sound/soc/pxa/pxa2xx-i2s.c | 39 |
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 |
265 | static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai) | 263 | static 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 | ||
282 | static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) | 277 | static 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 | ||
334 | EXPORT_SYMBOL_GPL(pxa_i2s_dai); | 328 | EXPORT_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 | ||