diff options
Diffstat (limited to 'sound/soc/pxa/poodle.c')
-rw-r--r-- | sound/soc/pxa/poodle.c | 83 |
1 files changed, 53 insertions, 30 deletions
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index ee9336086820..0915cf740421 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include "../codecs/wm8731.h" | 35 | #include "../codecs/wm8731.h" |
36 | #include "pxa2xx-pcm.h" | 36 | #include "pxa2xx-pcm.h" |
37 | #include "pxa2xx-i2s.h" | ||
37 | 38 | ||
38 | #define POODLE_HP 1 | 39 | #define POODLE_HP 1 |
39 | #define POODLE_HP_OFF 0 | 40 | #define POODLE_HP_OFF 0 |
@@ -100,8 +101,59 @@ static int poodle_shutdown(struct snd_pcm_substream *substream) | |||
100 | return 0; | 101 | return 0; |
101 | } | 102 | } |
102 | 103 | ||
104 | static int poodle_hw_params(struct snd_pcm_substream *substream, | ||
105 | struct snd_pcm_hw_params *params) | ||
106 | { | ||
107 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
108 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
109 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | ||
110 | unsigned int clk = 0; | ||
111 | int ret = 0; | ||
112 | |||
113 | switch (params_rate(params)) { | ||
114 | case 8000: | ||
115 | case 16000: | ||
116 | case 48000: | ||
117 | case 96000: | ||
118 | clk = 12288000; | ||
119 | break; | ||
120 | case 11025: | ||
121 | case 22050: | ||
122 | case 44100: | ||
123 | clk = 11289600; | ||
124 | break; | ||
125 | } | ||
126 | |||
127 | /* set codec DAI configuration */ | ||
128 | ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
129 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | |||
133 | /* set cpu DAI configuration */ | ||
134 | ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
135 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* set the codec system clock for DAC and ADC */ | ||
140 | ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, | ||
141 | SND_SOC_CLOCK_IN); | ||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | |||
145 | /* set the I2S system clock as input (unused) */ | ||
146 | ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, | ||
147 | SND_SOC_CLOCK_IN); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
103 | static struct snd_soc_ops poodle_ops = { | 154 | static struct snd_soc_ops poodle_ops = { |
104 | .startup = poodle_startup, | 155 | .startup = poodle_startup, |
156 | .hw_params = poodle_hw_params, | ||
105 | .shutdown = poodle_shutdown, | 157 | .shutdown = poodle_shutdown, |
106 | }; | 158 | }; |
107 | 159 | ||
@@ -225,34 +277,6 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec) | |||
225 | return 0; | 277 | return 0; |
226 | } | 278 | } |
227 | 279 | ||
228 | static unsigned int poodle_config_sysclk(struct snd_soc_pcm_runtime *rtd, | ||
229 | struct snd_soc_clock_info *info) | ||
230 | { | ||
231 | if (info->bclk_master & SND_SOC_DAIFMT_CBS_CFS) { | ||
232 | /* pxa2xx is i2s master */ | ||
233 | switch (info->rate) { | ||
234 | case 44100: | ||
235 | case 88200: | ||
236 | /* configure codec digital filters for 44.1, 88.2 */ | ||
237 | rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
238 | 11289600); | ||
239 | break; | ||
240 | default: | ||
241 | /* configure codec digital filters for all other rates */ | ||
242 | rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
243 | POODLE_AUDIO_CLOCK); | ||
244 | break; | ||
245 | } | ||
246 | return rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, | ||
247 | POODLE_AUDIO_CLOCK); | ||
248 | } else { | ||
249 | /* codec is i2s master - | ||
250 | * only configure codec DAI clock and filters */ | ||
251 | return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, | ||
252 | POODLE_AUDIO_CLOCK); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /* poodle digital audio interface glue - connects codec <--> CPU */ | 280 | /* poodle digital audio interface glue - connects codec <--> CPU */ |
257 | static struct snd_soc_dai_link poodle_dai = { | 281 | static struct snd_soc_dai_link poodle_dai = { |
258 | .name = "WM8731", | 282 | .name = "WM8731", |
@@ -260,7 +284,7 @@ static struct snd_soc_dai_link poodle_dai = { | |||
260 | .cpu_dai = &pxa_i2s_dai, | 284 | .cpu_dai = &pxa_i2s_dai, |
261 | .codec_dai = &wm8731_dai, | 285 | .codec_dai = &wm8731_dai, |
262 | .init = poodle_wm8731_init, | 286 | .init = poodle_wm8731_init, |
263 | .config_sysclk = poodle_config_sysclk, | 287 | .ops = &poodle_ops, |
264 | }; | 288 | }; |
265 | 289 | ||
266 | /* poodle audio machine driver */ | 290 | /* poodle audio machine driver */ |
@@ -268,7 +292,6 @@ static struct snd_soc_machine snd_soc_machine_poodle = { | |||
268 | .name = "Poodle", | 292 | .name = "Poodle", |
269 | .dai_link = &poodle_dai, | 293 | .dai_link = &poodle_dai, |
270 | .num_links = 1, | 294 | .num_links = 1, |
271 | .ops = &poodle_ops, | ||
272 | }; | 295 | }; |
273 | 296 | ||
274 | /* poodle audio private data */ | 297 | /* poodle audio private data */ |