diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/pxa/corgi.c | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 2b1c6e94d1e4..5ee51a994ac3 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include "../codecs/wm8731.h" | 38 | #include "../codecs/wm8731.h" |
39 | #include "pxa2xx-pcm.h" | 39 | #include "pxa2xx-pcm.h" |
40 | #include "pxa2xx-i2s.h" | ||
40 | 41 | ||
41 | #define CORGI_HP 0 | 42 | #define CORGI_HP 0 |
42 | #define CORGI_MIC 1 | 43 | #define CORGI_MIC 1 |
@@ -119,8 +120,59 @@ static int corgi_shutdown(struct snd_pcm_substream *substream) | |||
119 | return 0; | 120 | return 0; |
120 | } | 121 | } |
121 | 122 | ||
123 | static int corgi_hw_params(struct snd_pcm_substream *substream, | ||
124 | struct snd_pcm_hw_params *params) | ||
125 | { | ||
126 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
127 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
128 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | ||
129 | unsigned int clk = 0; | ||
130 | int ret = 0; | ||
131 | |||
132 | switch (params_rate(params)) { | ||
133 | case 8000: | ||
134 | case 16000: | ||
135 | case 48000: | ||
136 | case 96000: | ||
137 | clk = 12288000; | ||
138 | break; | ||
139 | case 11025: | ||
140 | case 22050: | ||
141 | case 44100: | ||
142 | clk = 11289600; | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | /* set codec DAI configuration */ | ||
147 | ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
148 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
149 | if (ret < 0) | ||
150 | return ret; | ||
151 | |||
152 | /* set cpu DAI configuration */ | ||
153 | ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
154 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
155 | if (ret < 0) | ||
156 | return ret; | ||
157 | |||
158 | /* set the codec system clock for DAC and ADC */ | ||
159 | ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, | ||
160 | SND_SOC_CLOCK_IN); | ||
161 | if (ret < 0) | ||
162 | return ret; | ||
163 | |||
164 | /* set the I2S system clock as input (unused) */ | ||
165 | ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, | ||
166 | SND_SOC_CLOCK_IN); | ||
167 | if (ret < 0) | ||
168 | return ret; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
122 | static struct snd_soc_ops corgi_ops = { | 173 | static struct snd_soc_ops corgi_ops = { |
123 | .startup = corgi_startup, | 174 | .startup = corgi_startup, |
175 | .hw_params = corgi_hw_params, | ||
124 | .shutdown = corgi_shutdown, | 176 | .shutdown = corgi_shutdown, |
125 | }; | 177 | }; |
126 | 178 | ||
@@ -264,35 +316,6 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec) | |||
264 | return 0; | 316 | return 0; |
265 | } | 317 | } |
266 | 318 | ||
267 | static unsigned int corgi_config_sysclk(struct snd_soc_pcm_runtime *rtd, | ||
268 | struct snd_soc_clock_info *info) | ||
269 | { | ||
270 | if (info->bclk_master & SND_SOC_DAIFMT_CBS_CFS) { | ||
271 | /* pxa2xx is i2s master */ | ||
272 | switch (info->rate) { | ||
273 | case 44100: | ||
274 | case 88200: | ||
275 | /* configure codec digital filters for 44.1, 88.2 */ | ||
276 | rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
277 | 11289600); | ||
278 | break; | ||
279 | default: | ||
280 | /* configure codec digital filters for all other rates */ | ||
281 | rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
282 | CORGI_AUDIO_CLOCK); | ||
283 | break; | ||
284 | } | ||
285 | /* config pxa i2s as master */ | ||
286 | return rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, | ||
287 | CORGI_AUDIO_CLOCK); | ||
288 | } else { | ||
289 | /* codec is i2s master - | ||
290 | * only configure codec DAI clock and filters */ | ||
291 | return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
292 | CORGI_AUDIO_CLOCK); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | /* corgi digital audio interface glue - connects codec <--> CPU */ | 319 | /* corgi digital audio interface glue - connects codec <--> CPU */ |
297 | static struct snd_soc_dai_link corgi_dai = { | 320 | static struct snd_soc_dai_link corgi_dai = { |
298 | .name = "WM8731", | 321 | .name = "WM8731", |
@@ -300,7 +323,7 @@ static struct snd_soc_dai_link corgi_dai = { | |||
300 | .cpu_dai = &pxa_i2s_dai, | 323 | .cpu_dai = &pxa_i2s_dai, |
301 | .codec_dai = &wm8731_dai, | 324 | .codec_dai = &wm8731_dai, |
302 | .init = corgi_wm8731_init, | 325 | .init = corgi_wm8731_init, |
303 | .config_sysclk = corgi_config_sysclk, | 326 | .ops = &corgi_ops, |
304 | }; | 327 | }; |
305 | 328 | ||
306 | /* corgi audio machine driver */ | 329 | /* corgi audio machine driver */ |
@@ -308,7 +331,6 @@ static struct snd_soc_machine snd_soc_machine_corgi = { | |||
308 | .name = "Corgi", | 331 | .name = "Corgi", |
309 | .dai_link = &corgi_dai, | 332 | .dai_link = &corgi_dai, |
310 | .num_links = 1, | 333 | .num_links = 1, |
311 | .ops = &corgi_ops, | ||
312 | }; | 334 | }; |
313 | 335 | ||
314 | /* corgi audio private data */ | 336 | /* corgi audio private data */ |