diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/pxa/spitz.c | 86 |
1 files changed, 53 insertions, 33 deletions
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 17c8e61efe6f..80e82109fef7 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/mach-types.h> | 37 | #include <asm/mach-types.h> |
38 | #include "../codecs/wm8750.h" | 38 | #include "../codecs/wm8750.h" |
39 | #include "pxa2xx-pcm.h" | 39 | #include "pxa2xx-pcm.h" |
40 | #include "pxa2xx-i2s.h" | ||
40 | 41 | ||
41 | #define SPITZ_HP 0 | 42 | #define SPITZ_HP 0 |
42 | #define SPITZ_MIC 1 | 43 | #define SPITZ_MIC 1 |
@@ -121,8 +122,59 @@ static int spitz_startup(struct snd_pcm_substream *substream) | |||
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
123 | 124 | ||
125 | static int spitz_hw_params(struct snd_pcm_substream *substream, | ||
126 | struct snd_pcm_hw_params *params) | ||
127 | { | ||
128 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
129 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
130 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | ||
131 | unsigned int clk = 0; | ||
132 | int ret = 0; | ||
133 | |||
134 | switch (params_rate(params)) { | ||
135 | case 8000: | ||
136 | case 16000: | ||
137 | case 48000: | ||
138 | case 96000: | ||
139 | clk = 12288000; | ||
140 | break; | ||
141 | case 11025: | ||
142 | case 22050: | ||
143 | case 44100: | ||
144 | clk = 11289600; | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | /* set codec DAI configuration */ | ||
149 | ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
150 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | /* set cpu DAI configuration */ | ||
155 | ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
156 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | |||
160 | /* set the codec system clock for DAC and ADC */ | ||
161 | ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8750_SYSCLK, clk, | ||
162 | SND_SOC_CLOCK_IN); | ||
163 | if (ret < 0) | ||
164 | return ret; | ||
165 | |||
166 | /* set the I2S system clock as input (unused) */ | ||
167 | ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, | ||
168 | SND_SOC_CLOCK_IN); | ||
169 | if (ret < 0) | ||
170 | return ret; | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
124 | static struct snd_soc_ops spitz_ops = { | 175 | static struct snd_soc_ops spitz_ops = { |
125 | .startup = spitz_startup, | 176 | .startup = spitz_startup, |
177 | .hw_params = spitz_hw_params, | ||
126 | }; | 178 | }; |
127 | 179 | ||
128 | static int spitz_get_jack(struct snd_kcontrol *kcontrol, | 180 | static int spitz_get_jack(struct snd_kcontrol *kcontrol, |
@@ -276,37 +328,6 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) | |||
276 | return 0; | 328 | return 0; |
277 | } | 329 | } |
278 | 330 | ||
279 | static unsigned int spitz_config_sysclk(struct snd_soc_pcm_runtime *rtd, | ||
280 | struct snd_soc_clock_info *info) | ||
281 | { | ||
282 | if (info->bclk_master & SND_SOC_DAIFMT_CBS_CFS) { | ||
283 | /* pxa2xx is i2s master */ | ||
284 | switch (info->rate) { | ||
285 | case 11025: | ||
286 | case 22050: | ||
287 | case 44100: | ||
288 | case 88200: | ||
289 | /* configure codec digital filters | ||
290 | * for 11.025, 22.05, 44.1, 88.2 */ | ||
291 | rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
292 | 11289600); | ||
293 | break; | ||
294 | default: | ||
295 | /* configure codec digital filters for all other rates */ | ||
296 | rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
297 | SPITZ_AUDIO_CLOCK); | ||
298 | break; | ||
299 | } | ||
300 | /* configure pxa2xx i2s interface clocks as master */ | ||
301 | return rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, | ||
302 | SPITZ_AUDIO_CLOCK); | ||
303 | } else { | ||
304 | /* codec is i2s master - only configure codec DAI clock */ | ||
305 | return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
306 | SPITZ_AUDIO_CLOCK); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | /* spitz digital audio interface glue - connects codec <--> CPU */ | 331 | /* spitz digital audio interface glue - connects codec <--> CPU */ |
311 | static struct snd_soc_dai_link spitz_dai = { | 332 | static struct snd_soc_dai_link spitz_dai = { |
312 | .name = "wm8750", | 333 | .name = "wm8750", |
@@ -314,7 +335,7 @@ static struct snd_soc_dai_link spitz_dai = { | |||
314 | .cpu_dai = &pxa_i2s_dai, | 335 | .cpu_dai = &pxa_i2s_dai, |
315 | .codec_dai = &wm8750_dai, | 336 | .codec_dai = &wm8750_dai, |
316 | .init = spitz_wm8750_init, | 337 | .init = spitz_wm8750_init, |
317 | .config_sysclk = spitz_config_sysclk, | 338 | .ops = &spitz_ops, |
318 | }; | 339 | }; |
319 | 340 | ||
320 | /* spitz audio machine driver */ | 341 | /* spitz audio machine driver */ |
@@ -322,7 +343,6 @@ static struct snd_soc_machine snd_soc_machine_spitz = { | |||
322 | .name = "Spitz", | 343 | .name = "Spitz", |
323 | .dai_link = &spitz_dai, | 344 | .dai_link = &spitz_dai, |
324 | .num_links = 1, | 345 | .num_links = 1, |
325 | .ops = &spitz_ops, | ||
326 | }; | 346 | }; |
327 | 347 | ||
328 | /* spitz audio private data */ | 348 | /* spitz audio private data */ |