1
2
3
4
5
6
7
8
9#include "motu.h"
10
11#include <linux/delay.h>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48#define CLK_828_STATUS_OFFSET 0x0b00
49#define CLK_828_STATUS_MASK 0x0000ffff
50#define CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF 0x00008000
51#define CLK_828_STATUS_FLAG_OPT_OUT_IFACE_IS_SPDIF 0x00004000
52#define CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES 0x00000080
53#define CLK_828_STATUS_FLAG_ENABLE_OUTPUT 0x00000008
54#define CLK_828_STATUS_FLAG_RATE_48000 0x00000004
55#define CLK_828_STATUS_MASK_SRC 0x00000023
56#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT 0x00000021
57#define CLK_828_STATUS_FLAG_SRC_SPH 0x00000003
58#define CLK_828_STATUS_FLAG_SRC_SPDIF 0x00000002
59#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_DSUB 0x00000001
60#define CLK_828_STATUS_FLAG_SRC_INTERNAL 0x00000000
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112#define CLK_896_STATUS_OFFSET 0x0b14
113#define CLK_896_STATUS_FLAG_FETCH_ENABLE 0x20000000
114#define CLK_896_STATUS_FLAG_OUTPUT_ON 0x03000000
115#define CLK_896_STATUS_MASK_SRC 0x00000007
116#define CLK_896_STATUS_FLAG_SRC_INTERNAL 0x00000000
117#define CLK_896_STATUS_FLAG_SRC_ADAT_ON_OPT 0x00000001
118#define CLK_896_STATUS_FLAG_SRC_AESEBU 0x00000002
119#define CLK_896_STATUS_FLAG_SRC_SPH 0x00000003
120#define CLK_896_STATUS_FLAG_SRC_WORD 0x00000004
121#define CLK_896_STATUS_FLAG_SRC_ADAT_ON_DSUB 0x00000005
122#define CLK_896_STATUS_MASK_RATE 0x00000018
123#define CLK_896_STATUS_FLAG_RATE_44100 0x00000000
124#define CLK_896_STATUS_FLAG_RATE_48000 0x00000008
125#define CLK_896_STATUS_FLAG_RATE_88200 0x00000010
126#define CLK_896_STATUS_FLAG_RATE_96000 0x00000018
127
128static void parse_clock_rate_828(u32 data, unsigned int *rate)
129{
130 if (data & CLK_828_STATUS_FLAG_RATE_48000)
131 *rate = 48000;
132 else
133 *rate = 44100;
134}
135
136static int get_clock_rate_828(struct snd_motu *motu, unsigned int *rate)
137{
138 __be32 reg;
139 int err;
140
141 err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
142 if (err < 0)
143 return err;
144 parse_clock_rate_828(be32_to_cpu(reg), rate);
145
146 return 0;
147}
148
149static int parse_clock_rate_896(u32 data, unsigned int *rate)
150{
151 switch (data & CLK_896_STATUS_MASK_RATE) {
152 case CLK_896_STATUS_FLAG_RATE_44100:
153 *rate = 44100;
154 break;
155 case CLK_896_STATUS_FLAG_RATE_48000:
156 *rate = 48000;
157 break;
158 case CLK_896_STATUS_FLAG_RATE_88200:
159 *rate = 88200;
160 break;
161 case CLK_896_STATUS_FLAG_RATE_96000:
162 *rate = 96000;
163 break;
164 default:
165 return -ENXIO;
166 }
167
168 return 0;
169}
170
171static int get_clock_rate_896(struct snd_motu *motu, unsigned int *rate)
172{
173 __be32 reg;
174 int err;
175
176 err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
177 if (err < 0)
178 return err;
179 return parse_clock_rate_896(be32_to_cpu(reg), rate);
180}
181
182int snd_motu_protocol_v1_get_clock_rate(struct snd_motu *motu, unsigned int *rate)
183{
184 if (motu->spec == &snd_motu_spec_828)
185 return get_clock_rate_828(motu, rate);
186 else if (motu->spec == &snd_motu_spec_896)
187 return get_clock_rate_896(motu, rate);
188 else
189 return -ENXIO;
190}
191
192static int set_clock_rate_828(struct snd_motu *motu, unsigned int rate)
193{
194 __be32 reg;
195 u32 data;
196 int err;
197
198 err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
199 if (err < 0)
200 return err;
201 data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
202
203 data &= ~CLK_828_STATUS_FLAG_RATE_48000;
204 if (rate == 48000)
205 data |= CLK_828_STATUS_FLAG_RATE_48000;
206
207 reg = cpu_to_be32(data);
208 return snd_motu_transaction_write(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
209}
210
211static int set_clock_rate_896(struct snd_motu *motu, unsigned int rate)
212{
213 unsigned int flag;
214 __be32 reg;
215 u32 data;
216 int err;
217
218 err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
219 if (err < 0)
220 return err;
221 data = be32_to_cpu(reg);
222
223 switch (rate) {
224 case 44100:
225 flag = CLK_896_STATUS_FLAG_RATE_44100;
226 break;
227 case 48000:
228 flag = CLK_896_STATUS_FLAG_RATE_48000;
229 break;
230 case 88200:
231 flag = CLK_896_STATUS_FLAG_RATE_88200;
232 break;
233 case 96000:
234 flag = CLK_896_STATUS_FLAG_RATE_96000;
235 break;
236 default:
237 return -EINVAL;
238 }
239
240 data &= ~CLK_896_STATUS_MASK_RATE;
241 data |= flag;
242
243 reg = cpu_to_be32(data);
244 return snd_motu_transaction_write(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
245}
246
247int snd_motu_protocol_v1_set_clock_rate(struct snd_motu *motu, unsigned int rate)
248{
249 if (motu->spec == &snd_motu_spec_828)
250 return set_clock_rate_828(motu, rate);
251 else if (motu->spec == &snd_motu_spec_896)
252 return set_clock_rate_896(motu, rate);
253 else
254 return -ENXIO;
255}
256
257static int get_clock_source_828(struct snd_motu *motu, enum snd_motu_clock_source *src)
258{
259 __be32 reg;
260 u32 data;
261 int err;
262
263 err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
264 if (err < 0)
265 return err;
266 data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
267
268 switch (data & CLK_828_STATUS_MASK_SRC) {
269 case CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT:
270 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
271 break;
272 case CLK_828_STATUS_FLAG_SRC_SPH:
273 *src = SND_MOTU_CLOCK_SOURCE_SPH;
274 break;
275 case CLK_828_STATUS_FLAG_SRC_SPDIF:
276 {
277 if (data & CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF)
278 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
279 else
280 *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT;
281 break;
282 }
283 case CLK_828_STATUS_FLAG_SRC_ADAT_ON_DSUB:
284 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
285 break;
286 case CLK_828_STATUS_FLAG_SRC_INTERNAL:
287 *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
288 break;
289 default:
290 return -ENXIO;
291 }
292
293 return 0;
294}
295
296static int get_clock_source_896(struct snd_motu *motu, enum snd_motu_clock_source *src)
297{
298 __be32 reg;
299 u32 data;
300 int err;
301
302 err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
303 if (err < 0)
304 return err;
305 data = be32_to_cpu(reg);
306
307 switch (data & CLK_896_STATUS_MASK_SRC) {
308 case CLK_896_STATUS_FLAG_SRC_INTERNAL:
309 *src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
310 break;
311 case CLK_896_STATUS_FLAG_SRC_ADAT_ON_OPT:
312 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
313 break;
314 case CLK_896_STATUS_FLAG_SRC_AESEBU:
315 *src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
316 break;
317 case CLK_896_STATUS_FLAG_SRC_SPH:
318 *src = SND_MOTU_CLOCK_SOURCE_SPH;
319 break;
320 case CLK_896_STATUS_FLAG_SRC_WORD:
321 *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
322 break;
323 case CLK_896_STATUS_FLAG_SRC_ADAT_ON_DSUB:
324 *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
325 break;
326 default:
327 return -ENXIO;
328 }
329
330 return 0;
331}
332
333int snd_motu_protocol_v1_get_clock_source(struct snd_motu *motu, enum snd_motu_clock_source *src)
334{
335 if (motu->spec == &snd_motu_spec_828)
336 return get_clock_source_828(motu, src);
337 else if (motu->spec == &snd_motu_spec_896)
338 return get_clock_source_896(motu, src);
339 else
340 return -ENXIO;
341}
342
343static int switch_fetching_mode_828(struct snd_motu *motu, bool enable)
344{
345 __be32 reg;
346 u32 data;
347 int err;
348
349 err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
350 if (err < 0)
351 return err;
352 data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
353
354 data &= ~(CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_ENABLE_OUTPUT);
355 if (enable) {
356
357
358
359 msleep(100);
360 data |= CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_ENABLE_OUTPUT;
361 }
362
363 reg = cpu_to_be32(data);
364 return snd_motu_transaction_write(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
365}
366
367static int switch_fetching_mode_896(struct snd_motu *motu, bool enable)
368{
369 __be32 reg;
370 u32 data;
371 int err;
372
373 err = snd_motu_transaction_read(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
374 if (err < 0)
375 return err;
376 data = be32_to_cpu(reg);
377
378 data &= ~CLK_896_STATUS_FLAG_FETCH_ENABLE;
379 if (enable)
380 data |= CLK_896_STATUS_FLAG_FETCH_ENABLE | CLK_896_STATUS_FLAG_OUTPUT_ON;
381
382 reg = cpu_to_be32(data);
383 return snd_motu_transaction_write(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
384}
385
386int snd_motu_protocol_v1_switch_fetching_mode(struct snd_motu *motu, bool enable)
387{
388 if (motu->spec == &snd_motu_spec_828)
389 return switch_fetching_mode_828(motu, enable);
390 else if (motu->spec == &snd_motu_spec_896)
391 return switch_fetching_mode_896(motu, enable);
392 else
393 return -ENXIO;
394}
395
396static int detect_packet_formats_828(struct snd_motu *motu)
397{
398 __be32 reg;
399 u32 data;
400 int err;
401
402 motu->tx_packet_formats.pcm_byte_offset = 4;
403 motu->tx_packet_formats.msg_chunks = 2;
404
405 motu->rx_packet_formats.pcm_byte_offset = 4;
406 motu->rx_packet_formats.msg_chunks = 0;
407
408 err = snd_motu_transaction_read(motu, CLK_828_STATUS_OFFSET, ®, sizeof(reg));
409 if (err < 0)
410 return err;
411 data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
412
413
414 if (!(data & CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF))
415 motu->tx_packet_formats.pcm_chunks[0] += 8;
416
417 if (!(data & CLK_828_STATUS_FLAG_OPT_OUT_IFACE_IS_SPDIF))
418 motu->rx_packet_formats.pcm_chunks[0] += 8;
419
420 return 0;
421}
422
423static int detect_packet_formats_896(struct snd_motu *motu)
424{
425
426 motu->tx_packet_formats.pcm_byte_offset = 4;
427 motu->rx_packet_formats.pcm_byte_offset = 4;
428
429
430 motu->tx_packet_formats.msg_chunks = 0;
431 motu->rx_packet_formats.msg_chunks = 0;
432
433
434
435 motu->tx_packet_formats.pcm_chunks[0] += 8;
436 motu->tx_packet_formats.pcm_chunks[1] += 8;
437
438 motu->rx_packet_formats.pcm_chunks[0] += 8;
439 motu->rx_packet_formats.pcm_chunks[1] += 8;
440
441 return 0;
442}
443
444int snd_motu_protocol_v1_cache_packet_formats(struct snd_motu *motu)
445{
446 memcpy(motu->tx_packet_formats.pcm_chunks, motu->spec->tx_fixed_pcm_chunks,
447 sizeof(motu->tx_packet_formats.pcm_chunks));
448 memcpy(motu->rx_packet_formats.pcm_chunks, motu->spec->rx_fixed_pcm_chunks,
449 sizeof(motu->rx_packet_formats.pcm_chunks));
450
451 if (motu->spec == &snd_motu_spec_828)
452 return detect_packet_formats_828(motu);
453 else if (motu->spec == &snd_motu_spec_896)
454 return detect_packet_formats_896(motu);
455 else
456 return 0;
457}
458
459const struct snd_motu_spec snd_motu_spec_828 = {
460 .name = "828",
461 .protocol_version = SND_MOTU_PROTOCOL_V1,
462 .tx_fixed_pcm_chunks = {10, 0, 0},
463 .rx_fixed_pcm_chunks = {10, 0, 0},
464};
465
466const struct snd_motu_spec snd_motu_spec_896 = {
467 .name = "896",
468 .tx_fixed_pcm_chunks = {10, 10, 0},
469 .rx_fixed_pcm_chunks = {10, 10, 0},
470};
471