Commit | Line | Data |
---|---|---|
eb1a6af3 LG |
1 | ASoC currently supports the three main Digital Audio Interfaces (DAI) found on |
2 | SoC controllers and portable audio CODECS today, namely AC97, I2S and PCM. | |
3 | ||
4 | ||
5 | AC97 | |
6 | ==== | |
7 | ||
8 | AC97 is a five wire interface commonly found on many PC sound cards. It is | |
9 | now also popular in many portable devices. This DAI has a reset line and time | |
10 | multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines. | |
11 | 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 | |
13 | frame is 21uS long and is divided into 13 time slots. | |
14 | ||
a71a468a LG |
15 | The AC97 specification can be found at :- |
16 | http://www.intel.com/design/chipsets/audio/ac97_r23.pdf | |
eb1a6af3 LG |
17 | |
18 | ||
19 | I2S | |
20 | === | |
21 | ||
22 | I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and | |
23 | Rx lines are used for audio transmision, whilst the bit clock (BCLK) and | |
24 | left/right clock (LRC) synchronise the link. I2S is flexible in that either the | |
25 | controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock | |
26 | usually varies depending on the sample rate and the master system clock | |
27 | (SYSCLK). LRCLK is the same as the sample rate. A few devices support separate | |
28 | ADC and DAC LRCLK's, this allows for similtanious capture and playback at | |
29 | different sample rates. | |
30 | ||
31 | I2S has several different operating modes:- | |
32 | ||
33 | o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC | |
34 | transition. | |
35 | ||
36 | o Left Justified - MSB is transmitted on transition of LRC. | |
37 | ||
38 | o Right Justified - MSB is transmitted sample size BCLK's before LRC | |
39 | transition. | |
40 | ||
41 | PCM | |
42 | === | |
43 | ||
44 | PCM is another 4 wire interface, very similar to I2S, that can support a more | |
45 | flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used | |
46 | to synchronise the link whilst the Tx and Rx lines are used to transmit and | |
47 | receive the audio data. Bit clock usually varies depending on sample rate | |
48 | whilst sync runs at the sample rate. PCM also supports Time Division | |
49 | Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This | |
50 | is sometimes referred to as network mode). | |
51 | ||
52 | Common PCM operating modes:- | |
53 | ||
54 | o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC. | |
55 | ||
56 | o Mode B - MSB is transmitted on rising edge of FRAME/SYNC. | |
57 | ||
58 | ||
59 | ASoC DAI Configuration | |
60 | ====================== | |
61 | ||
62 | Every CODEC DAI and SoC DAI must have their capabilities defined in order to | |
63 | be configured together at runtime when the audio and clocking parameters are | |
64 | known. This is achieved by creating an array of struct snd_soc_hw_mode in the | |
65 | the CODEC and SoC interface drivers. Each element in the array describes a DAI | |
66 | mode and each mode is usually based upon the DAI system clock to sample rate | |
67 | ratio (FS). | |
68 | ||
69 | i.e. 48k sample rate @ 256 FS = sytem clock of 12.288 MHz | |
70 | 48000 * 256 = 12288000 | |
71 | ||
72 | The CPU and Codec DAI modes are then ANDed together at runtime to determine the | |
73 | rutime DAI configuration for both the Codec and CPU. | |
74 | ||
75 | When creating a new codec or SoC DAI it's probably best to start of with a few | |
76 | sample rates first and then test your interface. | |
77 | ||
78 | struct snd_soc_dai_mode is defined (in soc.h) as:- | |
79 | ||
80 | /* SoC DAI mode */ | |
a71a468a LG |
81 | struct snd_soc_dai_mode { |
82 | u16 fmt; /* SND_SOC_DAIFMT_* */ | |
83 | u16 tdm; /* SND_SOC_HWTDM_* */ | |
84 | u64 pcmfmt; /* SNDRV_PCM_FMTBIT_* */ | |
85 | u16 pcmrate; /* SND_SOC_HWRATE_* */ | |
86 | u16 pcmdir:2; /* SND_SOC_HWDIR_* */ | |
87 | u16 flags:8; /* hw flags */ | |
88 | u16 fs; /* mclk to rate divider */ | |
89 | u64 bfs; /* mclk to bclk dividers */ | |
90 | unsigned long priv; /* private mode data */ | |
eb1a6af3 LG |
91 | }; |
92 | ||
93 | fmt: | |
94 | ---- | |
95 | This field defines the DAI mode hardware format (e.g. I2S settings) and | |
96 | supports the following settings:- | |
97 | ||
98 | 1) hardware DAI formats | |
99 | ||
100 | #define SND_SOC_DAIFMT_I2S (1 << 0) /* I2S mode */ | |
101 | #define SND_SOC_DAIFMT_RIGHT_J (1 << 1) /* Right justified mode */ | |
102 | #define SND_SOC_DAIFMT_LEFT_J (1 << 2) /* Left Justified mode */ | |
103 | #define SND_SOC_DAIFMT_DSP_A (1 << 3) /* L data msb after FRM */ | |
104 | #define SND_SOC_DAIFMT_DSP_B (1 << 4) /* L data msb during FRM */ | |
105 | #define SND_SOC_DAIFMT_AC97 (1 << 5) /* AC97 */ | |
106 | ||
107 | 2) hw DAI signal inversions | |
108 | ||
109 | #define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */ | |
110 | #define SND_SOC_DAIFMT_NB_IF (1 << 9) /* normal bclk + inv frm */ | |
111 | #define SND_SOC_DAIFMT_IB_NF (1 << 10) /* invert bclk + nor frm */ | |
112 | #define SND_SOC_DAIFMT_IB_IF (1 << 11) /* invert bclk + frm */ | |
113 | ||
114 | 3) hw clock masters | |
115 | This is wrt the codec, the inverse is true for the interface | |
116 | i.e. if the codec is clk and frm master then the interface is | |
117 | clk and frame slave. | |
118 | ||
119 | #define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & frm master */ | |
120 | #define SND_SOC_DAIFMT_CBS_CFM (1 << 13) /* codec clk slave & frm master */ | |
121 | #define SND_SOC_DAIFMT_CBM_CFS (1 << 14) /* codec clk master & frame slave */ | |
122 | #define SND_SOC_DAIFMT_CBS_CFS (1 << 15) /* codec clk & frm slave */ | |
123 | ||
124 | At least one option from each section must be selected. Multiple selections are | |
125 | also supported e.g. | |
126 | ||
127 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_RIGHT_J | \ | |
128 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_IB_NF | \ | |
129 | SND_SOC_DAIFMT_IB_IF | |
130 | ||
131 | ||
132 | tdm: | |
133 | ------ | |
134 | This field defines the Time Division Multiplexing left and right word | |
135 | positions for the DAI mode if applicable. Set to SND_SOC_DAITDM_LRDW(0,0) for | |
136 | no TDM. | |
137 | ||
138 | ||
139 | pcmfmt: | |
140 | --------- | |
141 | The hardware PCM format. This describes the PCM formats supported by the DAI | |
142 | mode e.g. | |
143 | ||
a71a468a | 144 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ |
eb1a6af3 LG |
145 | SNDRV_PCM_FORMAT_S24_3LE |
146 | ||
147 | pcmrate: | |
148 | ---------- | |
149 | The PCM sample rates supported by the DAI mode. e.g. | |
150 | ||
a71a468a | 151 | .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ |
eb1a6af3 LG |
152 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
153 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | |
154 | ||
155 | ||
156 | pcmdir: | |
157 | --------- | |
158 | The stream directions supported by this mode. e.g. playback and capture | |
159 | ||
160 | ||
161 | flags: | |
162 | -------- | |
163 | The DAI hardware flags supported by the mode. | |
164 | ||
a71a468a LG |
165 | /* use bfs mclk divider mode (BCLK = MCLK / x) */ |
166 | #define SND_SOC_DAI_BFS_DIV 0x1 | |
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 | |
eb1a6af3 LG |
173 | |
174 | NOTE: Bitclock division and mulitiplication modes can be safely matched by the | |
175 | core logic. | |
176 | ||
177 | ||
178 | fs: | |
179 | ----- | |
180 | The FS supported by this DAI mode FS is the ratio between the system clock and | |
181 | the sample rate. See above | |
182 | ||
183 | bfs: | |
184 | ------ | |
185 | BFS is the ratio of BCLK to MCLK or the ratio of BCLK to sample rate (this | |
186 | depends on the codec or CPU DAI). | |
187 | ||
188 | The BFS supported by the DAI mode. This can either be the ratio between the | |
189 | bitclock (BCLK) and the sample rate OR the ratio between the system clock and | |
a71a468a | 190 | the sample rate. Depends on the flags above. |
eb1a6af3 LG |
191 | |
192 | priv: | |
193 | ----- | |
194 | private codec mode data. | |
195 | ||
196 | ||
197 | ||
198 | Examples | |
199 | ======== | |
200 | ||
201 | Note that Codec DAI and CPU DAI examples are interchangeable in these examples | |
202 | as long as the bus master is reversed. i.e. | |
203 | ||
204 | SND_SOC_DAIFMT_CBM_CFM would become SND_SOC_DAIFMT_CBS_CFS | |
205 | and vice versa. | |
206 | ||
207 | This applies to all SND_SOC_DAIFMT_CB*_CF*. | |
208 | ||
209 | Example 1 | |
210 | --------- | |
211 | ||
212 | Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a | |
213 | BCLK of either MCLK/2 or MCLK/4. | |
214 | ||
215 | /* codec master */ | |
a71a468a LG |
216 | { |
217 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
218 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | } | |
eb1a6af3 LG |
225 | |
226 | ||
227 | Example 2 | |
228 | --------- | |
229 | Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a | |
230 | BCLK of either Rate * 32 or Rate * 64. | |
231 | ||
232 | /* codec master */ | |
a71a468a LG |
233 | { |
234 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
235 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
251 | |
252 | ||
253 | Example 3 | |
254 | --------- | |
a71a468a LG |
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 | --------- | |
eb1a6af3 LG |
276 | Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a |
277 | BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long | |
278 | as BCLK is rate * 32 or rate * 64. | |
279 | ||
280 | /* codec master */ | |
a71a468a LG |
281 | { |
282 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
283 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
299 | |
300 | /* codec slave */ | |
a71a468a LG |
301 | { |
302 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, | |
303 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
319 | |
320 | ||
a71a468a | 321 | Example 5 |
eb1a6af3 LG |
322 | --------- |
323 | Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master | |
324 | mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave | |
325 | mode as and does not care about FS or BCLK (as long as there is enough bandwidth). | |
326 | ||
327 | #define CODEC_FSB \ | |
328 | (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ | |
329 | SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) | |
330 | ||
331 | #define CODEC_RATES \ | |
332 | (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 |\ | |
333 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) | |
334 | ||
335 | /* codec master @ 128, 192 & 256 FS */ | |
a71a468a LG |
336 | { |
337 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
338 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
339 | .pcmrate = CODEC_RATES, | |
340 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | |
341 | .flags = SND_SOC_DAI_BFS_DIV, | |
342 | .fs = 128, | |
343 | .bfs = CODEC_FSB, | |
344 | }, | |
345 | ||
346 | { | |
347 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
348 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
365 | |
366 | /* codec slave */ | |
a71a468a LG |
367 | { |
368 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, | |
369 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
375 | |
376 | ||
a71a468a | 377 | Example 6 |
eb1a6af3 LG |
378 | --------- |
379 | Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use | |
380 | with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). | |
381 | Codec can also run in slave mode as and does not care about FS or BCLK (as long | |
382 | as there is enough bandwidth). Codec can support 16, 24 and 32 bit PCM sample | |
383 | sizes. | |
384 | ||
385 | #define CODEC_FSB \ | |
386 | (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ | |
387 | SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) | |
388 | ||
389 | #define CODEC_PCM_FORMATS \ | |
390 | (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ | |
391 | SNDRV_PCM_FORMAT_S24_3LE | SNDRV_PCM_FORMAT_S24_LE | SNDRV_PCM_FORMAT_S32_LE) | |
392 | ||
393 | /* codec master */ | |
a71a468a LG |
394 | { |
395 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
396 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
397 | .pcmrate = SNDRV_PCM_RATE_8000, | |
398 | .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, | |
399 | .flags = SND_SOC_DAI_BFS_DIV, | |
400 | .fs = 1536, | |
401 | .bfs = CODEC_FSB, | |
402 | }, | |
403 | ||
404 | { | |
405 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, | |
406 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
423 | |
424 | /* codec slave */ | |
a71a468a LG |
425 | { |
426 | .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, | |
427 | .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, | |
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 | }, | |
eb1a6af3 LG |
433 | |
434 | ||
a71a468a | 435 | Example 7 |
eb1a6af3 LG |
436 | --------- |
437 | AC97 Codec that does not support VRA (i.e only runs at 48k). | |
438 | ||
439 | #define AC97_DIR \ | |
440 | (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) | |
441 | ||
eb1a6af3 LG |
442 | #define AC97_PCM_FORMATS \ |
443 | (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S18_3LE | \ | |
444 | SNDRV_PCM_FORMAT_S20_3LE) | |
445 | ||
446 | /* AC97 with no VRA */ | |
a71a468a LG |
447 | { |
448 | .pcmfmt = AC97_PCM_FORMATS, | |
449 | .pcmrate = SNDRV_PCM_RATE_48000, | |
450 | } | |
eb1a6af3 LG |
451 | |
452 | ||
a71a468a | 453 | Example 8 |
eb1a6af3 LG |
454 | --------- |
455 | ||
456 | CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. | |
457 | Slave mode (CPU DAI is FRAME master) supports 8k - 96k at any FS as long as | |
458 | BCLK = 64 * rate. (Intel XScale I2S controller). | |
459 | ||
460 | #define PXA_I2S_DAIFMT \ | |
461 | (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF) | |
462 | ||
463 | #define PXA_I2S_DIR \ | |
464 | (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) | |
465 | ||
466 | #define PXA_I2S_RATES \ | |
467 | (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ | |
468 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | |
469 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | |
470 | ||
a71a468a LG |
471 | /* priv is divider */ |
472 | static struct snd_soc_dai_mode pxa2xx_i2s_modes[] = { | |
eb1a6af3 | 473 | /* pxa2xx I2S frame and clock master modes */ |
a71a468a LG |
474 | { |
475 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, | |
476 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | |
477 | .pcmrate = SNDRV_PCM_RATE_8000, | |
478 | .pcmdir = PXA_I2S_DIR, | |
479 | .flags = SND_SOC_DAI_BFS_DIV, | |
480 | .fs = 256, | |
481 | .bfs = SND_SOC_FSBD(4), | |
482 | .priv = 0x48, | |
483 | }, | |
484 | { | |
485 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, | |
486 | .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, | |
487 | .pcmrate = SNDRV_PCM_RATE_11025, | |
488 | .pcmdir = PXA_I2S_DIR, | |
489 | .flags = SND_SOC_DAI_BFS_DIV, | |
490 | .fs = 256, | |
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 | }, | |
eb1a6af3 LG |
534 | |
535 | /* pxa2xx I2S frame master and clock slave mode */ | |
a71a468a LG |
536 | { |
537 | .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, | |
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 | }; |