aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Girdwood <lg@opensource.wolfsonmicro.com>2006-10-19 14:35:56 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:01:07 -0500
commita71a468a50f1385855e28864e26251b02df829bb (patch)
tree243daee96ea5c55c88a186aa03b7917f7ad533f6
parent543a0fbe18d0b44f3d037fe6b59458fa0c0d5e4b (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.txt358
-rw-r--r--Documentation/sound/alsa/soc/clocking.txt13
-rw-r--r--include/sound/soc.h23
-rw-r--r--sound/soc/codecs/wm8731.c33
-rw-r--r--sound/soc/codecs/wm8750.c15
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c3
-rw-r--r--sound/soc/soc-core.c215
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
12frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 12frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97
13frame is 21uS long and is divided into 13 time slots. 13frame is 21uS long and is divided into 13 time slots.
14 14
15The AC97 specification can be found at http://intel.com/ 15The AC97 specification can be found at :-
16http://www.intel.com/design/chipsets/audio/ac97_r23.pdf
16 17
17 18
18I2S 19I2S
@@ -77,16 +78,16 @@ sample rates first and then test your interface.
77struct snd_soc_dai_mode is defined (in soc.h) as:- 78struct snd_soc_dai_mode is defined (in soc.h) as:-
78 79
79/* SoC DAI mode */ 80/* SoC DAI mode */
80struct snd_soc_hw_mode { 81struct 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
92fmt: 93fmt:
@@ -140,14 +141,14 @@ pcmfmt:
140The hardware PCM format. This describes the PCM formats supported by the DAI 141The hardware PCM format. This describes the PCM formats supported by the DAI
141mode e.g. 142mode 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
146pcmrate: 147pcmrate:
147---------- 148----------
148The PCM sample rates supported by the DAI mode. e.g. 149The 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--------
162The DAI hardware flags supported by the mode. 163The DAI hardware flags supported by the mode.
163 164
164SND_SOC_DAI_BFS_DIV 165/* use bfs mclk divider mode (BCLK = MCLK / x) */
165This flag states that bit clock is generated by dividing MCLK in this mode, if 166#define SND_SOC_DAI_BFS_DIV 0x1
166this 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
168NOTE: Bitclock division and mulitiplication modes can be safely matched by the 174NOTE: Bitclock division and mulitiplication modes can be safely matched by the
169core logic. 175core logic.
@@ -181,7 +187,7 @@ depends on the codec or CPU DAI).
181 187
182The BFS supported by the DAI mode. This can either be the ratio between the 188The BFS supported by the DAI mode. This can either be the ratio between the
183bitclock (BCLK) and the sample rate OR the ratio between the system clock and 189bitclock (BCLK) and the sample rate OR the ratio between the system clock and
184the sample rate. Depends on the SND_SOC_DAI_BFS_DIV flag above. 190the sample rate. Depends on the flags above.
185 191
186priv: 192priv:
187----- 193-----
@@ -207,10 +213,15 @@ Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a
207BCLK of either MCLK/2 or MCLK/4. 213BCLK 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
216Example 2 227Example 2
@@ -219,32 +230,95 @@ Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a
219BCLK of either Rate * 32 or Rate * 64. 230BCLK 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
228Example 3 253Example 3
229--------- 254---------
255Codec that runs at 8k & 48k @ 256FS in master mode, can generate a BCLK that
256is a multiple of Rate * channels * word size. (RCW) i.e.
257
258 BCLK = 8000 * 2 * 16 (8k, stereo, 16bit)
259 = 256kHz
260
261This 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
274Example 4
275---------
230Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a 276Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a
231BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long 277BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long
232as BCLK is rate * 32 or rate * 64. 278as 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
247Example 4 321Example 5
248--------- 322---------
249Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master 323Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master
250mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave 324mode 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
284Example 5 377Example 6
285--------- 378---------
286Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use 379Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use
287with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). 380with 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
323Example 6 435Example 7
324--------- 436---------
325AC97 Codec that does not support VRA (i.e only runs at 48k). 437AC97 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
339Example 7 453Example 8
340--------- 454---------
341 455
342CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. 456CPU 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
27The DAI also has a frame clock to signal the start of each audio frame. This 27The DAI also has a frame clock to signal the start of each audio frame. This
28clock is sometimes referred to as LRC (left right clock) or FRAME. This clock 28clock is sometimes referred to as LRC (left right clock) or FRAME. This clock
29runs at exactly the sample rate. 29runs at exactly the sample rate (LRC = Rate).
30 30
31Bit Clock is usually always a ratio of MCLK or a multiple of LRC. i.e. 31Bit Clock can be generated as follows:-
32 32
33BCLK = MCLK / x 33BCLK = MCLK / x
34 34
@@ -36,9 +36,14 @@ BCLK = MCLK / x
36 36
37BCLK = LRC * x 37BCLK = LRC * x
38 38
39 or
40
41BCLK = LRC * Channels * Word Size
42
39This relationship depends on the codec or SoC CPU in particular. ASoC can quite 43This relationship depends on the codec or SoC CPU in particular. ASoC can quite
40easily match a codec that generates BCLK by division (FSBD) with a CPU that 44easily match BCLK generated by division (SND_SOC_DAI_BFS_DIV) with BCLK by
41generates BCLK by multiplication (FSB). 45multiplication (SND_SOC_DAI_BFS_RATE) or BCLK generated by
46Rate * Channels * Word size (RCW or SND_SOC_DAI_BFS_RCW).
42 47
43 48
44ASoC Clocking 49ASoC 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)
836static unsigned int wm8750_config_sysclk(struct snd_soc_codec_dai *dai, 839static 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
54static DEFINE_MUTEX(pcm_mutex); 56static DEFINE_MUTEX(pcm_mutex);
55static DEFINE_MUTEX(io_mutex); 57static DEFINE_MUTEX(io_mutex);
56static struct workqueue_struct *soc_workq; 58static 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 */
153static u16 soc_bfs_mult_to_div(u16 bfs, int rate, unsigned int mclk, 155static 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 */
183static u16 soc_bfs_div_to_mult(u16 bfs, int rate, unsigned int mclk, 182static 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 */
212static 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 */
235static 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 */
213static int soc_hw_match_params(struct snd_pcm_substream *substream, 258static 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)