2 * tascam-stream.c - a part of driver for TASCAM FireWire series
4 * Copyright (c) 2015 Takashi Sakamoto
6 * Licensed under the terms of the GNU General Public License, version 2.
9 #include <linux/delay.h>
12 #define CALLBACK_TIMEOUT 500
14 static int get_clock(struct snd_tscm
*tscm
, u32
*data
)
19 err
= snd_fw_transaction(tscm
->unit
, TCODE_READ_QUADLET_REQUEST
,
20 TSCM_ADDR_BASE
+ TSCM_OFFSET_CLOCK_STATUS
,
21 ®
, sizeof(reg
), 0);
23 *data
= be32_to_cpu(reg
);
28 static int set_clock(struct snd_tscm
*tscm
, unsigned int rate
,
29 enum snd_tscm_clock clock
)
35 err
= get_clock(tscm
, &data
);
43 if ((rate
% 44100) == 0) {
46 if (rate
/ 44100 == 2)
48 } else if ((rate
% 48000) == 0) {
51 if (rate
/ 48000 == 2)
58 if (clock
!= INT_MAX
) {
63 reg
= cpu_to_be32(data
);
65 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
66 TSCM_ADDR_BASE
+ TSCM_OFFSET_CLOCK_STATUS
,
67 ®
, sizeof(reg
), 0);
71 if (data
& 0x00008000)
72 reg
= cpu_to_be32(0x0000001a);
74 reg
= cpu_to_be32(0x0000000d);
76 return snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
77 TSCM_ADDR_BASE
+ TSCM_OFFSET_MULTIPLEX_MODE
,
78 ®
, sizeof(reg
), 0);
81 int snd_tscm_stream_get_rate(struct snd_tscm
*tscm
, unsigned int *rate
)
84 unsigned int trials
= 0;
87 while (data
== 0x0 || trials
++ < 5) {
88 err
= get_clock(tscm
, &data
);
92 data
= (data
& 0xff000000) >> 24;
95 /* Check base rate. */
96 if ((data
& 0x0f) == 0x01)
98 else if ((data
& 0x0f) == 0x02)
103 /* Check multiplier. */
104 if ((data
& 0xf0) == 0x80)
106 else if ((data
& 0xf0) != 0x00)
112 int snd_tscm_stream_get_clock(struct snd_tscm
*tscm
, enum snd_tscm_clock
*clock
)
117 err
= get_clock(tscm
, &data
);
121 *clock
= ((data
& 0x00ff0000) >> 16) - 1;
122 if (*clock
< 0 || *clock
> SND_TSCM_CLOCK_ADAT
)
128 static int enable_data_channels(struct snd_tscm
*tscm
)
136 for (i
= 0; i
< tscm
->spec
->pcm_capture_analog_channels
; ++i
)
138 if (tscm
->spec
->has_adat
)
140 if (tscm
->spec
->has_spdif
)
143 reg
= cpu_to_be32(data
);
144 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
145 TSCM_ADDR_BASE
+ TSCM_OFFSET_TX_PCM_CHANNELS
,
146 ®
, sizeof(reg
), 0);
151 for (i
= 0; i
< tscm
->spec
->pcm_playback_analog_channels
; ++i
)
153 if (tscm
->spec
->has_adat
)
155 if (tscm
->spec
->has_spdif
)
158 reg
= cpu_to_be32(data
);
159 return snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
160 TSCM_ADDR_BASE
+ TSCM_OFFSET_RX_PCM_CHANNELS
,
161 ®
, sizeof(reg
), 0);
164 static int set_stream_formats(struct snd_tscm
*tscm
, unsigned int rate
)
169 /* Set an option for unknown purpose. */
170 reg
= cpu_to_be32(0x00200000);
171 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
172 TSCM_ADDR_BASE
+ TSCM_OFFSET_SET_OPTION
,
173 ®
, sizeof(reg
), 0);
177 err
= enable_data_channels(tscm
);
181 return set_clock(tscm
, rate
, INT_MAX
);
184 static void finish_session(struct snd_tscm
*tscm
)
189 snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
190 TSCM_ADDR_BASE
+ TSCM_OFFSET_START_STREAMING
,
191 ®
, sizeof(reg
), 0);
194 snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
195 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_RX_ON
,
196 ®
, sizeof(reg
), 0);
200 static int begin_session(struct snd_tscm
*tscm
)
205 reg
= cpu_to_be32(0x00000001);
206 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
207 TSCM_ADDR_BASE
+ TSCM_OFFSET_START_STREAMING
,
208 ®
, sizeof(reg
), 0);
212 reg
= cpu_to_be32(0x00000001);
213 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
214 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_RX_ON
,
215 ®
, sizeof(reg
), 0);
219 /* Set an option for unknown purpose. */
220 reg
= cpu_to_be32(0x00002000);
221 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
222 TSCM_ADDR_BASE
+ TSCM_OFFSET_SET_OPTION
,
223 ®
, sizeof(reg
), 0);
227 /* Start multiplexing PCM samples on packets. */
228 reg
= cpu_to_be32(0x00000001);
229 return snd_fw_transaction(tscm
->unit
,
230 TCODE_WRITE_QUADLET_REQUEST
,
231 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_TX_ON
,
232 ®
, sizeof(reg
), 0);
235 static void release_resources(struct snd_tscm
*tscm
)
239 /* Unregister channels. */
240 reg
= cpu_to_be32(0x00000000);
241 snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
242 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_TX_CH
,
243 ®
, sizeof(reg
), 0);
244 reg
= cpu_to_be32(0x00000000);
245 snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
246 TSCM_ADDR_BASE
+ TSCM_OFFSET_UNKNOWN
,
247 ®
, sizeof(reg
), 0);
248 reg
= cpu_to_be32(0x00000000);
249 snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
250 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_RX_CH
,
251 ®
, sizeof(reg
), 0);
253 /* Release isochronous resources. */
254 fw_iso_resources_free(&tscm
->tx_resources
);
255 fw_iso_resources_free(&tscm
->rx_resources
);
258 static int keep_resources(struct snd_tscm
*tscm
, unsigned int rate
)
263 /* Keep resources for in-stream. */
264 err
= amdtp_tscm_set_parameters(&tscm
->tx_stream
, rate
);
267 err
= fw_iso_resources_allocate(&tscm
->tx_resources
,
268 amdtp_stream_get_max_payload(&tscm
->tx_stream
),
269 fw_parent_device(tscm
->unit
)->max_speed
);
273 /* Keep resources for out-stream. */
274 err
= amdtp_tscm_set_parameters(&tscm
->rx_stream
, rate
);
277 err
= fw_iso_resources_allocate(&tscm
->rx_resources
,
278 amdtp_stream_get_max_payload(&tscm
->rx_stream
),
279 fw_parent_device(tscm
->unit
)->max_speed
);
283 /* Register the isochronous channel for transmitting stream. */
284 reg
= cpu_to_be32(tscm
->tx_resources
.channel
);
285 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
286 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_TX_CH
,
287 ®
, sizeof(reg
), 0);
292 reg
= cpu_to_be32(0x00000002);
293 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
294 TSCM_ADDR_BASE
+ TSCM_OFFSET_UNKNOWN
,
295 ®
, sizeof(reg
), 0);
299 /* Register the isochronous channel for receiving stream. */
300 reg
= cpu_to_be32(tscm
->rx_resources
.channel
);
301 err
= snd_fw_transaction(tscm
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
302 TSCM_ADDR_BASE
+ TSCM_OFFSET_ISOC_RX_CH
,
303 ®
, sizeof(reg
), 0);
309 release_resources(tscm
);
313 int snd_tscm_stream_init_duplex(struct snd_tscm
*tscm
)
315 unsigned int pcm_channels
;
318 /* For out-stream. */
319 err
= fw_iso_resources_init(&tscm
->rx_resources
, tscm
->unit
);
322 pcm_channels
= tscm
->spec
->pcm_playback_analog_channels
;
323 if (tscm
->spec
->has_adat
)
325 if (tscm
->spec
->has_spdif
)
327 err
= amdtp_tscm_init(&tscm
->rx_stream
, tscm
->unit
, AMDTP_OUT_STREAM
,
333 err
= fw_iso_resources_init(&tscm
->tx_resources
, tscm
->unit
);
336 pcm_channels
= tscm
->spec
->pcm_capture_analog_channels
;
337 if (tscm
->spec
->has_adat
)
339 if (tscm
->spec
->has_spdif
)
341 err
= amdtp_tscm_init(&tscm
->tx_stream
, tscm
->unit
, AMDTP_IN_STREAM
,
344 amdtp_stream_destroy(&tscm
->rx_stream
);
349 /* At bus reset, streaming is stopped and some registers are clear. */
350 void snd_tscm_stream_update_duplex(struct snd_tscm
*tscm
)
352 amdtp_stream_pcm_abort(&tscm
->tx_stream
);
353 amdtp_stream_stop(&tscm
->tx_stream
);
355 amdtp_stream_pcm_abort(&tscm
->rx_stream
);
356 amdtp_stream_stop(&tscm
->rx_stream
);
360 * This function should be called before starting streams or after stopping
363 void snd_tscm_stream_destroy_duplex(struct snd_tscm
*tscm
)
365 amdtp_stream_destroy(&tscm
->rx_stream
);
366 amdtp_stream_destroy(&tscm
->tx_stream
);
368 fw_iso_resources_destroy(&tscm
->rx_resources
);
369 fw_iso_resources_destroy(&tscm
->tx_resources
);
372 int snd_tscm_stream_start_duplex(struct snd_tscm
*tscm
, unsigned int rate
)
374 unsigned int curr_rate
;
377 if (tscm
->substreams_counter
== 0)
380 err
= snd_tscm_stream_get_rate(tscm
, &curr_rate
);
383 if (curr_rate
!= rate
||
384 amdtp_streaming_error(&tscm
->rx_stream
) ||
385 amdtp_streaming_error(&tscm
->tx_stream
)) {
386 finish_session(tscm
);
388 amdtp_stream_stop(&tscm
->rx_stream
);
389 amdtp_stream_stop(&tscm
->tx_stream
);
391 release_resources(tscm
);
394 if (!amdtp_stream_running(&tscm
->rx_stream
)) {
395 err
= keep_resources(tscm
, rate
);
399 err
= set_stream_formats(tscm
, rate
);
403 err
= begin_session(tscm
);
407 err
= amdtp_stream_start(&tscm
->rx_stream
,
408 tscm
->rx_resources
.channel
,
409 fw_parent_device(tscm
->unit
)->max_speed
);
413 if (!amdtp_stream_wait_callback(&tscm
->rx_stream
,
420 if (!amdtp_stream_running(&tscm
->tx_stream
)) {
421 err
= amdtp_stream_start(&tscm
->tx_stream
,
422 tscm
->tx_resources
.channel
,
423 fw_parent_device(tscm
->unit
)->max_speed
);
427 if (!amdtp_stream_wait_callback(&tscm
->tx_stream
,
436 amdtp_stream_stop(&tscm
->rx_stream
);
437 amdtp_stream_stop(&tscm
->tx_stream
);
439 finish_session(tscm
);
440 release_resources(tscm
);
445 void snd_tscm_stream_stop_duplex(struct snd_tscm
*tscm
)
447 if (tscm
->substreams_counter
> 0)
450 amdtp_stream_stop(&tscm
->tx_stream
);
451 amdtp_stream_stop(&tscm
->rx_stream
);
453 finish_session(tscm
);
454 release_resources(tscm
);
457 void snd_tscm_stream_lock_changed(struct snd_tscm
*tscm
)
459 tscm
->dev_lock_changed
= true;
460 wake_up(&tscm
->hwdep_wait
);
463 int snd_tscm_stream_lock_try(struct snd_tscm
*tscm
)
467 spin_lock_irq(&tscm
->lock
);
469 /* user land lock this */
470 if (tscm
->dev_lock_count
< 0) {
475 /* this is the first time */
476 if (tscm
->dev_lock_count
++ == 0)
477 snd_tscm_stream_lock_changed(tscm
);
480 spin_unlock_irq(&tscm
->lock
);
484 void snd_tscm_stream_lock_release(struct snd_tscm
*tscm
)
486 spin_lock_irq(&tscm
->lock
);
488 if (WARN_ON(tscm
->dev_lock_count
<= 0))
490 if (--tscm
->dev_lock_count
== 0)
491 snd_tscm_stream_lock_changed(tscm
);
493 spin_unlock_irq(&tscm
->lock
);