2 * Audio and Music Data Transmission Protocol (IEC 61883-6) streams
3 * with Common Isochronous Packet (IEC 61883-1) headers
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6 * Licensed under the terms of the GNU General Public License, version 2.
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/firewire.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <sound/pcm.h>
17 #define TICKS_PER_CYCLE 3072
18 #define CYCLES_PER_SECOND 8000
19 #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
21 #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */
25 #define CIP_EOH (1u << 31)
26 #define CIP_FMT_AM (0x10 << 24)
27 #define AMDTP_FDF_AM824 (0 << 19)
28 #define AMDTP_FDF_SFC_SHIFT 16
30 /* TODO: make these configurable */
31 #define INTERRUPT_INTERVAL 16
32 #define QUEUE_LENGTH 48
35 * amdtp_out_stream_init - initialize an AMDTP output stream structure
36 * @s: the AMDTP output stream to initialize
37 * @unit: the target of the stream
38 * @flags: the packet transmission method to use
40 int amdtp_out_stream_init(struct amdtp_out_stream
*s
, struct fw_unit
*unit
,
41 enum cip_out_flags flags
)
43 if (flags
!= CIP_NONBLOCKING
)
46 s
->unit
= fw_unit_get(unit
);
48 s
->context
= ERR_PTR(-1);
49 mutex_init(&s
->mutex
);
54 EXPORT_SYMBOL(amdtp_out_stream_init
);
57 * amdtp_out_stream_destroy - free stream resources
58 * @s: the AMDTP output stream to destroy
60 void amdtp_out_stream_destroy(struct amdtp_out_stream
*s
)
62 WARN_ON(!IS_ERR(s
->context
));
63 mutex_destroy(&s
->mutex
);
66 EXPORT_SYMBOL(amdtp_out_stream_destroy
);
69 * amdtp_out_stream_set_rate - set the sample rate
70 * @s: the AMDTP output stream to configure
71 * @rate: the sample rate
73 * The sample rate must be set before the stream is started, and must not be
74 * changed while the stream is running.
76 void amdtp_out_stream_set_rate(struct amdtp_out_stream
*s
, unsigned int rate
)
80 unsigned int syt_interval
;
82 [CIP_SFC_32000
] = { 32000, 8, },
83 [CIP_SFC_44100
] = { 44100, 8, },
84 [CIP_SFC_48000
] = { 48000, 8, },
85 [CIP_SFC_88200
] = { 88200, 16, },
86 [CIP_SFC_96000
] = { 96000, 16, },
87 [CIP_SFC_176400
] = { 176400, 32, },
88 [CIP_SFC_192000
] = { 192000, 32, },
92 if (WARN_ON(!IS_ERR(s
->context
)))
95 for (sfc
= 0; sfc
< ARRAY_SIZE(rate_info
); ++sfc
)
96 if (rate_info
[sfc
].rate
== rate
) {
98 s
->syt_interval
= rate_info
[sfc
].syt_interval
;
103 EXPORT_SYMBOL(amdtp_out_stream_set_rate
);
106 * amdtp_out_stream_get_max_payload - get the stream's packet size
107 * @s: the AMDTP output stream
109 * This function must not be called before the stream has been configured
110 * with amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
111 * amdtp_out_stream_set_midi().
113 unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream
*s
)
115 static const unsigned int max_data_blocks
[] = {
119 [CIP_SFC_88200
] = 12,
120 [CIP_SFC_96000
] = 12,
121 [CIP_SFC_176400
] = 23,
122 [CIP_SFC_192000
] = 24,
125 s
->data_block_quadlets
= s
->pcm_channels
;
126 s
->data_block_quadlets
+= DIV_ROUND_UP(s
->midi_ports
, 8);
128 return 8 + max_data_blocks
[s
->sfc
] * 4 * s
->data_block_quadlets
;
130 EXPORT_SYMBOL(amdtp_out_stream_get_max_payload
);
132 static void amdtp_write_s16(struct amdtp_out_stream
*s
,
133 struct snd_pcm_substream
*pcm
,
134 __be32
*buffer
, unsigned int frames
);
135 static void amdtp_write_s32(struct amdtp_out_stream
*s
,
136 struct snd_pcm_substream
*pcm
,
137 __be32
*buffer
, unsigned int frames
);
140 * amdtp_out_stream_set_pcm_format - set the PCM format
141 * @s: the AMDTP output stream to configure
142 * @format: the format of the ALSA PCM device
144 * The sample format must be set before the stream is started, and must not be
145 * changed while the stream is running.
147 void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream
*s
,
148 snd_pcm_format_t format
)
150 if (WARN_ON(!IS_ERR(s
->context
)))
157 case SNDRV_PCM_FORMAT_S16
:
158 s
->transfer_samples
= amdtp_write_s16
;
160 case SNDRV_PCM_FORMAT_S32
:
161 s
->transfer_samples
= amdtp_write_s32
;
165 EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format
);
167 static unsigned int calculate_data_blocks(struct amdtp_out_stream
*s
)
169 unsigned int phase
, data_blocks
;
171 if (!cip_sfc_is_base_44100(s
->sfc
)) {
172 /* Sample_rate / 8000 is an integer, and precomputed. */
173 data_blocks
= s
->data_block_state
;
175 phase
= s
->data_block_state
;
178 * This calculates the number of data blocks per packet so that
179 * 1) the overall rate is correct and exactly synchronized to
181 * 2) packets with a rounded-up number of blocks occur as early
182 * as possible in the sequence (to prevent underruns of the
185 if (s
->sfc
== CIP_SFC_44100
)
186 /* 6 6 5 6 5 6 5 ... */
187 data_blocks
= 5 + ((phase
& 1) ^
188 (phase
== 0 || phase
>= 40));
190 /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */
191 data_blocks
= 11 * (s
->sfc
>> 1) + (phase
== 0);
192 if (++phase
>= (80 >> (s
->sfc
>> 1)))
194 s
->data_block_state
= phase
;
200 static unsigned int calculate_syt(struct amdtp_out_stream
*s
,
203 unsigned int syt_offset
, phase
, index
, syt
;
205 if (s
->last_syt_offset
< TICKS_PER_CYCLE
) {
206 if (!cip_sfc_is_base_44100(s
->sfc
))
207 syt_offset
= s
->last_syt_offset
+ s
->syt_offset_state
;
210 * The time, in ticks, of the n'th SYT_INTERVAL sample is:
211 * n * SYT_INTERVAL * 24576000 / sample_rate
212 * Modulo TICKS_PER_CYCLE, the difference between successive
213 * elements is about 1386.23. Rounding the results of this
214 * formula to the SYT precision results in a sequence of
215 * differences that begins with:
216 * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ...
217 * This code generates _exactly_ the same sequence.
219 phase
= s
->syt_offset_state
;
221 syt_offset
= s
->last_syt_offset
;
222 syt_offset
+= 1386 + ((index
&& !(index
& 3)) ||
226 s
->syt_offset_state
= phase
;
229 syt_offset
= s
->last_syt_offset
- TICKS_PER_CYCLE
;
230 s
->last_syt_offset
= syt_offset
;
232 if (syt_offset
< TICKS_PER_CYCLE
) {
233 syt_offset
+= TRANSFER_DELAY_TICKS
- TICKS_PER_CYCLE
;
234 syt
= (cycle
+ syt_offset
/ TICKS_PER_CYCLE
) << 12;
235 syt
+= syt_offset
% TICKS_PER_CYCLE
;
239 return 0xffff; /* no info */
243 static void amdtp_write_s32(struct amdtp_out_stream
*s
,
244 struct snd_pcm_substream
*pcm
,
245 __be32
*buffer
, unsigned int frames
)
247 struct snd_pcm_runtime
*runtime
= pcm
->runtime
;
248 unsigned int channels
, remaining_frames
, frame_step
, i
, c
;
251 channels
= s
->pcm_channels
;
252 src
= (void *)runtime
->dma_area
+
253 s
->pcm_buffer_pointer
* (runtime
->frame_bits
/ 8);
254 remaining_frames
= runtime
->buffer_size
- s
->pcm_buffer_pointer
;
255 frame_step
= s
->data_block_quadlets
- channels
;
257 for (i
= 0; i
< frames
; ++i
) {
258 for (c
= 0; c
< channels
; ++c
) {
259 *buffer
= cpu_to_be32((*src
>> 8) | 0x40000000);
263 buffer
+= frame_step
;
264 if (--remaining_frames
== 0)
265 src
= (void *)runtime
->dma_area
;
269 static void amdtp_write_s16(struct amdtp_out_stream
*s
,
270 struct snd_pcm_substream
*pcm
,
271 __be32
*buffer
, unsigned int frames
)
273 struct snd_pcm_runtime
*runtime
= pcm
->runtime
;
274 unsigned int channels
, remaining_frames
, frame_step
, i
, c
;
277 channels
= s
->pcm_channels
;
278 src
= (void *)runtime
->dma_area
+
279 s
->pcm_buffer_pointer
* (runtime
->frame_bits
/ 8);
280 remaining_frames
= runtime
->buffer_size
- s
->pcm_buffer_pointer
;
281 frame_step
= s
->data_block_quadlets
- channels
;
283 for (i
= 0; i
< frames
; ++i
) {
284 for (c
= 0; c
< channels
; ++c
) {
285 *buffer
= cpu_to_be32((*src
<< 8) | 0x40000000);
289 buffer
+= frame_step
;
290 if (--remaining_frames
== 0)
291 src
= (void *)runtime
->dma_area
;
295 static void amdtp_fill_pcm_silence(struct amdtp_out_stream
*s
,
296 __be32
*buffer
, unsigned int frames
)
300 for (i
= 0; i
< frames
; ++i
) {
301 for (c
= 0; c
< s
->pcm_channels
; ++c
)
302 buffer
[c
] = cpu_to_be32(0x40000000);
303 buffer
+= s
->data_block_quadlets
;
307 static void amdtp_fill_midi(struct amdtp_out_stream
*s
,
308 __be32
*buffer
, unsigned int frames
)
312 for (i
= 0; i
< frames
; ++i
)
313 buffer
[s
->pcm_channels
+ i
* s
->data_block_quadlets
] =
314 cpu_to_be32(0x80000000);
317 static void queue_out_packet(struct amdtp_out_stream
*s
, unsigned int cycle
)
320 unsigned int index
, data_blocks
, syt
, ptr
;
321 struct snd_pcm_substream
*pcm
;
322 struct fw_iso_packet packet
;
325 if (s
->packet_index
< 0)
327 index
= s
->packet_index
;
329 data_blocks
= calculate_data_blocks(s
);
330 syt
= calculate_syt(s
, cycle
);
332 buffer
= s
->buffer
.packets
[index
].buffer
;
333 buffer
[0] = cpu_to_be32(ACCESS_ONCE(s
->source_node_id_field
) |
334 (s
->data_block_quadlets
<< 16) |
335 s
->data_block_counter
);
336 buffer
[1] = cpu_to_be32(CIP_EOH
| CIP_FMT_AM
| AMDTP_FDF_AM824
|
337 (s
->sfc
<< AMDTP_FDF_SFC_SHIFT
) | syt
);
340 pcm
= ACCESS_ONCE(s
->pcm
);
342 s
->transfer_samples(s
, pcm
, buffer
, data_blocks
);
344 amdtp_fill_pcm_silence(s
, buffer
, data_blocks
);
346 amdtp_fill_midi(s
, buffer
, data_blocks
);
348 s
->data_block_counter
= (s
->data_block_counter
+ data_blocks
) & 0xff;
350 packet
.payload_length
= 8 + data_blocks
* 4 * s
->data_block_quadlets
;
351 packet
.interrupt
= IS_ALIGNED(index
+ 1, INTERRUPT_INTERVAL
);
353 packet
.tag
= TAG_CIP
;
355 packet
.header_length
= 0;
357 err
= fw_iso_context_queue(s
->context
, &packet
, &s
->buffer
.iso_buffer
,
358 s
->buffer
.packets
[index
].offset
);
360 dev_err(&s
->unit
->device
, "queueing error: %d\n", err
);
361 s
->packet_index
= -1;
362 amdtp_out_stream_pcm_abort(s
);
366 if (++index
>= QUEUE_LENGTH
)
368 s
->packet_index
= index
;
371 ptr
= s
->pcm_buffer_pointer
+ data_blocks
;
372 if (ptr
>= pcm
->runtime
->buffer_size
)
373 ptr
-= pcm
->runtime
->buffer_size
;
374 ACCESS_ONCE(s
->pcm_buffer_pointer
) = ptr
;
376 s
->pcm_period_pointer
+= data_blocks
;
377 if (s
->pcm_period_pointer
>= pcm
->runtime
->period_size
) {
378 s
->pcm_period_pointer
-= pcm
->runtime
->period_size
;
379 snd_pcm_period_elapsed(pcm
);
384 static void out_packet_callback(struct fw_iso_context
*context
, u32 cycle
,
385 size_t header_length
, void *header
, void *data
)
387 struct amdtp_out_stream
*s
= data
;
388 unsigned int i
, packets
= header_length
/ 4;
391 * Compute the cycle of the last queued packet.
392 * (We need only the four lowest bits for the SYT, so we can ignore
393 * that bits 0-11 must wrap around at 3072.)
395 cycle
+= QUEUE_LENGTH
- packets
;
397 for (i
= 0; i
< packets
; ++i
)
398 queue_out_packet(s
, ++cycle
);
401 static int queue_initial_skip_packets(struct amdtp_out_stream
*s
)
403 struct fw_iso_packet skip_packet
= {
409 for (i
= 0; i
< QUEUE_LENGTH
; ++i
) {
410 skip_packet
.interrupt
= IS_ALIGNED(s
->packet_index
+ 1,
412 err
= fw_iso_context_queue(s
->context
, &skip_packet
, NULL
, 0);
415 if (++s
->packet_index
>= QUEUE_LENGTH
)
423 * amdtp_out_stream_start - start sending packets
424 * @s: the AMDTP output stream to start
425 * @channel: the isochronous channel on the bus
426 * @speed: firewire speed code
428 * The stream cannot be started until it has been configured with
429 * amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
430 * amdtp_out_stream_set_midi(); and it must be started before any
431 * PCM or MIDI device can be started.
433 int amdtp_out_stream_start(struct amdtp_out_stream
*s
, int channel
, int speed
)
435 static const struct {
436 unsigned int data_block
;
437 unsigned int syt_offset
;
438 } initial_state
[] = {
439 [CIP_SFC_32000
] = { 4, 3072 },
440 [CIP_SFC_48000
] = { 6, 1024 },
441 [CIP_SFC_96000
] = { 12, 1024 },
442 [CIP_SFC_192000
] = { 24, 1024 },
443 [CIP_SFC_44100
] = { 0, 67 },
444 [CIP_SFC_88200
] = { 0, 67 },
445 [CIP_SFC_176400
] = { 0, 67 },
449 mutex_lock(&s
->mutex
);
451 if (WARN_ON(!IS_ERR(s
->context
) ||
452 (!s
->pcm_channels
&& !s
->midi_ports
))) {
457 s
->data_block_state
= initial_state
[s
->sfc
].data_block
;
458 s
->syt_offset_state
= initial_state
[s
->sfc
].syt_offset
;
459 s
->last_syt_offset
= TICKS_PER_CYCLE
;
461 err
= iso_packets_buffer_init(&s
->buffer
, s
->unit
, QUEUE_LENGTH
,
462 amdtp_out_stream_get_max_payload(s
),
467 s
->context
= fw_iso_context_create(fw_parent_device(s
->unit
)->card
,
468 FW_ISO_CONTEXT_TRANSMIT
,
470 out_packet_callback
, s
);
471 if (IS_ERR(s
->context
)) {
472 err
= PTR_ERR(s
->context
);
474 dev_err(&s
->unit
->device
,
475 "no free output stream on this controller\n");
479 amdtp_out_stream_update(s
);
482 s
->data_block_counter
= 0;
483 err
= queue_initial_skip_packets(s
);
487 err
= fw_iso_context_start(s
->context
, -1, 0, 0);
491 mutex_unlock(&s
->mutex
);
496 fw_iso_context_destroy(s
->context
);
497 s
->context
= ERR_PTR(-1);
499 iso_packets_buffer_destroy(&s
->buffer
, s
->unit
);
501 mutex_unlock(&s
->mutex
);
505 EXPORT_SYMBOL(amdtp_out_stream_start
);
508 * amdtp_out_stream_update - update the stream after a bus reset
509 * @s: the AMDTP output stream
511 void amdtp_out_stream_update(struct amdtp_out_stream
*s
)
513 ACCESS_ONCE(s
->source_node_id_field
) =
514 (fw_parent_device(s
->unit
)->card
->node_id
& 0x3f) << 24;
516 EXPORT_SYMBOL(amdtp_out_stream_update
);
519 * amdtp_out_stream_stop - stop sending packets
520 * @s: the AMDTP output stream to stop
522 * All PCM and MIDI devices of the stream must be stopped before the stream
523 * itself can be stopped.
525 void amdtp_out_stream_stop(struct amdtp_out_stream
*s
)
527 mutex_lock(&s
->mutex
);
529 if (IS_ERR(s
->context
)) {
530 mutex_unlock(&s
->mutex
);
534 fw_iso_context_stop(s
->context
);
535 fw_iso_context_destroy(s
->context
);
536 s
->context
= ERR_PTR(-1);
537 iso_packets_buffer_destroy(&s
->buffer
, s
->unit
);
539 mutex_unlock(&s
->mutex
);
541 EXPORT_SYMBOL(amdtp_out_stream_stop
);
544 * amdtp_out_stream_pcm_abort - abort the running PCM device
545 * @s: the AMDTP stream about to be stopped
547 * If the isochronous stream needs to be stopped asynchronously, call this
548 * function first to stop the PCM device.
550 void amdtp_out_stream_pcm_abort(struct amdtp_out_stream
*s
)
552 struct snd_pcm_substream
*pcm
;
554 pcm
= ACCESS_ONCE(s
->pcm
);
556 snd_pcm_stream_lock_irq(pcm
);
557 if (snd_pcm_running(pcm
))
558 snd_pcm_stop(pcm
, SNDRV_PCM_STATE_XRUN
);
559 snd_pcm_stream_unlock_irq(pcm
);
562 EXPORT_SYMBOL(amdtp_out_stream_pcm_abort
);