1 // SPDX-License-Identifier: GPL-2.0-only
3 * motu-protocol-v2.c - a part of driver for MOTU FireWire series
5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
10 #define V2_CLOCK_STATUS_OFFSET 0x0b14
11 #define V2_CLOCK_RATE_MASK 0x00000038
12 #define V2_CLOCK_RATE_SHIFT 3
13 #define V2_CLOCK_SRC_MASK 0x00000007
14 #define V2_CLOCK_SRC_SHIFT 0
15 #define V2_CLOCK_FETCH_ENABLE 0x02000000
16 #define V2_CLOCK_MODEL_SPECIFIC 0x04000000
18 #define V2_IN_OUT_CONF_OFFSET 0x0c04
19 #define V2_OPT_OUT_IFACE_MASK 0x00000c00
20 #define V2_OPT_OUT_IFACE_SHIFT 10
21 #define V2_OPT_IN_IFACE_MASK 0x00000300
22 #define V2_OPT_IN_IFACE_SHIFT 8
23 #define V2_OPT_IFACE_MODE_NONE 0
24 #define V2_OPT_IFACE_MODE_ADAT 1
25 #define V2_OPT_IFACE_MODE_SPDIF 2
27 static int get_clock_rate(u32 data
, unsigned int *rate
)
29 unsigned int index
= (data
& V2_CLOCK_RATE_MASK
) >> V2_CLOCK_RATE_SHIFT
;
30 if (index
>= ARRAY_SIZE(snd_motu_clock_rates
))
33 *rate
= snd_motu_clock_rates
[index
];
38 int snd_motu_protocol_v2_get_clock_rate(struct snd_motu
*motu
,
44 err
= snd_motu_transaction_read(motu
, V2_CLOCK_STATUS_OFFSET
, ®
,
49 return get_clock_rate(be32_to_cpu(reg
), rate
);
52 int snd_motu_protocol_v2_set_clock_rate(struct snd_motu
*motu
,
60 for (i
= 0; i
< ARRAY_SIZE(snd_motu_clock_rates
); ++i
) {
61 if (snd_motu_clock_rates
[i
] == rate
)
64 if (i
== ARRAY_SIZE(snd_motu_clock_rates
))
67 err
= snd_motu_transaction_read(motu
, V2_CLOCK_STATUS_OFFSET
, ®
,
71 data
= be32_to_cpu(reg
);
73 data
&= ~V2_CLOCK_RATE_MASK
;
74 data
|= i
<< V2_CLOCK_RATE_SHIFT
;
76 reg
= cpu_to_be32(data
);
77 return snd_motu_transaction_write(motu
, V2_CLOCK_STATUS_OFFSET
, ®
,
81 static int detect_clock_source_optical_model(struct snd_motu
*motu
, u32 data
,
82 enum snd_motu_clock_source
*src
)
86 *src
= SND_MOTU_CLOCK_SOURCE_INTERNAL
;
92 // To check the configuration of optical interface.
93 int err
= snd_motu_transaction_read(motu
, V2_IN_OUT_CONF_OFFSET
,
98 if (be32_to_cpu(reg
) & 0x00000200)
99 *src
= SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT
;
101 *src
= SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT
;
105 *src
= SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX
;
108 *src
= SND_MOTU_CLOCK_SOURCE_SPH
;
111 *src
= SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC
;
114 *src
= SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB
;
117 *src
= SND_MOTU_CLOCK_SOURCE_UNKNOWN
;
124 static int v2_detect_clock_source(struct snd_motu
*motu
, u32 data
,
125 enum snd_motu_clock_source
*src
)
129 *src
= SND_MOTU_CLOCK_SOURCE_INTERNAL
;
132 *src
= SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX
;
135 *src
= SND_MOTU_CLOCK_SOURCE_SPH
;
138 *src
= SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC
;
141 *src
= SND_MOTU_CLOCK_SOURCE_UNKNOWN
;
148 static int get_clock_source(struct snd_motu
*motu
, u32 data
,
149 enum snd_motu_clock_source
*src
)
151 data
&= V2_CLOCK_SRC_MASK
;
152 if (motu
->spec
== &snd_motu_spec_828mk2
||
153 motu
->spec
== &snd_motu_spec_traveler
)
154 return detect_clock_source_optical_model(motu
, data
, src
);
156 return v2_detect_clock_source(motu
, data
, src
);
159 int snd_motu_protocol_v2_get_clock_source(struct snd_motu
*motu
,
160 enum snd_motu_clock_source
*src
)
165 err
= snd_motu_transaction_read(motu
, V2_CLOCK_STATUS_OFFSET
, ®
,
170 return get_clock_source(motu
, be32_to_cpu(reg
), src
);
173 // Expected for Traveler and 896HD, which implements Altera Cyclone EP1C3.
174 static int switch_fetching_mode_cyclone(struct snd_motu
*motu
, u32
*data
,
177 *data
|= V2_CLOCK_MODEL_SPECIFIC
;
182 // For UltraLite and 8pre, which implements Xilinx Spartan XC3S200.
183 static int switch_fetching_mode_spartan(struct snd_motu
*motu
, u32
*data
,
187 enum snd_motu_clock_source src
;
190 err
= get_clock_source(motu
, *data
, &src
);
194 err
= get_clock_rate(*data
, &rate
);
198 if (src
== SND_MOTU_CLOCK_SOURCE_SPH
&& rate
> 48000)
199 *data
|= V2_CLOCK_MODEL_SPECIFIC
;
204 int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu
*motu
,
207 if (motu
->spec
== &snd_motu_spec_828mk2
) {
208 // 828mkII implements Altera ACEX 1K EP1K30. Nothing to do.
215 err
= snd_motu_transaction_read(motu
, V2_CLOCK_STATUS_OFFSET
,
219 data
= be32_to_cpu(reg
);
221 data
&= ~(V2_CLOCK_FETCH_ENABLE
| V2_CLOCK_MODEL_SPECIFIC
);
223 data
|= V2_CLOCK_FETCH_ENABLE
;
225 if (motu
->spec
== &snd_motu_spec_traveler
)
226 err
= switch_fetching_mode_cyclone(motu
, &data
, enable
);
228 err
= switch_fetching_mode_spartan(motu
, &data
, enable
);
232 reg
= cpu_to_be32(data
);
233 return snd_motu_transaction_write(motu
, V2_CLOCK_STATUS_OFFSET
,
238 static int detect_packet_formats_828mk2(struct snd_motu
*motu
, u32 data
)
240 if (((data
& V2_OPT_IN_IFACE_MASK
) >> V2_OPT_IN_IFACE_SHIFT
) ==
241 V2_OPT_IFACE_MODE_ADAT
) {
242 motu
->tx_packet_formats
.pcm_chunks
[0] += 8;
243 motu
->tx_packet_formats
.pcm_chunks
[1] += 4;
246 if (((data
& V2_OPT_OUT_IFACE_MASK
) >> V2_OPT_OUT_IFACE_SHIFT
) ==
247 V2_OPT_IFACE_MODE_ADAT
) {
248 motu
->rx_packet_formats
.pcm_chunks
[0] += 8;
249 motu
->rx_packet_formats
.pcm_chunks
[1] += 4;
255 static int detect_packet_formats_traveler(struct snd_motu
*motu
, u32 data
)
257 if (((data
& V2_OPT_IN_IFACE_MASK
) >> V2_OPT_IN_IFACE_SHIFT
) ==
258 V2_OPT_IFACE_MODE_ADAT
) {
259 motu
->tx_packet_formats
.pcm_chunks
[0] += 8;
260 motu
->tx_packet_formats
.pcm_chunks
[1] += 4;
263 if (((data
& V2_OPT_OUT_IFACE_MASK
) >> V2_OPT_OUT_IFACE_SHIFT
) ==
264 V2_OPT_IFACE_MODE_ADAT
) {
265 motu
->rx_packet_formats
.pcm_chunks
[0] += 8;
266 motu
->rx_packet_formats
.pcm_chunks
[1] += 4;
272 static int detect_packet_formats_8pre(struct snd_motu
*motu
, u32 data
)
274 if (((data
& V2_OPT_IN_IFACE_MASK
) >> V2_OPT_IN_IFACE_SHIFT
) ==
275 V2_OPT_IFACE_MODE_ADAT
) {
276 motu
->tx_packet_formats
.pcm_chunks
[0] += 8;
277 motu
->tx_packet_formats
.pcm_chunks
[1] += 8;
280 if (((data
& V2_OPT_OUT_IFACE_MASK
) >> V2_OPT_OUT_IFACE_SHIFT
) ==
281 V2_OPT_IFACE_MODE_ADAT
) {
282 motu
->rx_packet_formats
.pcm_chunks
[0] += 8;
283 motu
->rx_packet_formats
.pcm_chunks
[1] += 8;
289 int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu
*motu
)
295 motu
->tx_packet_formats
.pcm_byte_offset
= 10;
296 motu
->rx_packet_formats
.pcm_byte_offset
= 10;
298 motu
->tx_packet_formats
.msg_chunks
= 2;
299 motu
->rx_packet_formats
.msg_chunks
= 2;
301 err
= snd_motu_transaction_read(motu
, V2_IN_OUT_CONF_OFFSET
, ®
,
305 data
= be32_to_cpu(reg
);
307 memcpy(motu
->tx_packet_formats
.pcm_chunks
,
308 motu
->spec
->tx_fixed_pcm_chunks
,
309 sizeof(motu
->tx_packet_formats
.pcm_chunks
));
310 memcpy(motu
->rx_packet_formats
.pcm_chunks
,
311 motu
->spec
->rx_fixed_pcm_chunks
,
312 sizeof(motu
->rx_packet_formats
.pcm_chunks
));
314 if (motu
->spec
== &snd_motu_spec_828mk2
)
315 return detect_packet_formats_828mk2(motu
, data
);
316 else if (motu
->spec
== &snd_motu_spec_traveler
)
317 return detect_packet_formats_traveler(motu
, data
);
318 else if (motu
->spec
== &snd_motu_spec_8pre
)
319 return detect_packet_formats_8pre(motu
, data
);
324 const struct snd_motu_spec snd_motu_spec_828mk2
= {
326 .protocol_version
= SND_MOTU_PROTOCOL_V2
,
327 .flags
= SND_MOTU_SPEC_RX_MIDI_2ND_Q
|
328 SND_MOTU_SPEC_TX_MIDI_2ND_Q
,
329 .tx_fixed_pcm_chunks
= {14, 14, 0},
330 .rx_fixed_pcm_chunks
= {14, 14, 0},
333 const struct snd_motu_spec snd_motu_spec_traveler
= {
335 .protocol_version
= SND_MOTU_PROTOCOL_V2
,
336 .flags
= SND_MOTU_SPEC_RX_MIDI_2ND_Q
|
337 SND_MOTU_SPEC_TX_MIDI_2ND_Q
,
338 .tx_fixed_pcm_chunks
= {14, 14, 8},
339 .rx_fixed_pcm_chunks
= {14, 14, 8},
342 const struct snd_motu_spec snd_motu_spec_ultralite
= {
344 .protocol_version
= SND_MOTU_PROTOCOL_V2
,
345 .flags
= SND_MOTU_SPEC_RX_MIDI_2ND_Q
|
346 SND_MOTU_SPEC_TX_MIDI_2ND_Q
,
347 .tx_fixed_pcm_chunks
= {14, 14, 0},
348 .rx_fixed_pcm_chunks
= {14, 14, 0},
351 const struct snd_motu_spec snd_motu_spec_8pre
= {
353 .protocol_version
= SND_MOTU_PROTOCOL_V2
,
354 .flags
= SND_MOTU_SPEC_RX_MIDI_2ND_Q
|
355 SND_MOTU_SPEC_TX_MIDI_2ND_Q
,
356 .tx_fixed_pcm_chunks
= {10, 6, 0},
357 .rx_fixed_pcm_chunks
= {10, 6, 0},