diff options
Diffstat (limited to 'sound/soc/atmel')
-rw-r--r-- | sound/soc/atmel/sam9g20_wm8731.c | 89 |
1 files changed, 2 insertions, 87 deletions
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 173a239a541..9abab94fe2c 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
@@ -87,102 +87,17 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream, | |||
87 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 87 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
88 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | 88 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; |
89 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 89 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
90 | struct atmel_ssc_info *ssc_p = cpu_dai->private_data; | ||
91 | struct ssc_device *ssc = ssc_p->ssc; | ||
92 | int ret; | 90 | int ret; |
93 | 91 | ||
94 | unsigned int rate; | ||
95 | int cmr_div, period; | ||
96 | |||
97 | if (ssc == NULL) { | ||
98 | printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n"); | ||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | /* set codec DAI configuration */ | 92 | /* set codec DAI configuration */ |
103 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | 93 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | |
104 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | 94 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); |
105 | if (ret < 0) | 95 | if (ret < 0) |
106 | return ret; | 96 | return ret; |
107 | 97 | ||
108 | /* set cpu DAI configuration */ | 98 | /* set cpu DAI configuration */ |
109 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | 99 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | |
110 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | 100 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); |
111 | if (ret < 0) | ||
112 | return ret; | ||
113 | |||
114 | /* | ||
115 | * The SSC clock dividers depend on the sample rate. The CMR.DIV | ||
116 | * field divides the system master clock MCK to drive the SSC TK | ||
117 | * signal which provides the codec BCLK. The TCMR.PERIOD and | ||
118 | * RCMR.PERIOD fields further divide the BCLK signal to drive | ||
119 | * the SSC TF and RF signals which provide the codec DACLRC and | ||
120 | * ADCLRC clocks. | ||
121 | * | ||
122 | * The dividers were determined through trial and error, where a | ||
123 | * CMR.DIV value is chosen such that the resulting BCLK value is | ||
124 | * divisible, or almost divisible, by (2 * sample rate), and then | ||
125 | * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1. | ||
126 | */ | ||
127 | rate = params_rate(params); | ||
128 | |||
129 | switch (rate) { | ||
130 | case 8000: | ||
131 | cmr_div = 55; /* BCLK = 133MHz/(2*55) = 1.209MHz */ | ||
132 | period = 74; /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */ | ||
133 | break; | ||
134 | case 11025: | ||
135 | cmr_div = 67; /* BCLK = 133MHz/(2*60) = 1.108MHz */ | ||
136 | period = 45; /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */ | ||
137 | break; | ||
138 | case 16000: | ||
139 | cmr_div = 63; /* BCLK = 133MHz/(2*63) = 1.055MHz */ | ||
140 | period = 32; /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */ | ||
141 | break; | ||
142 | case 22050: | ||
143 | cmr_div = 52; /* BCLK = 133MHz/(2*52) = 1.278MHz */ | ||
144 | period = 28; /* LRC = BCLK/(2*(28+1)) = 22049Hz */ | ||
145 | break; | ||
146 | case 32000: | ||
147 | cmr_div = 66; /* BCLK = 133MHz/(2*66) = 1.007MHz */ | ||
148 | period = 15; /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */ | ||
149 | break; | ||
150 | case 44100: | ||
151 | cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */ | ||
152 | period = 25; /* LRC = BCLK/(2*(25+1)) = 44098Hz */ | ||
153 | break; | ||
154 | case 48000: | ||
155 | cmr_div = 33; /* BCLK = 133MHz/(2*33) = 2.015MHz */ | ||
156 | period = 20; /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */ | ||
157 | break; | ||
158 | case 88200: | ||
159 | cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */ | ||
160 | period = 12; /* LRC = BCLK/(2*(12+1)) = 88196Hz */ | ||
161 | break; | ||
162 | case 96000: | ||
163 | cmr_div = 23; /* BCLK = 133MHz/(2*23) = 2.891MHz */ | ||
164 | period = 14; /* LRC = BCLK/(2*(14+1)) = 96376Hz */ | ||
165 | break; | ||
166 | default: | ||
167 | printk(KERN_WARNING "unsupported rate %d" | ||
168 | " on at91sam9g20ek board\n", rate); | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | |||
172 | /* set the MCK divider for BCLK */ | ||
173 | ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div); | ||
174 | if (ret < 0) | ||
175 | return ret; | ||
176 | |||
177 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
178 | /* set the BCLK divider for DACLRC */ | ||
179 | ret = snd_soc_dai_set_clkdiv(cpu_dai, | ||
180 | ATMEL_SSC_TCMR_PERIOD, period); | ||
181 | } else { | ||
182 | /* set the BCLK divider for ADCLRC */ | ||
183 | ret = snd_soc_dai_set_clkdiv(cpu_dai, | ||
184 | ATMEL_SSC_RCMR_PERIOD, period); | ||
185 | } | ||
186 | if (ret < 0) | 101 | if (ret < 0) |
187 | return ret; | 102 | return ret; |
188 | 103 | ||