diff options
author | Liam Girdwood <lg@opensource.wolfsonmicro.com> | 2006-10-19 14:35:56 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:01:07 -0500 |
commit | a71a468a50f1385855e28864e26251b02df829bb (patch) | |
tree | 243daee96ea5c55c88a186aa03b7917f7ad533f6 | |
parent | 543a0fbe18d0b44f3d037fe6b59458fa0c0d5e4b (diff) |
[ALSA] ASoC: Add support for BCLK based on (Rate * Chn * Word Size)
This patch adds support for the DAI BCLK to be generated by multiplying
Rate * Channels * Word Size (RCW).
This now gives 3 options for BCLK clocking and synchronisation :-
1. BCLK = Rate * x
2. BCLK = MCLK / x
3. BCLK = Rate * Chn * Word Size. (New)
Changes:-
o Add support for RCW generation of BCLK
o Update Documentation to include RCW.
o Update DAI documentation for label = value DAI modes.
o Add RCW support to wm8731, wm8750 and pxa2xx-i2s drivers.
Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r-- | Documentation/sound/alsa/soc/DAI.txt | 358 | ||||
-rw-r--r-- | Documentation/sound/alsa/soc/clocking.txt | 13 | ||||
-rw-r--r-- | include/sound/soc.h | 23 | ||||
-rw-r--r-- | sound/soc/codecs/wm8731.c | 33 | ||||
-rw-r--r-- | sound/soc/codecs/wm8750.c | 15 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-i2s.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 215 |
7 files changed, 481 insertions, 179 deletions
diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt index 919de76bab8d..251545a88693 100644 --- a/Documentation/sound/alsa/soc/DAI.txt +++ b/Documentation/sound/alsa/soc/DAI.txt | |||
@@ -12,7 +12,8 @@ The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the | |||
12 | frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 | 12 | frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 |
13 | frame is 21uS long and is divided into 13 time slots. | 13 | frame is 21uS long and is divided into 13 time slots. |
14 | 14 | ||
15 | The AC97 specification can be found at http://intel.com/ | 15 | The AC97 specification can be found at :- |
16 | http://www.intel.com/design/chipsets/audio/ac97_r23.pdf | ||
16 | 17 | ||
17 | 18 | ||
18 | I2S | 19 | I2S |
@@ -77,16 +78,16 @@ sample rates first and then test your interface. | |||
77 | struct snd_soc_dai_mode is defined (in soc.h) as:- | 78 | struct snd_soc_dai_mode is defined (in soc.h) as:- |
78 | 79 | ||
79 | /* SoC DAI mode */ | 80 | /* SoC DAI mode */ |
80 | struct snd_soc_hw_mode { | 81 | struct snd_soc_dai_mode { |
81 | unsigned int fmt:16; /* SND_SOC_DAIFMT_* */ | 82 | u16 fmt; /* SND_SOC_DAIFMT_* */ |
82 | unsigned int tdm:16; /* SND_SOC_DAITDM_* */ | 83 | u16 tdm; /* SND_SOC_HWTDM_* */ |
83 | unsigned int pcmfmt:6; /* SNDRV_PCM_FORMAT_* */ | 84 | u64 pcmfmt; /* SNDRV_PCM_FMTBIT_* */ |
84 | unsigned int pcmrate:16; /* SND_SOC_DAIRATE_* */ | 85 | u16 pcmrate; /* SND_SOC_HWRATE_* */ |
85 | unsigned int pcmdir:2; /* SND_SOC_DAIDIR_* */ | 86 | u16 pcmdir:2; /* SND_SOC_HWDIR_* */ |
86 | unsigned int flags:8; /* hw flags */ | 87 | u16 flags:8; /* hw flags */ |
87 | unsigned int fs:32; /* mclk to rate dividers */ | 88 | u16 fs; /* mclk to rate divider */ |
88 | unsigned int bfs:16; /* mclk to bclk dividers */ | 89 | u64 bfs; /* mclk to bclk dividers */ |
89 | unsigned long priv; /* private mode data */ | 90 | unsigned long priv; /* private mode data */ |
90 | }; | 91 | }; |
91 | 92 | ||
92 | fmt: | 93 | fmt: |
@@ -140,14 +141,14 @@ pcmfmt: | |||
140 | The hardware PCM format. This describes the PCM formats supported by the DAI | 141 | The hardware PCM format. This describes the PCM formats supported by the DAI |
141 | mode e.g. | 142 | mode e.g. |
142 | 143 | ||
143 | .hwpcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ | 144 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ |
144 | SNDRV_PCM_FORMAT_S24_3LE | 145 | SNDRV_PCM_FORMAT_S24_3LE |
145 | 146 | ||
146 | pcmrate: | 147 | pcmrate: |
147 | ---------- | 148 | ---------- |
148 | The PCM sample rates supported by the DAI mode. e.g. | 149 | The PCM sample rates supported by the DAI mode. e.g. |
149 | 150 | ||
150 | .hwpcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ | 151 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ |
151 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | 152 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
152 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | 153 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
153 | 154 | ||
@@ -161,9 +162,14 @@ flags: | |||
161 | -------- | 162 | -------- |
162 | The DAI hardware flags supported by the mode. | 163 | The DAI hardware flags supported by the mode. |
163 | 164 | ||
164 | SND_SOC_DAI_BFS_DIV | 165 | /* use bfs mclk divider mode (BCLK = MCLK / x) */ |
165 | This flag states that bit clock is generated by dividing MCLK in this mode, if | 166 | #define SND_SOC_DAI_BFS_DIV 0x1 |
166 | this flag is absent the bitclock generated by mulitiplying sample rate. | 167 | /* use bfs rate mulitplier (BCLK = RATE * x)*/ |
168 | #define SND_SOC_DAI_BFS_RATE 0x2 | ||
169 | /* use bfs rcw multiplier (BCLK = RATE * CHN * WORD SIZE) */ | ||
170 | #define SND_SOC_DAI_BFS_RCW 0x4 | ||
171 | /* capture and playback can use different clocks */ | ||
172 | #define SND_SOC_DAI_ASYNC 0x8 | ||
167 | 173 | ||
168 | NOTE: Bitclock division and mulitiplication modes can be safely matched by the | 174 | NOTE: Bitclock division and mulitiplication modes can be safely matched by the |
169 | core logic. | 175 | core logic. |
@@ -181,7 +187,7 @@ depends on the codec or CPU DAI). | |||
181 | 187 | ||
182 | The BFS supported by the DAI mode. This can either be the ratio between the | 188 | The BFS supported by the DAI mode. This can either be the ratio between the |
183 | bitclock (BCLK) and the sample rate OR the ratio between the system clock and | 189 | bitclock (BCLK) and the sample rate OR the ratio between the system clock and |
184 | the sample rate. Depends on the SND_SOC_DAI_BFS_DIV flag above. | 190 | the sample rate. Depends on the flags above. |
185 | 191 | ||
186 | priv: | 192 | priv: |
187 | ----- | 193 | ----- |
@@ -207,10 +213,15 @@ Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a | |||
207 | BCLK of either MCLK/2 or MCLK/4. | 213 | BCLK of either MCLK/2 or MCLK/4. |
208 | 214 | ||
209 | /* codec master */ | 215 | /* codec master */ |
210 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 216 | { |
211 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | 217 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
212 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 218 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
213 | 256, SND_SOC_FSBD(2) | SND_SOC_FSBD(4)}, | 219 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, |
220 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
221 | .flags = SND_SOC_DAI_BFS_DIV, | ||
222 | .fs = 256, | ||
223 | .bfs = SND_SOC_FSBD(2) | SND_SOC_FSBD(4), | ||
224 | } | ||
214 | 225 | ||
215 | 226 | ||
216 | Example 2 | 227 | Example 2 |
@@ -219,32 +230,95 @@ Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a | |||
219 | BCLK of either Rate * 32 or Rate * 64. | 230 | BCLK of either Rate * 32 or Rate * 64. |
220 | 231 | ||
221 | /* codec master */ | 232 | /* codec master */ |
222 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 233 | { |
223 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | 234 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
224 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, | 235 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
225 | 256, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, | 236 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, |
237 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
238 | .flags = SND_SOC_DAI_BFS_RATE, | ||
239 | .fs = 256, | ||
240 | .bfs = 32, | ||
241 | }, | ||
242 | { | ||
243 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | ||
244 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | ||
245 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | ||
246 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
247 | .flags = SND_SOC_DAI_BFS_RATE, | ||
248 | .fs = 256, | ||
249 | .bfs = 64, | ||
250 | }, | ||
226 | 251 | ||
227 | 252 | ||
228 | Example 3 | 253 | Example 3 |
229 | --------- | 254 | --------- |
255 | Codec that runs at 8k & 48k @ 256FS in master mode, can generate a BCLK that | ||
256 | is a multiple of Rate * channels * word size. (RCW) i.e. | ||
257 | |||
258 | BCLK = 8000 * 2 * 16 (8k, stereo, 16bit) | ||
259 | = 256kHz | ||
260 | |||
261 | This codecs supports a RCW multiple of 1,2 | ||
262 | |||
263 | { | ||
264 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | ||
265 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | ||
266 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | ||
267 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
268 | .flags = SND_SOC_DAI_BFS_RCW, | ||
269 | .fs = 256, | ||
270 | .bfs = SND_SOC_FSBW(1) | SND_SOC_FSBW(2), | ||
271 | } | ||
272 | |||
273 | |||
274 | Example 4 | ||
275 | --------- | ||
230 | Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a | 276 | Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a |
231 | BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long | 277 | BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long |
232 | as BCLK is rate * 32 or rate * 64. | 278 | as BCLK is rate * 32 or rate * 64. |
233 | 279 | ||
234 | /* codec master */ | 280 | /* codec master */ |
235 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 281 | { |
236 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | 282 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
237 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, | 283 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
238 | 256, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, | 284 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, |
285 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
286 | .flags = SND_SOC_DAI_BFS_RATE, | ||
287 | .fs = 256, | ||
288 | .bfs = 32, | ||
289 | }, | ||
290 | { | ||
291 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | ||
292 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | ||
293 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | ||
294 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
295 | .flags = SND_SOC_DAI_BFS_RATE, | ||
296 | .fs = 256, | ||
297 | .bfs = 64, | ||
298 | }, | ||
239 | 299 | ||
240 | /* codec slave */ | 300 | /* codec slave */ |
241 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), | 301 | { |
242 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | 302 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, |
243 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, | 303 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
244 | SND_SOC_FS_ALL, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, | 304 | .pcmdir = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, |
305 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
306 | .flags = SND_SOC_DAI_BFS_RATE, | ||
307 | .fs = SND_SOC_FS_ALL, | ||
308 | .bfs = 32, | ||
309 | }, | ||
310 | { | ||
311 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, | ||
312 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | ||
313 | .pcmdir = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, | ||
314 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
315 | .flags = SND_SOC_DAI_BFS_RATE, | ||
316 | .fs = SND_SOC_FS_ALL, | ||
317 | .bfs = 64, | ||
318 | }, | ||
245 | 319 | ||
246 | 320 | ||
247 | Example 4 | 321 | Example 5 |
248 | --------- | 322 | --------- |
249 | Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master | 323 | Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master |
250 | mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave | 324 | mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave |
@@ -259,29 +333,48 @@ mode as and does not care about FS or BCLK (as long as there is enough bandwidth | |||
259 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) | 333 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) |
260 | 334 | ||
261 | /* codec master @ 128, 192 & 256 FS */ | 335 | /* codec master @ 128, 192 & 256 FS */ |
262 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 336 | { |
263 | SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, | 337 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
264 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 338 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
265 | 128, CODEC_FSB}, | 339 | .pcmrate = CODEC_RATES, |
266 | 340 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | |
267 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 341 | .flags = SND_SOC_DAI_BFS_DIV, |
268 | SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, | 342 | .fs = 128, |
269 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 343 | .bfs = CODEC_FSB, |
270 | 192, CODEC_FSB}, | 344 | }, |
271 | 345 | ||
272 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 346 | { |
273 | SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, | 347 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
274 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 348 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
275 | 256, CODEC_FSB}, | 349 | .pcmrate = CODEC_RATES, |
350 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
351 | .flags = SND_SOC_DAI_BFS_DIV, | ||
352 | .fs = 192, | ||
353 | .bfs = CODEC_FSB | ||
354 | }, | ||
355 | |||
356 | { | ||
357 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | ||
358 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | ||
359 | .pcmrate = CODEC_RATES, | ||
360 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
361 | .flags = SND_SOC_DAI_BFS_DIV, | ||
362 | .fs = 256, | ||
363 | .bfs = CODEC_FSB, | ||
364 | }, | ||
276 | 365 | ||
277 | /* codec slave */ | 366 | /* codec slave */ |
278 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), | 367 | { |
279 | SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, | 368 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, |
280 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, | 369 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
281 | SND_SOC_FS_ALL, SND_SOC_FSB_ALL}, | 370 | .pcmrate = CODEC_RATES, |
371 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
372 | .fs = SND_SOC_FS_ALL, | ||
373 | .bfs = SND_SOC_FSB_ALL, | ||
374 | }, | ||
282 | 375 | ||
283 | 376 | ||
284 | Example 5 | 377 | Example 6 |
285 | --------- | 378 | --------- |
286 | Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use | 379 | Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use |
287 | with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). | 380 | with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). |
@@ -298,45 +391,66 @@ sizes. | |||
298 | SNDRV_PCM_FORMAT_S24_3LE | SNDRV_PCM_FORMAT_S24_LE | SNDRV_PCM_FORMAT_S32_LE) | 391 | SNDRV_PCM_FORMAT_S24_3LE | SNDRV_PCM_FORMAT_S24_LE | SNDRV_PCM_FORMAT_S32_LE) |
299 | 392 | ||
300 | /* codec master */ | 393 | /* codec master */ |
301 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 394 | { |
302 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000, | 395 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
303 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 396 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
304 | 1536, CODEC_FSB}, | 397 | .pcmrate = SNDRV_PCM_RATE_8000, |
305 | 398 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | |
306 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 399 | .flags = SND_SOC_DAI_BFS_DIV, |
307 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_44100, | 400 | .fs = 1536, |
308 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 401 | .bfs = CODEC_FSB, |
309 | 272, CODEC_FSB}, | 402 | }, |
310 | 403 | ||
311 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), | 404 | { |
312 | SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_48000, | 405 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, |
313 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, | 406 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
314 | 256, CODEC_FSB}, | 407 | .pcmrate = SNDRV_PCM_RATE_44100, |
408 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
409 | .flags = SND_SOC_DAI_BFS_DIV, | ||
410 | .fs = 272, | ||
411 | .bfs = CODEC_FSB, | ||
412 | }, | ||
413 | |||
414 | { | ||
415 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | ||
416 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | ||
417 | .pcmrate = SNDRV_PCM_RATE_48000, | ||
418 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
419 | .flags = SND_SOC_DAI_BFS_DIV, | ||
420 | .fs = 256, | ||
421 | .bfs = CODEC_FSB, | ||
422 | }, | ||
315 | 423 | ||
316 | /* codec slave */ | 424 | /* codec slave */ |
317 | {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), | 425 | { |
318 | SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, | 426 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, |
319 | SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, | 427 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, |
320 | SND_SOC_FS_ALL, SND_SOC_FSB_ALL}, | 428 | .pcmrate = CODEC_RATES, |
429 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | ||
430 | .fs = SND_SOC_FS_ALL, | ||
431 | .bfs = SND_SOC_FSB_ALL, | ||
432 | }, | ||
321 | 433 | ||
322 | 434 | ||
323 | Example 6 | 435 | Example 7 |
324 | --------- | 436 | --------- |
325 | AC97 Codec that does not support VRA (i.e only runs at 48k). | 437 | AC97 Codec that does not support VRA (i.e only runs at 48k). |
326 | 438 | ||
327 | #define AC97_DIR \ | 439 | #define AC97_DIR \ |
328 | (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) | 440 | (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) |
329 | 441 | ||
330 | |||
331 | #define AC97_PCM_FORMATS \ | 442 | #define AC97_PCM_FORMATS \ |
332 | (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S18_3LE | \ | 443 | (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S18_3LE | \ |
333 | SNDRV_PCM_FORMAT_S20_3LE) | 444 | SNDRV_PCM_FORMAT_S20_3LE) |
334 | 445 | ||
335 | /* AC97 with no VRA */ | 446 | /* AC97 with no VRA */ |
336 | {0, 0, AC97_PCM_FORMATS, SNDRV_PCM_RATE_48000}, | 447 | { |
448 | .pcmfmt = AC97_PCM_FORMATS, | ||
449 | .pcmrate = SNDRV_PCM_RATE_48000, | ||
450 | } | ||
337 | 451 | ||
338 | 452 | ||
339 | Example 7 | 453 | Example 8 |
340 | --------- | 454 | --------- |
341 | 455 | ||
342 | CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. | 456 | CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. |
@@ -354,27 +468,79 @@ BCLK = 64 * rate. (Intel XScale I2S controller). | |||
354 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | 468 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
355 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | 469 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) |
356 | 470 | ||
471 | /* priv is divider */ | ||
472 | static struct snd_soc_dai_mode pxa2xx_i2s_modes[] = { | ||
357 | /* pxa2xx I2S frame and clock master modes */ | 473 | /* pxa2xx I2S frame and clock master modes */ |
358 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 474 | { |
359 | SNDRV_PCM_RATE_8000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, | 475 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, |
360 | SND_SOC_FSBD(4), 0x48}, | 476 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, |
361 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 477 | .pcmrate = SNDRV_PCM_RATE_8000, |
362 | SNDRV_PCM_RATE_11025, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, | 478 | .pcmdir = PXA_I2S_DIR, |
363 | SND_SOC_FSBD(4), 0x34}, | 479 | .flags = SND_SOC_DAI_BFS_DIV, |
364 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 480 | .fs = 256, |
365 | SNDRV_PCM_RATE_16000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, | 481 | .bfs = SND_SOC_FSBD(4), |
366 | SND_SOC_FSBD(4), 0x24}, | 482 | .priv = 0x48, |
367 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 483 | }, |
368 | SNDRV_PCM_RATE_22050, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, | 484 | { |
369 | SND_SOC_FSBD(4), 0x1a}, | 485 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, |
370 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 486 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, |
371 | SNDRV_PCM_RATE_44100, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, | 487 | .pcmrate = SNDRV_PCM_RATE_11025, |
372 | SND_SOC_FSBD(4), 0xd}, | 488 | .pcmdir = PXA_I2S_DIR, |
373 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 489 | .flags = SND_SOC_DAI_BFS_DIV, |
374 | SNDRV_PCM_RATE_48000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, | 490 | .fs = 256, |
375 | SND_SOC_FSBD(4), 0xc}, | 491 | .bfs = SND_SOC_FSBD(4), |
492 | .priv = 0x34, | ||
493 | }, | ||
494 | { | ||
495 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, | ||
496 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | ||
497 | .pcmrate = SNDRV_PCM_RATE_16000, | ||
498 | .pcmdir = PXA_I2S_DIR, | ||
499 | .flags = SND_SOC_DAI_BFS_DIV, | ||
500 | .fs = 256, | ||
501 | .bfs = SND_SOC_FSBD(4), | ||
502 | .priv = 0x24, | ||
503 | }, | ||
504 | { | ||
505 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, | ||
506 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | ||
507 | .pcmrate = SNDRV_PCM_RATE_22050, | ||
508 | .pcmdir = PXA_I2S_DIR, | ||
509 | .flags = SND_SOC_DAI_BFS_DIV, | ||
510 | .fs = 256, | ||
511 | .bfs = SND_SOC_FSBD(4), | ||
512 | .priv = 0x1a, | ||
513 | }, | ||
514 | { | ||
515 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, | ||
516 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | ||
517 | .pcmrate = SNDRV_PCM_RATE_44100, | ||
518 | .pcmdir = PXA_I2S_DIR, | ||
519 | .flags = SND_SOC_DAI_BFS_DIV, | ||
520 | .fs = 256, | ||
521 | .bfs = SND_SOC_FSBD(4), | ||
522 | .priv = 0xd, | ||
523 | }, | ||
524 | { | ||
525 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, | ||
526 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | ||
527 | .pcmrate = SNDRV_PCM_RATE_48000, | ||
528 | .pcmdir = PXA_I2S_DIR, | ||
529 | .flags = SND_SOC_DAI_BFS_DIV, | ||
530 | .fs = 256, | ||
531 | .bfs = SND_SOC_FSBD(4), | ||
532 | .priv = 0xc, | ||
533 | }, | ||
376 | 534 | ||
377 | /* pxa2xx I2S frame master and clock slave mode */ | 535 | /* pxa2xx I2S frame master and clock slave mode */ |
378 | {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, | 536 | { |
379 | PXA_I2S_RATES, PXA_I2S_DIR, 0, SND_SOC_FS_ALL, SND_SOC_FSB(64)}, | 537 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, |
380 | 538 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | |
539 | .pcmrate = PXA_I2S_RATES, | ||
540 | .pcmdir = PXA_I2S_DIR, | ||
541 | .fs = SND_SOC_FS_ALL, | ||
542 | .flags = SND_SOC_DAI_BFS_RATE, | ||
543 | .bfs = 64, | ||
544 | .priv = 0x48, | ||
545 | }, | ||
546 | }; | ||
diff --git a/Documentation/sound/alsa/soc/clocking.txt b/Documentation/sound/alsa/soc/clocking.txt index 88a16c9e1979..1f55fd8cb117 100644 --- a/Documentation/sound/alsa/soc/clocking.txt +++ b/Documentation/sound/alsa/soc/clocking.txt | |||
@@ -26,9 +26,9 @@ between the codec and CPU. | |||
26 | 26 | ||
27 | The DAI also has a frame clock to signal the start of each audio frame. This | 27 | The DAI also has a frame clock to signal the start of each audio frame. This |
28 | clock is sometimes referred to as LRC (left right clock) or FRAME. This clock | 28 | clock is sometimes referred to as LRC (left right clock) or FRAME. This clock |
29 | runs at exactly the sample rate. | 29 | runs at exactly the sample rate (LRC = Rate). |
30 | 30 | ||
31 | Bit Clock is usually always a ratio of MCLK or a multiple of LRC. i.e. | 31 | Bit Clock can be generated as follows:- |
32 | 32 | ||
33 | BCLK = MCLK / x | 33 | BCLK = MCLK / x |
34 | 34 | ||
@@ -36,9 +36,14 @@ BCLK = MCLK / x | |||
36 | 36 | ||
37 | BCLK = LRC * x | 37 | BCLK = LRC * x |
38 | 38 | ||
39 | or | ||
40 | |||
41 | BCLK = LRC * Channels * Word Size | ||
42 | |||
39 | This relationship depends on the codec or SoC CPU in particular. ASoC can quite | 43 | This relationship depends on the codec or SoC CPU in particular. ASoC can quite |
40 | easily match a codec that generates BCLK by division (FSBD) with a CPU that | 44 | easily match BCLK generated by division (SND_SOC_DAI_BFS_DIV) with BCLK by |
41 | generates BCLK by multiplication (FSB). | 45 | multiplication (SND_SOC_DAI_BFS_RATE) or BCLK generated by |
46 | Rate * Channels * Word size (RCW or SND_SOC_DAI_BFS_RCW). | ||
42 | 47 | ||
43 | 48 | ||
44 | ASoC Clocking | 49 | ASoC Clocking |
diff --git a/include/sound/soc.h b/include/sound/soc.h index ecdd1fac94b6..3dfe052e0788 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <sound/control.h> | 21 | #include <sound/control.h> |
22 | #include <sound/ac97_codec.h> | 22 | #include <sound/ac97_codec.h> |
23 | 23 | ||
24 | #define SND_SOC_VERSION "0.11.8" | 24 | #define SND_SOC_VERSION "0.12" |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Convenience kcontrol builders | 27 | * Convenience kcontrol builders |
@@ -141,19 +141,24 @@ | |||
141 | /* bit clock dividers */ | 141 | /* bit clock dividers */ |
142 | #define SND_SOC_FSBD(x) (1 << (x - 1)) /* ratio mclk:bclk */ | 142 | #define SND_SOC_FSBD(x) (1 << (x - 1)) /* ratio mclk:bclk */ |
143 | #define SND_SOC_FSBD_REAL(x) (ffs(x)) | 143 | #define SND_SOC_FSBD_REAL(x) (ffs(x)) |
144 | #define SND_SOC_FSBD_ALL 0xffff /* all bit clock dividers supported */ | ||
145 | 144 | ||
146 | /* bit clock ratio to sample rate */ | 145 | /* bit clock ratio to (sample rate * channels * word size) */ |
147 | #define SND_SOC_FSB(x) (1 << ((x - 16) / 16)) | 146 | #define SND_SOC_FSBW(x) (1 << (x - 1)) |
148 | #define SND_SOC_FSB_REAL(x) (((ffs(x) - 1) * 16) + 16) | 147 | #define SND_SOC_FSBW_REAL(x) (ffs(x)) |
149 | /* all bclk ratios supported */ | 148 | /* all bclk ratios supported */ |
150 | #define SND_SOC_FSB_ALL SND_SOC_FSBD_ALL | 149 | #define SND_SOC_FSB_ALL ~0ULL |
151 | 150 | ||
152 | /* | 151 | /* |
153 | * DAI hardware flags | 152 | * DAI hardware flags |
154 | */ | 153 | */ |
155 | /* use bfs mclk divider mode, else sample rate ratio */ | 154 | /* use bfs mclk divider mode (BCLK = MCLK / x) */ |
156 | #define SND_SOC_DAI_BFS_DIV 0x1 | 155 | #define SND_SOC_DAI_BFS_DIV 0x1 |
156 | /* use bfs rate mulitplier (BCLK = RATE * x)*/ | ||
157 | #define SND_SOC_DAI_BFS_RATE 0x2 | ||
158 | /* use bfs rcw multiplier (BCLK = RATE * CHN * WORD SIZE) */ | ||
159 | #define SND_SOC_DAI_BFS_RCW 0x4 | ||
160 | /* capture and playback can use different clocks */ | ||
161 | #define SND_SOC_DAI_ASYNC 0x8 | ||
157 | 162 | ||
158 | /* | 163 | /* |
159 | * AC97 codec ID's bitmask | 164 | * AC97 codec ID's bitmask |
@@ -264,7 +269,7 @@ struct snd_soc_dai_mode { | |||
264 | u16 pcmdir:2; /* SND_SOC_HWDIR_* */ | 269 | u16 pcmdir:2; /* SND_SOC_HWDIR_* */ |
265 | u16 flags:8; /* hw flags */ | 270 | u16 flags:8; /* hw flags */ |
266 | u16 fs; /* mclk to rate divider */ | 271 | u16 fs; /* mclk to rate divider */ |
267 | u32 bfs; /* mclk to bclk dividers */ | 272 | u64 bfs; /* mclk to bclk dividers */ |
268 | unsigned long priv; /* private mode data */ | 273 | unsigned long priv; /* private mode data */ |
269 | }; | 274 | }; |
270 | 275 | ||
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 9adbd2d401c4..412291241ece 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -90,32 +90,36 @@ static struct snd_soc_dai_mode wm8731_modes[] = { | |||
90 | .pcmfmt = WM8731_HIFI_BITS, | 90 | .pcmfmt = WM8731_HIFI_BITS, |
91 | .pcmrate = SNDRV_PCM_RATE_8000, | 91 | .pcmrate = SNDRV_PCM_RATE_8000, |
92 | .pcmdir = WM8731_DIR, | 92 | .pcmdir = WM8731_DIR, |
93 | .flags = SND_SOC_DAI_BFS_RATE, | ||
93 | .fs = 1536, | 94 | .fs = 1536, |
94 | .bfs = SND_SOC_FSB(64), | 95 | .bfs = 64, |
95 | }, | 96 | }, |
96 | { | 97 | { |
97 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, | 98 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, |
98 | .pcmfmt = WM8731_HIFI_BITS, | 99 | .pcmfmt = WM8731_HIFI_BITS, |
99 | .pcmrate = SNDRV_PCM_RATE_8000, | 100 | .pcmrate = SNDRV_PCM_RATE_8000, |
100 | .pcmdir = WM8731_DIR, | 101 | .pcmdir = WM8731_DIR, |
102 | .flags = SND_SOC_DAI_BFS_RATE, | ||
101 | .fs = 2304, | 103 | .fs = 2304, |
102 | .bfs = SND_SOC_FSB(64), | 104 | .bfs = 64, |
103 | }, | 105 | }, |
104 | { | 106 | { |
105 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, | 107 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, |
106 | .pcmfmt = WM8731_HIFI_BITS, | 108 | .pcmfmt = WM8731_HIFI_BITS, |
107 | .pcmrate = SNDRV_PCM_RATE_8000, | 109 | .pcmrate = SNDRV_PCM_RATE_8000, |
108 | .pcmdir = WM8731_DIR, | 110 | .pcmdir = WM8731_DIR, |
111 | .flags = SND_SOC_DAI_BFS_RATE, | ||
109 | .fs = 1408, | 112 | .fs = 1408, |
110 | .bfs = SND_SOC_FSB(64), | 113 | .bfs = 64, |
111 | }, | 114 | }, |
112 | { | 115 | { |
113 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, | 116 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, |
114 | .pcmfmt = WM8731_HIFI_BITS, | 117 | .pcmfmt = WM8731_HIFI_BITS, |
115 | .pcmrate = SNDRV_PCM_RATE_8000, | 118 | .pcmrate = SNDRV_PCM_RATE_8000, |
116 | .pcmdir = WM8731_DIR, | 119 | .pcmdir = WM8731_DIR, |
120 | .flags = SND_SOC_DAI_BFS_RATE, | ||
117 | .fs = 2112, | 121 | .fs = 2112, |
118 | .bfs = SND_SOC_FSB(64), | 122 | .bfs = 64, |
119 | }, | 123 | }, |
120 | 124 | ||
121 | /* 32k */ | 125 | /* 32k */ |
@@ -124,16 +128,18 @@ static struct snd_soc_dai_mode wm8731_modes[] = { | |||
124 | .pcmfmt = WM8731_HIFI_BITS, | 128 | .pcmfmt = WM8731_HIFI_BITS, |
125 | .pcmrate = SNDRV_PCM_RATE_32000, | 129 | .pcmrate = SNDRV_PCM_RATE_32000, |
126 | .pcmdir = WM8731_DIR, | 130 | .pcmdir = WM8731_DIR, |
131 | .flags = SND_SOC_DAI_BFS_RATE, | ||
127 | .fs = 384, | 132 | .fs = 384, |
128 | .bfs = SND_SOC_FSB(64), | 133 | .bfs = 64, |
129 | }, | 134 | }, |
130 | { | 135 | { |
131 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, | 136 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, |
132 | .pcmfmt = WM8731_HIFI_BITS, | 137 | .pcmfmt = WM8731_HIFI_BITS, |
133 | .pcmrate = SNDRV_PCM_RATE_32000, | 138 | .pcmrate = SNDRV_PCM_RATE_32000, |
134 | .pcmdir = WM8731_DIR, | 139 | .pcmdir = WM8731_DIR, |
140 | .flags = SND_SOC_DAI_BFS_RATE, | ||
135 | .fs = 576, | 141 | .fs = 576, |
136 | .bfs = SND_SOC_FSB(64), | 142 | .bfs = 64, |
137 | }, | 143 | }, |
138 | 144 | ||
139 | /* 44.1k & 48k */ | 145 | /* 44.1k & 48k */ |
@@ -142,16 +148,18 @@ static struct snd_soc_dai_mode wm8731_modes[] = { | |||
142 | .pcmfmt = WM8731_HIFI_BITS, | 148 | .pcmfmt = WM8731_HIFI_BITS, |
143 | .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | 149 | .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, |
144 | .pcmdir = WM8731_DIR, | 150 | .pcmdir = WM8731_DIR, |
151 | .flags = SND_SOC_DAI_BFS_RATE, | ||
145 | .fs = 256, | 152 | .fs = 256, |
146 | .bfs = SND_SOC_FSB(64), | 153 | .bfs = 64, |
147 | }, | 154 | }, |
148 | { | 155 | { |
149 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, | 156 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, |
150 | .pcmfmt = WM8731_HIFI_BITS, | 157 | .pcmfmt = WM8731_HIFI_BITS, |
151 | .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | 158 | .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, |
152 | .pcmdir = WM8731_DIR, | 159 | .pcmdir = WM8731_DIR, |
160 | .flags = SND_SOC_DAI_BFS_RATE, | ||
153 | .fs = 384, | 161 | .fs = 384, |
154 | .bfs = SND_SOC_FSB(64), | 162 | .bfs = 64, |
155 | }, | 163 | }, |
156 | 164 | ||
157 | /* 88.2 & 96k */ | 165 | /* 88.2 & 96k */ |
@@ -160,17 +168,18 @@ static struct snd_soc_dai_mode wm8731_modes[] = { | |||
160 | .pcmfmt = WM8731_HIFI_BITS, | 168 | .pcmfmt = WM8731_HIFI_BITS, |
161 | .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, | 169 | .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, |
162 | .pcmdir = WM8731_DIR, | 170 | .pcmdir = WM8731_DIR, |
171 | .flags = SND_SOC_DAI_BFS_RATE, | ||
163 | .fs = 128, | 172 | .fs = 128, |
164 | .bfs = SND_SOC_FSB(64), | 173 | .bfs = 64, |
165 | |||
166 | }, | 174 | }, |
167 | { | 175 | { |
168 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, | 176 | .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, |
169 | .pcmfmt = WM8731_HIFI_BITS, | 177 | .pcmfmt = WM8731_HIFI_BITS, |
170 | .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, | 178 | .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, |
171 | .pcmdir = WM8731_DIR, | 179 | .pcmdir = WM8731_DIR, |
180 | .flags = SND_SOC_DAI_BFS_RATE, | ||
172 | .fs = 192, | 181 | .fs = 192, |
173 | .bfs = SND_SOC_FSB(64), | 182 | .bfs = 64, |
174 | }, | 183 | }, |
175 | 184 | ||
176 | /* USB codec frame and clock master modes */ | 185 | /* USB codec frame and clock master modes */ |
@@ -237,7 +246,7 @@ static struct snd_soc_dai_mode wm8731_modes[] = { | |||
237 | .pcmdir = WM8731_DIR, | 246 | .pcmdir = WM8731_DIR, |
238 | .flags = SND_SOC_DAI_BFS_DIV, | 247 | .flags = SND_SOC_DAI_BFS_DIV, |
239 | .fs = SND_SOC_FS_ALL, | 248 | .fs = SND_SOC_FS_ALL, |
240 | .bfs = SND_SOC_FSBD_ALL, | 249 | .bfs = SND_SOC_FSB_ALL, |
241 | }, | 250 | }, |
242 | }; | 251 | }; |
243 | 252 | ||
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 243da712d9c1..c5d13a9454d9 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -343,7 +343,7 @@ static struct snd_soc_dai_mode wm8750_modes[] = { | |||
343 | .pcmdir = WM8750_DIR, | 343 | .pcmdir = WM8750_DIR, |
344 | .flags = SND_SOC_DAI_BFS_DIV, | 344 | .flags = SND_SOC_DAI_BFS_DIV, |
345 | .fs = SND_SOC_FS_ALL, | 345 | .fs = SND_SOC_FS_ALL, |
346 | .bfs = SND_SOC_FSBD_ALL, | 346 | .bfs = SND_SOC_FSB_ALL, |
347 | }, | 347 | }, |
348 | }; | 348 | }; |
349 | 349 | ||
@@ -829,6 +829,9 @@ static inline int get_coeff(int mclk, int rate) | |||
829 | if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) | 829 | if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) |
830 | return i; | 830 | return i; |
831 | } | 831 | } |
832 | |||
833 | printk(KERN_ERR "wm8750: could not get coeff for mclk %d @ rate %d\n", | ||
834 | mclk, rate); | ||
832 | return -EINVAL; | 835 | return -EINVAL; |
833 | } | 836 | } |
834 | 837 | ||
@@ -836,13 +839,7 @@ static inline int get_coeff(int mclk, int rate) | |||
836 | static unsigned int wm8750_config_sysclk(struct snd_soc_codec_dai *dai, | 839 | static unsigned int wm8750_config_sysclk(struct snd_soc_codec_dai *dai, |
837 | struct snd_soc_clock_info *info, unsigned int clk) | 840 | struct snd_soc_clock_info *info, unsigned int clk) |
838 | { | 841 | { |
839 | dai->mclk = 0; | 842 | dai->mclk = clk; |
840 | |||
841 | /* check that the calculated FS and rate actually match a clock from | ||
842 | * the machine driver */ | ||
843 | if (info->fs * info->rate == clk) | ||
844 | dai->mclk = clk; | ||
845 | |||
846 | return dai->mclk; | 843 | return dai->mclk; |
847 | } | 844 | } |
848 | 845 | ||
@@ -859,7 +856,7 @@ static int wm8750_pcm_prepare(struct snd_pcm_substream *substream) | |||
859 | if (i < 0) | 856 | if (i < 0) |
860 | return i; | 857 | return i; |
861 | 858 | ||
862 | bfs = SND_SOC_FSB_REAL(rtd->codec_dai->dai_runtime.bfs); | 859 | bfs = SND_SOC_FSBD_REAL(rtd->codec_dai->dai_runtime.bfs); |
863 | 860 | ||
864 | /* set master/slave audio interface */ | 861 | /* set master/slave audio interface */ |
865 | switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK) { | 862 | switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK) { |
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 99f1da32744b..98b167fe68e5 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c | |||
@@ -126,7 +126,8 @@ static struct snd_soc_dai_mode pxa2xx_i2s_modes[] = { | |||
126 | .pcmrate = PXA_I2S_RATES, | 126 | .pcmrate = PXA_I2S_RATES, |
127 | .pcmdir = PXA_I2S_DIR, | 127 | .pcmdir = PXA_I2S_DIR, |
128 | .fs = SND_SOC_FS_ALL, | 128 | .fs = SND_SOC_FS_ALL, |
129 | .bfs = SND_SOC_FSB(64), | 129 | .flags = SND_SOC_DAI_BFS_RATE, |
130 | .bfs = 64, | ||
130 | .priv = 0x48, | 131 | .priv = 0x48, |
131 | }, | 132 | }, |
132 | }; | 133 | }; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2ce0c8251dc3..6da1616bf776 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -51,6 +51,8 @@ | |||
51 | #define dbgc(format, arg...) | 51 | #define dbgc(format, arg...) |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #define CODEC_CPU(codec, cpu) ((codec << 4) | cpu) | ||
55 | |||
54 | static DEFINE_MUTEX(pcm_mutex); | 56 | static DEFINE_MUTEX(pcm_mutex); |
55 | static DEFINE_MUTEX(io_mutex); | 57 | static DEFINE_MUTEX(io_mutex); |
56 | static struct workqueue_struct *soc_workq; | 58 | static struct workqueue_struct *soc_workq; |
@@ -150,11 +152,11 @@ static unsigned inline int soc_get_mclk(struct snd_soc_pcm_runtime *rtd, | |||
150 | } | 152 | } |
151 | 153 | ||
152 | /* changes a bitclk multiplier mask to a divider mask */ | 154 | /* changes a bitclk multiplier mask to a divider mask */ |
153 | static u16 soc_bfs_mult_to_div(u16 bfs, int rate, unsigned int mclk, | 155 | static u64 soc_bfs_rcw_to_div(u64 bfs, int rate, unsigned int mclk, |
154 | unsigned int pcmfmt, unsigned int chn) | 156 | unsigned int pcmfmt, unsigned int chn) |
155 | { | 157 | { |
156 | int i, j; | 158 | int i, j; |
157 | u16 bfs_ = 0; | 159 | u64 bfs_ = 0; |
158 | int size = snd_pcm_format_physical_width(pcmfmt), min = 0; | 160 | int size = snd_pcm_format_physical_width(pcmfmt), min = 0; |
159 | 161 | ||
160 | if (size <= 0) | 162 | if (size <= 0) |
@@ -162,17 +164,14 @@ static u16 soc_bfs_mult_to_div(u16 bfs, int rate, unsigned int mclk, | |||
162 | 164 | ||
163 | /* the minimum bit clock that has enough bandwidth */ | 165 | /* the minimum bit clock that has enough bandwidth */ |
164 | min = size * rate * chn; | 166 | min = size * rate * chn; |
165 | dbgc("mult --> div min bclk %d with mclk %d\n", min, mclk); | 167 | dbgc("rcw --> div min bclk %d with mclk %d\n", min, mclk); |
166 | 168 | ||
167 | for (i = 0; i < 16; i++) { | 169 | for (i = 0; i < 64; i++) { |
168 | if ((bfs >> i) & 0x1) { | 170 | if ((bfs >> i) & 0x1) { |
169 | j = rate * SND_SOC_FSB_REAL(1<<i); | 171 | j = min * (i + 1); |
170 | 172 | bfs_ |= SND_SOC_FSBD(mclk/j); | |
171 | if (j >= min) { | 173 | dbgc("rcw --> div support mult %d\n", |
172 | bfs_ |= SND_SOC_FSBD(mclk/j); | 174 | SND_SOC_FSBD_REAL(1<<i)); |
173 | dbgc("mult --> div support mult %d\n", | ||
174 | SND_SOC_FSB_REAL(1<<i)); | ||
175 | } | ||
176 | } | 175 | } |
177 | } | 176 | } |
178 | 177 | ||
@@ -180,11 +179,11 @@ static u16 soc_bfs_mult_to_div(u16 bfs, int rate, unsigned int mclk, | |||
180 | } | 179 | } |
181 | 180 | ||
182 | /* changes a bitclk divider mask to a multiplier mask */ | 181 | /* changes a bitclk divider mask to a multiplier mask */ |
183 | static u16 soc_bfs_div_to_mult(u16 bfs, int rate, unsigned int mclk, | 182 | static u64 soc_bfs_div_to_rcw(u64 bfs, int rate, unsigned int mclk, |
184 | unsigned int pcmfmt, unsigned int chn) | 183 | unsigned int pcmfmt, unsigned int chn) |
185 | { | 184 | { |
186 | int i, j; | 185 | int i, j; |
187 | u16 bfs_ = 0; | 186 | u64 bfs_ = 0; |
188 | 187 | ||
189 | int size = snd_pcm_format_physical_width(pcmfmt), min = 0; | 188 | int size = snd_pcm_format_physical_width(pcmfmt), min = 0; |
190 | 189 | ||
@@ -193,15 +192,15 @@ static u16 soc_bfs_div_to_mult(u16 bfs, int rate, unsigned int mclk, | |||
193 | 192 | ||
194 | /* the minimum bit clock that has enough bandwidth */ | 193 | /* the minimum bit clock that has enough bandwidth */ |
195 | min = size * rate * chn; | 194 | min = size * rate * chn; |
196 | dbgc("div to mult min bclk %d with mclk %d\n", min, mclk); | 195 | dbgc("div to rcw min bclk %d with mclk %d\n", min, mclk); |
197 | 196 | ||
198 | for (i = 0; i < 16; i++) { | 197 | for (i = 0; i < 64; i++) { |
199 | if ((bfs >> i) & 0x1) { | 198 | if ((bfs >> i) & 0x1) { |
200 | j = mclk / (SND_SOC_FSBD_REAL(1<<i)); | 199 | j = mclk / (i + 1); |
201 | if (j >= min) { | 200 | if (j >= min) { |
202 | bfs_ |= SND_SOC_FSB(j/rate); | 201 | bfs_ |= SND_SOC_FSBW(j/min); |
203 | dbgc("div --> mult support div %d\n", | 202 | dbgc("div --> rcw support div %d\n", |
204 | SND_SOC_FSBD_REAL(1<<i)); | 203 | SND_SOC_FSBW_REAL(1<<i)); |
205 | } | 204 | } |
206 | } | 205 | } |
207 | } | 206 | } |
@@ -209,6 +208,52 @@ static u16 soc_bfs_div_to_mult(u16 bfs, int rate, unsigned int mclk, | |||
209 | return bfs_; | 208 | return bfs_; |
210 | } | 209 | } |
211 | 210 | ||
211 | /* changes a constant bitclk to a multiplier mask */ | ||
212 | static u64 soc_bfs_rate_to_rcw(u64 bfs, int rate, unsigned int mclk, | ||
213 | unsigned int pcmfmt, unsigned int chn) | ||
214 | { | ||
215 | unsigned int bfs_ = rate * bfs; | ||
216 | int size = snd_pcm_format_physical_width(pcmfmt), min = 0; | ||
217 | |||
218 | if (size <= 0) | ||
219 | return 0; | ||
220 | |||
221 | /* the minimum bit clock that has enough bandwidth */ | ||
222 | min = size * rate * chn; | ||
223 | dbgc("rate --> rcw min bclk %d with mclk %d\n", min, mclk); | ||
224 | |||
225 | if (bfs_ < min) | ||
226 | return 0; | ||
227 | else { | ||
228 | bfs_ = SND_SOC_FSBW(bfs_/min); | ||
229 | dbgc("rate --> rcw support div %d\n", SND_SOC_FSBW_REAL(bfs_)); | ||
230 | return bfs_; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /* changes a bitclk multiplier mask to a divider mask */ | ||
235 | static u64 soc_bfs_rate_to_div(u64 bfs, int rate, unsigned int mclk, | ||
236 | unsigned int pcmfmt, unsigned int chn) | ||
237 | { | ||
238 | unsigned int bfs_ = rate * bfs; | ||
239 | int size = snd_pcm_format_physical_width(pcmfmt), min = 0; | ||
240 | |||
241 | if (size <= 0) | ||
242 | return 0; | ||
243 | |||
244 | /* the minimum bit clock that has enough bandwidth */ | ||
245 | min = size * rate * chn; | ||
246 | dbgc("rate --> div min bclk %d with mclk %d\n", min, mclk); | ||
247 | |||
248 | if (bfs_ < min) | ||
249 | return 0; | ||
250 | else { | ||
251 | bfs_ = SND_SOC_FSBW(mclk/bfs_); | ||
252 | dbgc("rate --> div support div %d\n", SND_SOC_FSBD_REAL(bfs_)); | ||
253 | return bfs_; | ||
254 | } | ||
255 | } | ||
256 | |||
212 | /* Matches codec DAI and SoC CPU DAI hardware parameters */ | 257 | /* Matches codec DAI and SoC CPU DAI hardware parameters */ |
213 | static int soc_hw_match_params(struct snd_pcm_substream *substream, | 258 | static int soc_hw_match_params(struct snd_pcm_substream *substream, |
214 | struct snd_pcm_hw_params *params) | 259 | struct snd_pcm_hw_params *params) |
@@ -217,9 +262,10 @@ static int soc_hw_match_params(struct snd_pcm_substream *substream, | |||
217 | struct snd_soc_dai_mode *codec_dai_mode = NULL; | 262 | struct snd_soc_dai_mode *codec_dai_mode = NULL; |
218 | struct snd_soc_dai_mode *cpu_dai_mode = NULL; | 263 | struct snd_soc_dai_mode *cpu_dai_mode = NULL; |
219 | struct snd_soc_clock_info clk_info; | 264 | struct snd_soc_clock_info clk_info; |
220 | unsigned int fs, mclk, codec_bfs, cpu_bfs, rate = params_rate(params), | 265 | unsigned int fs, mclk, rate = params_rate(params), |
221 | chn, j, k, cpu_bclk, codec_bclk, pcmrate; | 266 | chn, j, k, cpu_bclk, codec_bclk, pcmrate; |
222 | u16 fmt = 0; | 267 | u16 fmt = 0; |
268 | u64 codec_bfs, cpu_bfs; | ||
223 | 269 | ||
224 | dbg("asoc: match version %s\n", SND_SOC_VERSION); | 270 | dbg("asoc: match version %s\n", SND_SOC_VERSION); |
225 | clk_info.rate = rate; | 271 | clk_info.rate = rate; |
@@ -309,44 +355,98 @@ static int soc_hw_match_params(struct snd_pcm_substream *substream, | |||
309 | * used in the codec and cpu DAI modes. We always choose the | 355 | * used in the codec and cpu DAI modes. We always choose the |
310 | * lowest possible clocks to reduce power. | 356 | * lowest possible clocks to reduce power. |
311 | */ | 357 | */ |
312 | if (codec_dai_mode->flags & cpu_dai_mode->flags & | 358 | switch (CODEC_CPU(codec_dai_mode->flags, cpu_dai_mode->flags)) { |
313 | SND_SOC_DAI_BFS_DIV) { | 359 | case CODEC_CPU(SND_SOC_DAI_BFS_DIV, SND_SOC_DAI_BFS_DIV): |
314 | /* cpu & codec bfs dividers */ | 360 | /* cpu & codec bfs dividers */ |
315 | rtd->cpu_dai->dai_runtime.bfs = | 361 | rtd->cpu_dai->dai_runtime.bfs = |
316 | rtd->codec_dai->dai_runtime.bfs = | 362 | rtd->codec_dai->dai_runtime.bfs = |
317 | 1 << (fls(codec_dai_mode->bfs & cpu_dai_mode->bfs) - 1); | 363 | 1 << (fls(codec_dai_mode->bfs & cpu_dai_mode->bfs) - 1); |
318 | } else if (codec_dai_mode->flags & SND_SOC_DAI_BFS_DIV) { | 364 | break; |
319 | /* normalise bfs codec divider & cpu mult */ | 365 | case CODEC_CPU(SND_SOC_DAI_BFS_DIV, SND_SOC_DAI_BFS_RCW): |
320 | codec_bfs = soc_bfs_div_to_mult(codec_dai_mode->bfs, rate, | 366 | /* normalise bfs codec divider & cpu rcw mult */ |
367 | codec_bfs = soc_bfs_div_to_rcw(codec_dai_mode->bfs, rate, | ||
321 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); | 368 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); |
322 | rtd->cpu_dai->dai_runtime.bfs = | 369 | rtd->cpu_dai->dai_runtime.bfs = |
323 | 1 << (ffs(codec_bfs & cpu_dai_mode->bfs) - 1); | 370 | 1 << (ffs(codec_bfs & cpu_dai_mode->bfs) - 1); |
324 | cpu_bfs = soc_bfs_mult_to_div(cpu_dai_mode->bfs, rate, mclk, | 371 | cpu_bfs = soc_bfs_rcw_to_div(cpu_dai_mode->bfs, rate, mclk, |
325 | rtd->codec_dai->dai_runtime.pcmfmt, chn); | 372 | rtd->codec_dai->dai_runtime.pcmfmt, chn); |
326 | rtd->codec_dai->dai_runtime.bfs = | 373 | rtd->codec_dai->dai_runtime.bfs = |
327 | 1 << (fls(codec_dai_mode->bfs & cpu_bfs) - 1); | 374 | 1 << (fls(codec_dai_mode->bfs & cpu_bfs) - 1); |
328 | } else if (cpu_dai_mode->flags & SND_SOC_DAI_BFS_DIV) { | 375 | break; |
329 | /* normalise bfs codec mult & cpu divider */ | 376 | case CODEC_CPU(SND_SOC_DAI_BFS_RCW, SND_SOC_DAI_BFS_DIV): |
330 | codec_bfs = soc_bfs_mult_to_div(codec_dai_mode->bfs, rate, | 377 | /* normalise bfs codec rcw mult & cpu divider */ |
378 | codec_bfs = soc_bfs_rcw_to_div(codec_dai_mode->bfs, rate, | ||
331 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); | 379 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); |
332 | rtd->cpu_dai->dai_runtime.bfs = | 380 | rtd->cpu_dai->dai_runtime.bfs = |
333 | 1 << (fls(codec_bfs & cpu_dai_mode->bfs) -1); | 381 | 1 << (fls(codec_bfs & cpu_dai_mode->bfs) -1); |
334 | cpu_bfs = soc_bfs_div_to_mult(cpu_dai_mode->bfs, rate, mclk, | 382 | cpu_bfs = soc_bfs_div_to_rcw(cpu_dai_mode->bfs, rate, mclk, |
335 | rtd->codec_dai->dai_runtime.pcmfmt, chn); | 383 | rtd->codec_dai->dai_runtime.pcmfmt, chn); |
336 | rtd->codec_dai->dai_runtime.bfs = | 384 | rtd->codec_dai->dai_runtime.bfs = |
337 | 1 << (ffs(codec_dai_mode->bfs & cpu_bfs) -1); | 385 | 1 << (ffs(codec_dai_mode->bfs & cpu_bfs) -1); |
338 | } else { | 386 | break; |
339 | /* codec & cpu bfs rate multipliers */ | 387 | case CODEC_CPU(SND_SOC_DAI_BFS_RCW, SND_SOC_DAI_BFS_RCW): |
388 | /* codec & cpu bfs rate rcw multipliers */ | ||
340 | rtd->cpu_dai->dai_runtime.bfs = | 389 | rtd->cpu_dai->dai_runtime.bfs = |
341 | rtd->codec_dai->dai_runtime.bfs = | 390 | rtd->codec_dai->dai_runtime.bfs = |
342 | 1 << (ffs(codec_dai_mode->bfs & cpu_dai_mode->bfs) -1); | 391 | 1 << (ffs(codec_dai_mode->bfs & cpu_dai_mode->bfs) -1); |
392 | break; | ||
393 | case CODEC_CPU(SND_SOC_DAI_BFS_DIV, SND_SOC_DAI_BFS_RATE): | ||
394 | /* normalise cpu bfs rate const multiplier & codec div */ | ||
395 | cpu_bfs = soc_bfs_rate_to_div(cpu_dai_mode->bfs, rate, | ||
396 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); | ||
397 | if(codec_dai_mode->bfs & cpu_bfs) { | ||
398 | rtd->codec_dai->dai_runtime.bfs = cpu_bfs; | ||
399 | rtd->cpu_dai->dai_runtime.bfs = cpu_dai_mode->bfs; | ||
400 | } else | ||
401 | rtd->cpu_dai->dai_runtime.bfs = 0; | ||
402 | break; | ||
403 | case CODEC_CPU(SND_SOC_DAI_BFS_RCW, SND_SOC_DAI_BFS_RATE): | ||
404 | /* normalise cpu bfs rate const multiplier & codec rcw mult */ | ||
405 | cpu_bfs = soc_bfs_rate_to_rcw(cpu_dai_mode->bfs, rate, | ||
406 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); | ||
407 | if(codec_dai_mode->bfs & cpu_bfs) { | ||
408 | rtd->codec_dai->dai_runtime.bfs = cpu_bfs; | ||
409 | rtd->cpu_dai->dai_runtime.bfs = cpu_dai_mode->bfs; | ||
410 | } else | ||
411 | rtd->cpu_dai->dai_runtime.bfs = 0; | ||
412 | break; | ||
413 | case CODEC_CPU(SND_SOC_DAI_BFS_RATE, SND_SOC_DAI_BFS_RCW): | ||
414 | /* normalise cpu bfs rate rcw multiplier & codec const mult */ | ||
415 | codec_bfs = soc_bfs_rate_to_rcw(codec_dai_mode->bfs, rate, | ||
416 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); | ||
417 | if(cpu_dai_mode->bfs & codec_bfs) { | ||
418 | rtd->cpu_dai->dai_runtime.bfs = codec_bfs; | ||
419 | rtd->codec_dai->dai_runtime.bfs = codec_dai_mode->bfs; | ||
420 | } else | ||
421 | rtd->cpu_dai->dai_runtime.bfs = 0; | ||
422 | break; | ||
423 | case CODEC_CPU(SND_SOC_DAI_BFS_RATE, SND_SOC_DAI_BFS_DIV): | ||
424 | /* normalise cpu bfs div & codec const mult */ | ||
425 | codec_bfs = soc_bfs_rate_to_div(codec_dai_mode->bfs, rate, | ||
426 | mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn); | ||
427 | if(codec_dai_mode->bfs & codec_bfs) { | ||
428 | rtd->cpu_dai->dai_runtime.bfs = codec_bfs; | ||
429 | rtd->codec_dai->dai_runtime.bfs = codec_dai_mode->bfs; | ||
430 | } else | ||
431 | rtd->cpu_dai->dai_runtime.bfs = 0; | ||
432 | break; | ||
433 | case CODEC_CPU(SND_SOC_DAI_BFS_RATE, SND_SOC_DAI_BFS_RATE): | ||
434 | /* cpu & codec constant mult */ | ||
435 | if(codec_dai_mode->bfs == cpu_dai_mode->bfs) | ||
436 | rtd->cpu_dai->dai_runtime.bfs = | ||
437 | rtd->codec_dai->dai_runtime.bfs = | ||
438 | codec_dai_mode->bfs; | ||
439 | else | ||
440 | rtd->cpu_dai->dai_runtime.bfs = | ||
441 | rtd->codec_dai->dai_runtime.bfs = 0; | ||
442 | break; | ||
343 | } | 443 | } |
344 | 444 | ||
345 | /* make sure the bit clock speed is acceptable */ | 445 | /* make sure the bit clock speed is acceptable */ |
346 | if (!rtd->cpu_dai->dai_runtime.bfs || | 446 | if (!rtd->cpu_dai->dai_runtime.bfs || |
347 | !rtd->codec_dai->dai_runtime.bfs) { | 447 | !rtd->codec_dai->dai_runtime.bfs) { |
348 | dbgc("asoc: DAI[%d:%d] failed to match BFS\n", j, k); | 448 | dbgc("asoc: DAI[%d:%d] failed to match BFS\n", j, k); |
349 | dbgc("asoc: cpu_dai %x codec %x\n", | 449 | dbgc("asoc: cpu_dai %llu codec %llu\n", |
350 | rtd->cpu_dai->dai_runtime.bfs, | 450 | rtd->cpu_dai->dai_runtime.bfs, |
351 | rtd->codec_dai->dai_runtime.bfs); | 451 | rtd->codec_dai->dai_runtime.bfs); |
352 | dbgc("asoc: mclk %d hwfmt %x\n", mclk, fmt); | 452 | dbgc("asoc: mclk %d hwfmt %x\n", mclk, fmt); |
@@ -378,26 +478,41 @@ found: | |||
378 | dbg("asoc: codec fs %d mclk %d bfs div %d bclk %d\n", | 478 | dbg("asoc: codec fs %d mclk %d bfs div %d bclk %d\n", |
379 | rtd->codec_dai->dai_runtime.fs, mclk, | 479 | rtd->codec_dai->dai_runtime.fs, mclk, |
380 | SND_SOC_FSBD_REAL(rtd->codec_dai->dai_runtime.bfs), codec_bclk); | 480 | SND_SOC_FSBD_REAL(rtd->codec_dai->dai_runtime.bfs), codec_bclk); |
381 | } else { | 481 | } else if(rtd->codec_dai->dai_runtime.flags == SND_SOC_DAI_BFS_RATE) { |
382 | codec_bclk = params_rate(params) * | 482 | codec_bclk = params_rate(params) * rtd->codec_dai->dai_runtime.bfs; |
383 | SND_SOC_FSB_REAL(rtd->codec_dai->dai_runtime.bfs); | 483 | dbg("asoc: codec fs %d mclk %d bfs rate mult %llu bclk %d\n", |
384 | dbg("asoc: codec fs %d mclk %d bfs mult %d bclk %d\n", | ||
385 | rtd->codec_dai->dai_runtime.fs, mclk, | 484 | rtd->codec_dai->dai_runtime.fs, mclk, |
386 | SND_SOC_FSB_REAL(rtd->codec_dai->dai_runtime.bfs), codec_bclk); | 485 | rtd->codec_dai->dai_runtime.bfs, codec_bclk); |
387 | } | 486 | } else if (rtd->cpu_dai->dai_runtime.flags == SND_SOC_DAI_BFS_RCW) { |
487 | codec_bclk = params_rate(params) * params_channels(params) * | ||
488 | snd_pcm_format_physical_width(rtd->codec_dai->dai_runtime.pcmfmt) * | ||
489 | SND_SOC_FSBW_REAL(rtd->codec_dai->dai_runtime.bfs); | ||
490 | dbg("asoc: codec fs %d mclk %d bfs rcw mult %d bclk %d\n", | ||
491 | rtd->codec_dai->dai_runtime.fs, mclk, | ||
492 | SND_SOC_FSBW_REAL(rtd->codec_dai->dai_runtime.bfs), codec_bclk); | ||
493 | } else | ||
494 | codec_bclk = 0; | ||
495 | |||
388 | if (rtd->cpu_dai->dai_runtime.flags == SND_SOC_DAI_BFS_DIV) { | 496 | if (rtd->cpu_dai->dai_runtime.flags == SND_SOC_DAI_BFS_DIV) { |
389 | cpu_bclk = (rtd->cpu_dai->dai_runtime.fs * params_rate(params)) / | 497 | cpu_bclk = (rtd->cpu_dai->dai_runtime.fs * params_rate(params)) / |
390 | SND_SOC_FSBD_REAL(rtd->cpu_dai->dai_runtime.bfs); | 498 | SND_SOC_FSBD_REAL(rtd->cpu_dai->dai_runtime.bfs); |
391 | dbg("asoc: cpu fs %d mclk %d bfs div %d bclk %d\n", | 499 | dbg("asoc: cpu fs %d mclk %d bfs div %d bclk %d\n", |
392 | rtd->cpu_dai->dai_runtime.fs, mclk, | 500 | rtd->cpu_dai->dai_runtime.fs, mclk, |
393 | SND_SOC_FSBD_REAL(rtd->cpu_dai->dai_runtime.bfs), cpu_bclk); | 501 | SND_SOC_FSBD_REAL(rtd->cpu_dai->dai_runtime.bfs), cpu_bclk); |
394 | } else { | 502 | } else if (rtd->cpu_dai->dai_runtime.flags == SND_SOC_DAI_BFS_RATE) { |
395 | cpu_bclk = params_rate(params) * | 503 | cpu_bclk = params_rate(params) * rtd->cpu_dai->dai_runtime.bfs; |
396 | SND_SOC_FSB_REAL(rtd->cpu_dai->dai_runtime.bfs); | 504 | dbg("asoc: cpu fs %d mclk %d bfs rate mult %llu bclk %d\n", |
397 | dbg("asoc: cpu fs %d mclk %d bfs mult %d bclk %d\n", | ||
398 | rtd->cpu_dai->dai_runtime.fs, mclk, | 505 | rtd->cpu_dai->dai_runtime.fs, mclk, |
399 | SND_SOC_FSB_REAL(rtd->cpu_dai->dai_runtime.bfs), cpu_bclk); | 506 | rtd->cpu_dai->dai_runtime.bfs, cpu_bclk); |
400 | } | 507 | } else if (rtd->cpu_dai->dai_runtime.flags == SND_SOC_DAI_BFS_RCW) { |
508 | cpu_bclk = params_rate(params) * params_channels(params) * | ||
509 | snd_pcm_format_physical_width(rtd->cpu_dai->dai_runtime.pcmfmt) * | ||
510 | SND_SOC_FSBW_REAL(rtd->cpu_dai->dai_runtime.bfs); | ||
511 | dbg("asoc: cpu fs %d mclk %d bfs mult rcw %d bclk %d\n", | ||
512 | rtd->cpu_dai->dai_runtime.fs, mclk, | ||
513 | SND_SOC_FSBW_REAL(rtd->cpu_dai->dai_runtime.bfs), cpu_bclk); | ||
514 | } else | ||
515 | cpu_bclk = 0; | ||
401 | 516 | ||
402 | /* | 517 | /* |
403 | * Check we have matching bitclocks. If we don't then it means the | 518 | * Check we have matching bitclocks. If we don't then it means the |
@@ -405,7 +520,7 @@ found: | |||
405 | * machine sysclock function) is wrong compared with the supported DAI | 520 | * machine sysclock function) is wrong compared with the supported DAI |
406 | * modes for the codec or cpu DAI. | 521 | * modes for the codec or cpu DAI. |
407 | */ | 522 | */ |
408 | if (cpu_bclk != codec_bclk){ | 523 | if (cpu_bclk != codec_bclk && cpu_bclk){ |
409 | printk(KERN_ERR | 524 | printk(KERN_ERR |
410 | "asoc: codec and cpu bitclocks differ, audio may be wrong speed\n" | 525 | "asoc: codec and cpu bitclocks differ, audio may be wrong speed\n" |
411 | ); | 526 | ); |
@@ -723,14 +838,18 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
723 | mutex_lock(&pcm_mutex); | 838 | mutex_lock(&pcm_mutex); |
724 | if (platform->pcm_ops->prepare) { | 839 | if (platform->pcm_ops->prepare) { |
725 | ret = platform->pcm_ops->prepare(substream); | 840 | ret = platform->pcm_ops->prepare(substream); |
726 | if (ret < 0) | 841 | if (ret < 0) { |
842 | printk(KERN_ERR "asoc: platform prepare error\n"); | ||
727 | goto out; | 843 | goto out; |
844 | } | ||
728 | } | 845 | } |
729 | 846 | ||
730 | if (rtd->codec_dai->ops.prepare) { | 847 | if (rtd->codec_dai->ops.prepare) { |
731 | ret = rtd->codec_dai->ops.prepare(substream); | 848 | ret = rtd->codec_dai->ops.prepare(substream); |
732 | if (ret < 0) | 849 | if (ret < 0) { |
850 | printk(KERN_ERR "asoc: codec DAI prepare error\n"); | ||
733 | goto out; | 851 | goto out; |
852 | } | ||
734 | } | 853 | } |
735 | 854 | ||
736 | if (rtd->cpu_dai->ops.prepare) | 855 | if (rtd->cpu_dai->ops.prepare) |