1 // SPDX-License-Identifier: GPL-2.0-only
3 * motu-stream.c - a part of driver for MOTU FireWire series
5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
10 #define CALLBACK_TIMEOUT 200
12 #define ISOC_COMM_CONTROL_OFFSET 0x0b00
13 #define ISOC_COMM_CONTROL_MASK 0xffff0000
14 #define CHANGE_RX_ISOC_COMM_STATE 0x80000000
15 #define RX_ISOC_COMM_IS_ACTIVATED 0x40000000
16 #define RX_ISOC_COMM_CHANNEL_MASK 0x3f000000
17 #define RX_ISOC_COMM_CHANNEL_SHIFT 24
18 #define CHANGE_TX_ISOC_COMM_STATE 0x00800000
19 #define TX_ISOC_COMM_IS_ACTIVATED 0x00400000
20 #define TX_ISOC_COMM_CHANNEL_MASK 0x003f0000
21 #define TX_ISOC_COMM_CHANNEL_SHIFT 16
23 #define PACKET_FORMAT_OFFSET 0x0b10
24 #define TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000080
25 #define RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000040
26 #define TX_PACKET_TRANSMISSION_SPEED_MASK 0x0000000f
28 static int start_both_streams(struct snd_motu
*motu
, unsigned int rate
)
30 unsigned int midi_ports
= 0;
35 if ((motu
->spec
->flags
& SND_MOTU_SPEC_RX_MIDI_2ND_Q
) ||
36 (motu
->spec
->flags
& SND_MOTU_SPEC_RX_MIDI_3RD_Q
))
39 /* Set packet formation to our packet streaming engine. */
40 err
= amdtp_motu_set_parameters(&motu
->rx_stream
, rate
, midi_ports
,
41 &motu
->rx_packet_formats
);
45 if ((motu
->spec
->flags
& SND_MOTU_SPEC_TX_MIDI_2ND_Q
) ||
46 (motu
->spec
->flags
& SND_MOTU_SPEC_TX_MIDI_3RD_Q
))
51 err
= amdtp_motu_set_parameters(&motu
->tx_stream
, rate
, midi_ports
,
52 &motu
->tx_packet_formats
);
56 /* Get isochronous resources on the bus. */
57 err
= fw_iso_resources_allocate(&motu
->rx_resources
,
58 amdtp_stream_get_max_payload(&motu
->rx_stream
),
59 fw_parent_device(motu
->unit
)->max_speed
);
63 err
= fw_iso_resources_allocate(&motu
->tx_resources
,
64 amdtp_stream_get_max_payload(&motu
->tx_stream
),
65 fw_parent_device(motu
->unit
)->max_speed
);
69 /* Configure the unit to start isochronous communication. */
70 err
= snd_motu_transaction_read(motu
, ISOC_COMM_CONTROL_OFFSET
, ®
,
74 data
= be32_to_cpu(reg
) & ~ISOC_COMM_CONTROL_MASK
;
76 data
|= CHANGE_RX_ISOC_COMM_STATE
| RX_ISOC_COMM_IS_ACTIVATED
|
77 (motu
->rx_resources
.channel
<< RX_ISOC_COMM_CHANNEL_SHIFT
) |
78 CHANGE_TX_ISOC_COMM_STATE
| TX_ISOC_COMM_IS_ACTIVATED
|
79 (motu
->tx_resources
.channel
<< TX_ISOC_COMM_CHANNEL_SHIFT
);
81 reg
= cpu_to_be32(data
);
82 return snd_motu_transaction_write(motu
, ISOC_COMM_CONTROL_OFFSET
, ®
,
86 static void stop_both_streams(struct snd_motu
*motu
)
92 err
= motu
->spec
->protocol
->switch_fetching_mode(motu
, false);
96 err
= snd_motu_transaction_read(motu
, ISOC_COMM_CONTROL_OFFSET
, ®
,
100 data
= be32_to_cpu(reg
);
102 data
&= ~(RX_ISOC_COMM_IS_ACTIVATED
| TX_ISOC_COMM_IS_ACTIVATED
);
103 data
|= CHANGE_RX_ISOC_COMM_STATE
| CHANGE_TX_ISOC_COMM_STATE
;
105 reg
= cpu_to_be32(data
);
106 snd_motu_transaction_write(motu
, ISOC_COMM_CONTROL_OFFSET
, ®
,
109 fw_iso_resources_free(&motu
->tx_resources
);
110 fw_iso_resources_free(&motu
->rx_resources
);
113 static int start_isoc_ctx(struct snd_motu
*motu
, struct amdtp_stream
*stream
)
115 struct fw_iso_resources
*resources
;
118 if (stream
== &motu
->rx_stream
)
119 resources
= &motu
->rx_resources
;
121 resources
= &motu
->tx_resources
;
123 err
= amdtp_stream_start(stream
, resources
->channel
,
124 fw_parent_device(motu
->unit
)->max_speed
);
128 if (!amdtp_stream_wait_callback(stream
, CALLBACK_TIMEOUT
)) {
129 amdtp_stream_stop(stream
);
130 fw_iso_resources_free(resources
);
137 static void stop_isoc_ctx(struct snd_motu
*motu
, struct amdtp_stream
*stream
)
139 struct fw_iso_resources
*resources
;
141 if (stream
== &motu
->rx_stream
)
142 resources
= &motu
->rx_resources
;
144 resources
= &motu
->tx_resources
;
146 amdtp_stream_stop(stream
);
147 fw_iso_resources_free(resources
);
150 int snd_motu_stream_cache_packet_formats(struct snd_motu
*motu
)
154 err
= motu
->spec
->protocol
->cache_packet_formats(motu
);
158 if (motu
->spec
->flags
& SND_MOTU_SPEC_TX_MIDI_2ND_Q
) {
159 motu
->tx_packet_formats
.midi_flag_offset
= 4;
160 motu
->tx_packet_formats
.midi_byte_offset
= 6;
161 } else if (motu
->spec
->flags
& SND_MOTU_SPEC_TX_MIDI_3RD_Q
) {
162 motu
->tx_packet_formats
.midi_flag_offset
= 8;
163 motu
->tx_packet_formats
.midi_byte_offset
= 7;
166 if (motu
->spec
->flags
& SND_MOTU_SPEC_RX_MIDI_2ND_Q
) {
167 motu
->rx_packet_formats
.midi_flag_offset
= 4;
168 motu
->rx_packet_formats
.midi_byte_offset
= 6;
169 } else if (motu
->spec
->flags
& SND_MOTU_SPEC_RX_MIDI_3RD_Q
) {
170 motu
->rx_packet_formats
.midi_flag_offset
= 8;
171 motu
->rx_packet_formats
.midi_byte_offset
= 7;
177 static int ensure_packet_formats(struct snd_motu
*motu
)
183 err
= snd_motu_transaction_read(motu
, PACKET_FORMAT_OFFSET
, ®
,
187 data
= be32_to_cpu(reg
);
189 data
&= ~(TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS
|
190 RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS
|
191 TX_PACKET_TRANSMISSION_SPEED_MASK
);
192 if (motu
->tx_packet_formats
.differed_part_pcm_chunks
[0] == 0)
193 data
|= TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS
;
194 if (motu
->rx_packet_formats
.differed_part_pcm_chunks
[0] == 0)
195 data
|= RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS
;
196 data
|= fw_parent_device(motu
->unit
)->max_speed
;
198 reg
= cpu_to_be32(data
);
199 return snd_motu_transaction_write(motu
, PACKET_FORMAT_OFFSET
, ®
,
203 int snd_motu_stream_start_duplex(struct snd_motu
*motu
, unsigned int rate
)
205 const struct snd_motu_protocol
*protocol
= motu
->spec
->protocol
;
206 unsigned int curr_rate
;
209 if (motu
->capture_substreams
== 0 && motu
->playback_substreams
== 0)
212 /* Some packet queueing errors. */
213 if (amdtp_streaming_error(&motu
->rx_stream
) ||
214 amdtp_streaming_error(&motu
->tx_stream
)) {
215 amdtp_stream_stop(&motu
->rx_stream
);
216 amdtp_stream_stop(&motu
->tx_stream
);
217 stop_both_streams(motu
);
220 err
= snd_motu_stream_cache_packet_formats(motu
);
224 /* Stop stream if rate is different. */
225 err
= protocol
->get_clock_rate(motu
, &curr_rate
);
227 dev_err(&motu
->unit
->device
,
228 "fail to get sampling rate: %d\n", err
);
233 if (rate
!= curr_rate
) {
234 amdtp_stream_stop(&motu
->rx_stream
);
235 amdtp_stream_stop(&motu
->tx_stream
);
236 stop_both_streams(motu
);
239 if (!amdtp_stream_running(&motu
->rx_stream
)) {
240 err
= protocol
->set_clock_rate(motu
, rate
);
242 dev_err(&motu
->unit
->device
,
243 "fail to set sampling rate: %d\n", err
);
247 err
= ensure_packet_formats(motu
);
251 err
= start_both_streams(motu
, rate
);
253 dev_err(&motu
->unit
->device
,
254 "fail to start isochronous comm: %d\n", err
);
258 err
= start_isoc_ctx(motu
, &motu
->rx_stream
);
260 dev_err(&motu
->unit
->device
,
261 "fail to start IT context: %d\n", err
);
265 err
= protocol
->switch_fetching_mode(motu
, true);
267 dev_err(&motu
->unit
->device
,
268 "fail to enable frame fetching: %d\n", err
);
273 if (!amdtp_stream_running(&motu
->tx_stream
) &&
274 motu
->capture_substreams
> 0) {
275 err
= start_isoc_ctx(motu
, &motu
->tx_stream
);
277 dev_err(&motu
->unit
->device
,
278 "fail to start IR context: %d", err
);
279 amdtp_stream_stop(&motu
->rx_stream
);
287 stop_both_streams(motu
);
291 void snd_motu_stream_stop_duplex(struct snd_motu
*motu
)
293 if (motu
->capture_substreams
== 0) {
294 if (amdtp_stream_running(&motu
->tx_stream
))
295 stop_isoc_ctx(motu
, &motu
->tx_stream
);
297 if (motu
->playback_substreams
== 0) {
298 if (amdtp_stream_running(&motu
->rx_stream
))
299 stop_isoc_ctx(motu
, &motu
->rx_stream
);
300 stop_both_streams(motu
);
305 static int init_stream(struct snd_motu
*motu
, enum amdtp_stream_direction dir
)
308 struct amdtp_stream
*stream
;
309 struct fw_iso_resources
*resources
;
311 if (dir
== AMDTP_IN_STREAM
) {
312 stream
= &motu
->tx_stream
;
313 resources
= &motu
->tx_resources
;
315 stream
= &motu
->rx_stream
;
316 resources
= &motu
->rx_resources
;
319 err
= fw_iso_resources_init(resources
, motu
->unit
);
323 err
= amdtp_motu_init(stream
, motu
->unit
, dir
, motu
->spec
->protocol
);
325 amdtp_stream_destroy(stream
);
326 fw_iso_resources_destroy(resources
);
332 static void destroy_stream(struct snd_motu
*motu
,
333 enum amdtp_stream_direction dir
)
335 struct amdtp_stream
*stream
;
336 struct fw_iso_resources
*resources
;
338 if (dir
== AMDTP_IN_STREAM
) {
339 stream
= &motu
->tx_stream
;
340 resources
= &motu
->tx_resources
;
342 stream
= &motu
->rx_stream
;
343 resources
= &motu
->rx_resources
;
346 amdtp_stream_destroy(stream
);
347 fw_iso_resources_destroy(resources
);
350 int snd_motu_stream_init_duplex(struct snd_motu
*motu
)
354 err
= init_stream(motu
, AMDTP_IN_STREAM
);
358 err
= init_stream(motu
, AMDTP_OUT_STREAM
);
360 destroy_stream(motu
, AMDTP_IN_STREAM
);
366 * This function should be called before starting streams or after stopping
369 void snd_motu_stream_destroy_duplex(struct snd_motu
*motu
)
371 destroy_stream(motu
, AMDTP_IN_STREAM
);
372 destroy_stream(motu
, AMDTP_OUT_STREAM
);
374 motu
->playback_substreams
= 0;
375 motu
->capture_substreams
= 0;
378 static void motu_lock_changed(struct snd_motu
*motu
)
380 motu
->dev_lock_changed
= true;
381 wake_up(&motu
->hwdep_wait
);
384 int snd_motu_stream_lock_try(struct snd_motu
*motu
)
388 spin_lock_irq(&motu
->lock
);
390 if (motu
->dev_lock_count
< 0) {
395 if (motu
->dev_lock_count
++ == 0)
396 motu_lock_changed(motu
);
399 spin_unlock_irq(&motu
->lock
);
403 void snd_motu_stream_lock_release(struct snd_motu
*motu
)
405 spin_lock_irq(&motu
->lock
);
407 if (WARN_ON(motu
->dev_lock_count
<= 0))
410 if (--motu
->dev_lock_count
== 0)
411 motu_lock_changed(motu
);
413 spin_unlock_irq(&motu
->lock
);