Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 157561
b: refs/heads/master
c: 2a01e5f
h: refs/heads/master
i:
  157559: a5f4f59
v: v3
  • Loading branch information
Mark Brown committed Jul 8, 2009
1 parent 9f3322f commit 3a87321
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 88 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4934482d93ca42d57180e08bf3ee6b77124f5f8e
refs/heads/master: 2a01e5f3587be459c934d711bffddc14d66386f3
89 changes: 2 additions & 87 deletions trunk/sound/soc/atmel/sam9g20_wm8731.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,102 +87,17 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
struct ssc_device *ssc = ssc_p->ssc;
int ret;

unsigned int rate;
int cmr_div, period;

if (ssc == NULL) {
printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
return -EINVAL;
}

/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;

/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0)
return ret;

/*
* The SSC clock dividers depend on the sample rate. The CMR.DIV
* field divides the system master clock MCK to drive the SSC TK
* signal which provides the codec BCLK. The TCMR.PERIOD and
* RCMR.PERIOD fields further divide the BCLK signal to drive
* the SSC TF and RF signals which provide the codec DACLRC and
* ADCLRC clocks.
*
* The dividers were determined through trial and error, where a
* CMR.DIV value is chosen such that the resulting BCLK value is
* divisible, or almost divisible, by (2 * sample rate), and then
* the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
*/
rate = params_rate(params);

switch (rate) {
case 8000:
cmr_div = 55; /* BCLK = 133MHz/(2*55) = 1.209MHz */
period = 74; /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
break;
case 11025:
cmr_div = 67; /* BCLK = 133MHz/(2*60) = 1.108MHz */
period = 45; /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
break;
case 16000:
cmr_div = 63; /* BCLK = 133MHz/(2*63) = 1.055MHz */
period = 32; /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
break;
case 22050:
cmr_div = 52; /* BCLK = 133MHz/(2*52) = 1.278MHz */
period = 28; /* LRC = BCLK/(2*(28+1)) = 22049Hz */
break;
case 32000:
cmr_div = 66; /* BCLK = 133MHz/(2*66) = 1.007MHz */
period = 15; /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
break;
case 44100:
cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
period = 25; /* LRC = BCLK/(2*(25+1)) = 44098Hz */
break;
case 48000:
cmr_div = 33; /* BCLK = 133MHz/(2*33) = 2.015MHz */
period = 20; /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
break;
case 88200:
cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
period = 12; /* LRC = BCLK/(2*(12+1)) = 88196Hz */
break;
case 96000:
cmr_div = 23; /* BCLK = 133MHz/(2*23) = 2.891MHz */
period = 14; /* LRC = BCLK/(2*(14+1)) = 96376Hz */
break;
default:
printk(KERN_WARNING "unsupported rate %d"
" on at91sam9g20ek board\n", rate);
return -EINVAL;
}

/* set the MCK divider for BCLK */
ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
if (ret < 0)
return ret;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/* set the BCLK divider for DACLRC */
ret = snd_soc_dai_set_clkdiv(cpu_dai,
ATMEL_SSC_TCMR_PERIOD, period);
} else {
/* set the BCLK divider for ADCLRC */
ret = snd_soc_dai_set_clkdiv(cpu_dai,
ATMEL_SSC_RCMR_PERIOD, period);
}
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;

Expand Down

0 comments on commit 3a87321

Please sign in to comment.