aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa/pxa-ssp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa/pxa-ssp.c')
-rw-r--r--sound/soc/pxa/pxa-ssp.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 308a657928d2..286be31545df 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -280,12 +280,33 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
280 * ssp_set_clkdiv - set SSP clock divider 280 * ssp_set_clkdiv - set SSP clock divider
281 * @div: serial clock rate divider 281 * @div: serial clock rate divider
282 */ 282 */
283static void ssp_set_scr(struct ssp_dev *dev, u32 div) 283static void ssp_set_scr(struct ssp_device *ssp, u32 div)
284{ 284{
285 struct ssp_device *ssp = dev->ssp; 285 u32 sscr0 = ssp_read_reg(ssp, SSCR0);
286 u32 sscr0 = ssp_read_reg(dev->ssp, SSCR0) & ~SSCR0_SCR; 286
287 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
288 sscr0 &= ~0x0000ff00;
289 sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
290 } else {
291 sscr0 &= ~0x000fff00;
292 sscr0 |= (div - 1) << 8; /* 1..4096 */
293 }
294 ssp_write_reg(ssp, SSCR0, sscr0);
295}
296
297/**
298 * ssp_get_clkdiv - get SSP clock divider
299 */
300static u32 ssp_get_scr(struct ssp_device *ssp)
301{
302 u32 sscr0 = ssp_read_reg(ssp, SSCR0);
303 u32 div;
287 304
288 ssp_write_reg(ssp, SSCR0, (sscr0 | SSCR0_SerClkDiv(div))); 305 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
306 div = ((sscr0 >> 8) & 0xff) * 2 + 2;
307 else
308 div = ((sscr0 >> 8) & 0xfff) + 1;
309 return div;
289} 310}
290 311
291/* 312/*
@@ -326,7 +347,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
326 break; 347 break;
327 case PXA_SSP_CLK_AUDIO: 348 case PXA_SSP_CLK_AUDIO:
328 priv->sysclk = 0; 349 priv->sysclk = 0;
329 ssp_set_scr(&priv->dev, 1); 350 ssp_set_scr(ssp, 1);
330 sscr0 |= SSCR0_ACS; 351 sscr0 |= SSCR0_ACS;
331 break; 352 break;
332 default: 353 default:
@@ -387,7 +408,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
387 ssp_write_reg(ssp, SSACD, val); 408 ssp_write_reg(ssp, SSACD, val);
388 break; 409 break;
389 case PXA_SSP_DIV_SCR: 410 case PXA_SSP_DIV_SCR:
390 ssp_set_scr(&priv->dev, div); 411 ssp_set_scr(ssp, div);
391 break; 412 break;
392 default: 413 default:
393 return -ENODEV; 414 return -ENODEV;
@@ -674,8 +695,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
674 case SND_SOC_DAIFMT_I2S: 695 case SND_SOC_DAIFMT_I2S:
675 sspsp = ssp_read_reg(ssp, SSPSP); 696 sspsp = ssp_read_reg(ssp, SSPSP);
676 697
677 if (((sscr0 & SSCR0_SCR) == SSCR0_SerClkDiv(4)) && 698 if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
678 (width == 16)) {
679 /* This is a special case where the bitclk is 64fs 699 /* This is a special case where the bitclk is 64fs
680 * and we're not dealing with 2*32 bits of audio 700 * and we're not dealing with 2*32 bits of audio
681 * samples. 701 * samples.
@@ -806,6 +826,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
806 goto err_priv; 826 goto err_priv;
807 } 827 }
808 828
829 priv->dai_fmt = (unsigned int) -1;
809 dai->private_data = priv; 830 dai->private_data = priv;
810 831
811 return 0; 832 return 0;