aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2015-09-18 22:22:02 -0400
committerTakashi Iwai <tiwai@suse.de>2015-09-29 06:51:20 -0400
commitdf075feefbd347f13fba5198294cda619532c237 (patch)
tree6fbde961132507f27c5fde6f5693139e6ac37ee4
parent49c7b3fcd9f0a0125e8cd8212d5576382198eeb2 (diff)
ALSA: firewire-lib: complete AM824 data block processing layer
This commit moves the codes related to data block processing from packet streaming layer to AM824 layer. Each driver initializes amdtp stream structure for AM824 data block by calling amdtp_am824_init(). Then, a memory block is allocated for AM824 specific structure. This memory block is released by calling amdtp_stream_destroy(). When setting streaming parameters, it calls amdtp_am824_set_parameters(). When starting packet streaming, it calls amdtp_stream_start(). When stopping packet streaming, it calls amdtp_stream_stop(). Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/firewire/amdtp-am824.c349
-rw-r--r--sound/firewire/amdtp-am824.h24
-rw-r--r--sound/firewire/amdtp-stream.c316
-rw-r--r--sound/firewire/amdtp-stream.h62
4 files changed, 401 insertions, 350 deletions
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c
index 540a101661e2..fe4b83f65831 100644
--- a/sound/firewire/amdtp-am824.c
+++ b/sound/firewire/amdtp-am824.c
@@ -1,11 +1,14 @@
1/* 1/*
2 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6) 2 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
4 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 * 6 *
6 * Licensed under the terms of the GNU General Public License, version 2. 7 * Licensed under the terms of the GNU General Public License, version 2.
7 */ 8 */
8 9
10#include <linux/slab.h>
11
9#include "amdtp-am824.h" 12#include "amdtp-am824.h"
10 13
11#define CIP_FMT_AM 0x10 14#define CIP_FMT_AM 0x10
@@ -13,6 +16,35 @@
13/* "Clock-based rate control mode" is just supported. */ 16/* "Clock-based rate control mode" is just supported. */
14#define AMDTP_FDF_AM824 0x00 17#define AMDTP_FDF_AM824 0x00
15 18
19/*
20 * Nominally 3125 bytes/second, but the MIDI port's clock might be
21 * 1% too slow, and the bus clock 100 ppm too fast.
22 */
23#define MIDI_BYTES_PER_SECOND 3093
24
25/*
26 * Several devices look only at the first eight data blocks.
27 * In any case, this is more than enough for the MIDI data rate.
28 */
29#define MAX_MIDI_RX_BLOCKS 8
30
31struct amdtp_am824 {
32 struct snd_rawmidi_substream *midi[AM824_MAX_CHANNELS_FOR_MIDI * 8];
33 int midi_fifo_limit;
34 int midi_fifo_used[AM824_MAX_CHANNELS_FOR_MIDI * 8];
35 unsigned int pcm_channels;
36 unsigned int midi_ports;
37
38 u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM];
39 u8 midi_position;
40
41 void (*transfer_samples)(struct amdtp_stream *s,
42 struct snd_pcm_substream *pcm,
43 __be32 *buffer, unsigned int frames);
44
45 unsigned int frame_multiplier;
46};
47
16/** 48/**
17 * amdtp_am824_set_parameters - set stream parameters 49 * amdtp_am824_set_parameters - set stream parameters
18 * @s: the AMDTP stream to configure 50 * @s: the AMDTP stream to configure
@@ -30,23 +62,58 @@ int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
30 unsigned int midi_ports, 62 unsigned int midi_ports,
31 bool double_pcm_frames) 63 bool double_pcm_frames)
32{ 64{
65 struct amdtp_am824 *p = s->protocol;
66 unsigned int midi_channels;
67 unsigned int i;
33 int err; 68 int err;
34 69
35 err = amdtp_stream_set_parameters(s, rate, pcm_channels, midi_ports); 70 if (amdtp_stream_running(s))
71 return -EINVAL;
72
73 if (pcm_channels > AM824_MAX_CHANNELS_FOR_PCM)
74 return -EINVAL;
75
76 midi_channels = DIV_ROUND_UP(midi_ports, 8);
77 if (midi_channels > AM824_MAX_CHANNELS_FOR_MIDI)
78 return -EINVAL;
79
80 if (WARN_ON(amdtp_stream_running(s)) ||
81 WARN_ON(pcm_channels > AM824_MAX_CHANNELS_FOR_PCM) ||
82 WARN_ON(midi_channels > AM824_MAX_CHANNELS_FOR_MIDI))
83 return -EINVAL;
84
85 err = amdtp_stream_set_parameters(s, rate,
86 pcm_channels + midi_channels);
36 if (err < 0) 87 if (err < 0)
37 return err; 88 return err;
38 89
39 s->fdf = AMDTP_FDF_AM824 | s->sfc; 90 s->fdf = AMDTP_FDF_AM824 | s->sfc;
40 91
92 p->pcm_channels = pcm_channels;
93 p->midi_ports = midi_ports;
94
41 /* 95 /*
42 * In IEC 61883-6, one data block represents one event. In ALSA, one 96 * In IEC 61883-6, one data block represents one event. In ALSA, one
43 * event equals to one PCM frame. But Dice has a quirk at higher 97 * event equals to one PCM frame. But Dice has a quirk at higher
44 * sampling rate to transfer two PCM frames in one data block. 98 * sampling rate to transfer two PCM frames in one data block.
45 */ 99 */
46 if (double_pcm_frames) 100 if (double_pcm_frames)
47 s->frame_multiplier = 2; 101 p->frame_multiplier = 2;
48 else 102 else
49 s->frame_multiplier = 1; 103 p->frame_multiplier = 1;
104
105 /* init the position map for PCM and MIDI channels */
106 for (i = 0; i < pcm_channels; i++)
107 p->pcm_positions[i] = i;
108 p->midi_position = p->pcm_channels;
109
110 /*
111 * We do not know the actual MIDI FIFO size of most devices. Just
112 * assume two bytes, i.e., one byte can be received over the bus while
113 * the previous one is transmitted over MIDI.
114 * (The value here is adjusted for midi_ratelimit_per_packet().)
115 */
116 p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
50 117
51 return 0; 118 return 0;
52} 119}
@@ -62,8 +129,10 @@ EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters);
62void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index, 129void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
63 unsigned int position) 130 unsigned int position)
64{ 131{
65 if (index < s->pcm_channels) 132 struct amdtp_am824 *p = s->protocol;
66 s->pcm_positions[index] = position; 133
134 if (index < p->pcm_channels)
135 p->pcm_positions[index] = position;
67} 136}
68EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position); 137EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
69 138
@@ -76,10 +145,139 @@ EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
76void amdtp_am824_set_midi_position(struct amdtp_stream *s, 145void amdtp_am824_set_midi_position(struct amdtp_stream *s,
77 unsigned int position) 146 unsigned int position)
78{ 147{
79 s->midi_position = position; 148 struct amdtp_am824 *p = s->protocol;
149
150 p->midi_position = position;
80} 151}
81EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position); 152EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
82 153
154static void write_pcm_s32(struct amdtp_stream *s,
155 struct snd_pcm_substream *pcm,
156 __be32 *buffer, unsigned int frames)
157{
158 struct amdtp_am824 *p = s->protocol;
159 struct snd_pcm_runtime *runtime = pcm->runtime;
160 unsigned int channels, remaining_frames, i, c;
161 const u32 *src;
162
163 channels = p->pcm_channels;
164 src = (void *)runtime->dma_area +
165 frames_to_bytes(runtime, s->pcm_buffer_pointer);
166 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
167
168 for (i = 0; i < frames; ++i) {
169 for (c = 0; c < channels; ++c) {
170 buffer[p->pcm_positions[c]] =
171 cpu_to_be32((*src >> 8) | 0x40000000);
172 src++;
173 }
174 buffer += s->data_block_quadlets;
175 if (--remaining_frames == 0)
176 src = (void *)runtime->dma_area;
177 }
178}
179
180static void write_pcm_s16(struct amdtp_stream *s,
181 struct snd_pcm_substream *pcm,
182 __be32 *buffer, unsigned int frames)
183{
184 struct amdtp_am824 *p = s->protocol;
185 struct snd_pcm_runtime *runtime = pcm->runtime;
186 unsigned int channels, remaining_frames, i, c;
187 const u16 *src;
188
189 channels = p->pcm_channels;
190 src = (void *)runtime->dma_area +
191 frames_to_bytes(runtime, s->pcm_buffer_pointer);
192 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
193
194 for (i = 0; i < frames; ++i) {
195 for (c = 0; c < channels; ++c) {
196 buffer[p->pcm_positions[c]] =
197 cpu_to_be32((*src << 8) | 0x42000000);
198 src++;
199 }
200 buffer += s->data_block_quadlets;
201 if (--remaining_frames == 0)
202 src = (void *)runtime->dma_area;
203 }
204}
205
206static void read_pcm_s32(struct amdtp_stream *s,
207 struct snd_pcm_substream *pcm,
208 __be32 *buffer, unsigned int frames)
209{
210 struct amdtp_am824 *p = s->protocol;
211 struct snd_pcm_runtime *runtime = pcm->runtime;
212 unsigned int channels, remaining_frames, i, c;
213 u32 *dst;
214
215 channels = p->pcm_channels;
216 dst = (void *)runtime->dma_area +
217 frames_to_bytes(runtime, s->pcm_buffer_pointer);
218 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
219
220 for (i = 0; i < frames; ++i) {
221 for (c = 0; c < channels; ++c) {
222 *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8;
223 dst++;
224 }
225 buffer += s->data_block_quadlets;
226 if (--remaining_frames == 0)
227 dst = (void *)runtime->dma_area;
228 }
229}
230
231static void write_pcm_silence(struct amdtp_stream *s,
232 __be32 *buffer, unsigned int frames)
233{
234 struct amdtp_am824 *p = s->protocol;
235 unsigned int i, c, channels = p->pcm_channels;
236
237 for (i = 0; i < frames; ++i) {
238 for (c = 0; c < channels; ++c)
239 buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000);
240 buffer += s->data_block_quadlets;
241 }
242}
243
244/**
245 * amdtp_am824_set_pcm_format - set the PCM format
246 * @s: the AMDTP stream to configure
247 * @format: the format of the ALSA PCM device
248 *
249 * The sample format must be set after the other parameters (rate/PCM channels/
250 * MIDI) and before the stream is started, and must not be changed while the
251 * stream is running.
252 */
253void amdtp_am824_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format)
254{
255 struct amdtp_am824 *p = s->protocol;
256
257 if (WARN_ON(amdtp_stream_pcm_running(s)))
258 return;
259
260 switch (format) {
261 default:
262 WARN_ON(1);
263 /* fall through */
264 case SNDRV_PCM_FORMAT_S16:
265 if (s->direction == AMDTP_OUT_STREAM) {
266 p->transfer_samples = write_pcm_s16;
267 break;
268 }
269 WARN_ON(1);
270 /* fall through */
271 case SNDRV_PCM_FORMAT_S32:
272 if (s->direction == AMDTP_OUT_STREAM)
273 p->transfer_samples = write_pcm_s32;
274 else
275 p->transfer_samples = read_pcm_s32;
276 break;
277 }
278}
279EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_format);
280
83/** 281/**
84 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream 282 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
85 * @s: the AMDTP stream for AM824 data block, must be initialized. 283 * @s: the AMDTP stream for AM824 data block, must be initialized.
@@ -113,11 +311,135 @@ EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints);
113void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port, 311void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
114 struct snd_rawmidi_substream *midi) 312 struct snd_rawmidi_substream *midi)
115{ 313{
116 if (port < s->midi_ports) 314 struct amdtp_am824 *p = s->protocol;
117 ACCESS_ONCE(s->midi[port]) = midi; 315
316 if (port < p->midi_ports)
317 ACCESS_ONCE(p->midi[port]) = midi;
118} 318}
119EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger); 319EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger);
120 320
321/*
322 * To avoid sending MIDI bytes at too high a rate, assume that the receiving
323 * device has a FIFO, and track how much it is filled. This values increases
324 * by one whenever we send one byte in a packet, but the FIFO empties at
325 * a constant rate independent of our packet rate. One packet has syt_interval
326 * samples, so the number of bytes that empty out of the FIFO, per packet(!),
327 * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing
328 * fractional values, the values in midi_fifo_used[] are measured in bytes
329 * multiplied by the sample rate.
330 */
331static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
332{
333 struct amdtp_am824 *p = s->protocol;
334 int used;
335
336 used = p->midi_fifo_used[port];
337 if (used == 0) /* common shortcut */
338 return true;
339
340 used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
341 used = max(used, 0);
342 p->midi_fifo_used[port] = used;
343
344 return used < p->midi_fifo_limit;
345}
346
347static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
348{
349 struct amdtp_am824 *p = s->protocol;
350
351 p->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
352}
353
354static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
355 unsigned int frames)
356{
357 struct amdtp_am824 *p = s->protocol;
358 unsigned int f, port;
359 u8 *b;
360
361 for (f = 0; f < frames; f++) {
362 b = (u8 *)&buffer[p->midi_position];
363
364 port = (s->data_block_counter + f) % 8;
365 if (f < MAX_MIDI_RX_BLOCKS &&
366 midi_ratelimit_per_packet(s, port) &&
367 p->midi[port] != NULL &&
368 snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) {
369 midi_rate_use_one_byte(s, port);
370 b[0] = 0x81;
371 } else {
372 b[0] = 0x80;
373 b[1] = 0;
374 }
375 b[2] = 0;
376 b[3] = 0;
377
378 buffer += s->data_block_quadlets;
379 }
380}
381
382static void read_midi_messages(struct amdtp_stream *s,
383 __be32 *buffer, unsigned int frames)
384{
385 struct amdtp_am824 *p = s->protocol;
386 unsigned int f, port;
387 int len;
388 u8 *b;
389
390 for (f = 0; f < frames; f++) {
391 port = (s->data_block_counter + f) % 8;
392 b = (u8 *)&buffer[p->midi_position];
393
394 len = b[0] - 0x80;
395 if ((1 <= len) && (len <= 3) && (p->midi[port]))
396 snd_rawmidi_receive(p->midi[port], b + 1, len);
397
398 buffer += s->data_block_quadlets;
399 }
400}
401
402unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
403 unsigned int data_blocks, unsigned int *syt)
404{
405 struct amdtp_am824 *p = s->protocol;
406 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
407 unsigned int pcm_frames;
408
409 if (pcm) {
410 p->transfer_samples(s, pcm, buffer, data_blocks);
411 pcm_frames = data_blocks * p->frame_multiplier;
412 } else {
413 write_pcm_silence(s, buffer, data_blocks);
414 pcm_frames = 0;
415 }
416
417 if (p->midi_ports)
418 write_midi_messages(s, buffer, data_blocks);
419
420 return pcm_frames;
421}
422
423unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
424 unsigned int data_blocks, unsigned int *syt)
425{
426 struct amdtp_am824 *p = s->protocol;
427 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
428 unsigned int pcm_frames;
429
430 if (pcm) {
431 p->transfer_samples(s, pcm, buffer, data_blocks);
432 pcm_frames = data_blocks * p->frame_multiplier;
433 } else {
434 pcm_frames = 0;
435 }
436
437 if (p->midi_ports)
438 read_midi_messages(s, buffer, data_blocks);
439
440 return pcm_frames;
441}
442
121/** 443/**
122 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824 444 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
123 * data block 445 * data block
@@ -129,6 +451,15 @@ EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger);
129int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit, 451int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
130 enum amdtp_stream_direction dir, enum cip_flags flags) 452 enum amdtp_stream_direction dir, enum cip_flags flags)
131{ 453{
132 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM); 454 amdtp_stream_process_data_blocks_t process_data_blocks;
455
456 if (dir == AMDTP_IN_STREAM)
457 process_data_blocks = process_tx_data_blocks;
458 else
459 process_data_blocks = process_rx_data_blocks;
460
461 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
462 process_data_blocks,
463 sizeof(struct amdtp_am824));
133} 464}
134EXPORT_SYMBOL_GPL(amdtp_am824_init); 465EXPORT_SYMBOL_GPL(amdtp_am824_init);
diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h
index 65e6093a4460..73b07b3109db 100644
--- a/sound/firewire/amdtp-am824.h
+++ b/sound/firewire/amdtp-am824.h
@@ -6,6 +6,27 @@
6 6
7#include "amdtp-stream.h" 7#include "amdtp-stream.h"
8 8
9#define AM824_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32
10
11#define AM824_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
12 SNDRV_PCM_FMTBIT_S32)
13
14/*
15 * This module supports maximum 64 PCM channels for one PCM stream
16 * This is for our convenience.
17 */
18#define AM824_MAX_CHANNELS_FOR_PCM 64
19
20/*
21 * AMDTP packet can include channels for MIDI conformant data.
22 * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
23 * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
24 *
25 * This module supports maximum 1 MIDI conformant data channels.
26 * Then this AMDTP packets can transfer maximum 8 MIDI data streams.
27 */
28#define AM824_MAX_CHANNELS_FOR_MIDI 1
29
9int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate, 30int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
10 unsigned int pcm_channels, 31 unsigned int pcm_channels,
11 unsigned int midi_ports, 32 unsigned int midi_ports,
@@ -20,6 +41,9 @@ void amdtp_am824_set_midi_position(struct amdtp_stream *s,
20int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s, 41int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
21 struct snd_pcm_runtime *runtime); 42 struct snd_pcm_runtime *runtime);
22 43
44void amdtp_am824_set_pcm_format(struct amdtp_stream *s,
45 snd_pcm_format_t format);
46
23void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port, 47void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
24 struct snd_rawmidi_substream *midi); 48 struct snd_rawmidi_substream *midi);
25 49
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index c61e0ec5c0f5..fa10b58a0957 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -13,25 +13,12 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <sound/pcm.h> 14#include <sound/pcm.h>
15#include <sound/pcm_params.h> 15#include <sound/pcm_params.h>
16#include <sound/rawmidi.h>
17#include "amdtp-stream.h" 16#include "amdtp-stream.h"
18 17
19#define TICKS_PER_CYCLE 3072 18#define TICKS_PER_CYCLE 3072
20#define CYCLES_PER_SECOND 8000 19#define CYCLES_PER_SECOND 8000
21#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) 20#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
22 21
23/*
24 * Nominally 3125 bytes/second, but the MIDI port's clock might be
25 * 1% too slow, and the bus clock 100 ppm too fast.
26 */
27#define MIDI_BYTES_PER_SECOND 3093
28
29/*
30 * Several devices look only at the first eight data blocks.
31 * In any case, this is more than enough for the MIDI data rate.
32 */
33#define MAX_MIDI_RX_BLOCKS 8
34
35#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ 22#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */
36 23
37/* isochronous header parameters */ 24/* isochronous header parameters */
@@ -74,11 +61,22 @@ static void pcm_period_tasklet(unsigned long data);
74 * @dir: the direction of stream 61 * @dir: the direction of stream
75 * @flags: the packet transmission method to use 62 * @flags: the packet transmission method to use
76 * @fmt: the value of fmt field in CIP header 63 * @fmt: the value of fmt field in CIP header
64 * @process_data_blocks: callback handler to process data blocks
65 * @protocol_size: the size to allocate newly for protocol
77 */ 66 */
78int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 67int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
79 enum amdtp_stream_direction dir, enum cip_flags flags, 68 enum amdtp_stream_direction dir, enum cip_flags flags,
80 unsigned int fmt) 69 unsigned int fmt,
70 amdtp_stream_process_data_blocks_t process_data_blocks,
71 unsigned int protocol_size)
81{ 72{
73 if (process_data_blocks == NULL)
74 return -EINVAL;
75
76 s->protocol = kzalloc(protocol_size, GFP_KERNEL);
77 if (!s->protocol)
78 return -ENOMEM;
79
82 s->unit = unit; 80 s->unit = unit;
83 s->direction = dir; 81 s->direction = dir;
84 s->flags = flags; 82 s->flags = flags;
@@ -92,6 +90,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
92 s->sync_slave = NULL; 90 s->sync_slave = NULL;
93 91
94 s->fmt = fmt; 92 s->fmt = fmt;
93 s->process_data_blocks = process_data_blocks;
95 94
96 return 0; 95 return 0;
97} 96}
@@ -104,6 +103,7 @@ EXPORT_SYMBOL(amdtp_stream_init);
104void amdtp_stream_destroy(struct amdtp_stream *s) 103void amdtp_stream_destroy(struct amdtp_stream *s)
105{ 104{
106 WARN_ON(amdtp_stream_running(s)); 105 WARN_ON(amdtp_stream_running(s));
106 kfree(s->protocol);
107 mutex_destroy(&s->mutex); 107 mutex_destroy(&s->mutex);
108} 108}
109EXPORT_SYMBOL(amdtp_stream_destroy); 109EXPORT_SYMBOL(amdtp_stream_destroy);
@@ -184,27 +184,15 @@ EXPORT_SYMBOL(amdtp_stream_add_pcm_hw_constraints);
184 * amdtp_stream_set_parameters - set stream parameters 184 * amdtp_stream_set_parameters - set stream parameters
185 * @s: the AMDTP stream to configure 185 * @s: the AMDTP stream to configure
186 * @rate: the sample rate 186 * @rate: the sample rate
187 * @pcm_channels: the number of PCM samples in each data block, to be encoded 187 * @data_block_quadlets: the size of a data block in quadlet unit
188 * as AM824 multi-bit linear audio
189 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
190 * @double_pcm_frames: one data block transfers two PCM frames
191 * 188 *
192 * The parameters must be set before the stream is started, and must not be 189 * The parameters must be set before the stream is started, and must not be
193 * changed while the stream is running. 190 * changed while the stream is running.
194 */ 191 */
195int amdtp_stream_set_parameters(struct amdtp_stream *s, 192int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
196 unsigned int rate, 193 unsigned int data_block_quadlets)
197 unsigned int pcm_channels,
198 unsigned int midi_ports)
199{ 194{
200 unsigned int i, sfc, midi_channels; 195 unsigned int sfc;
201
202 midi_channels = DIV_ROUND_UP(midi_ports, 8);
203
204 if (WARN_ON(amdtp_stream_running(s)) ||
205 WARN_ON(pcm_channels > AM824_MAX_CHANNELS_FOR_PCM) ||
206 WARN_ON(midi_channels > AM824_MAX_CHANNELS_FOR_MIDI))
207 return -EINVAL;
208 196
209 for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) { 197 for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) {
210 if (amdtp_rate_table[sfc] == rate) 198 if (amdtp_rate_table[sfc] == rate)
@@ -213,11 +201,8 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s,
213 if (sfc == ARRAY_SIZE(amdtp_rate_table)) 201 if (sfc == ARRAY_SIZE(amdtp_rate_table))
214 return -EINVAL; 202 return -EINVAL;
215 203
216 s->pcm_channels = pcm_channels;
217 s->sfc = sfc; 204 s->sfc = sfc;
218 s->data_block_quadlets = s->pcm_channels + midi_channels; 205 s->data_block_quadlets = data_block_quadlets;
219 s->midi_ports = midi_ports;
220
221 s->syt_interval = amdtp_syt_intervals[sfc]; 206 s->syt_interval = amdtp_syt_intervals[sfc];
222 207
223 /* default buffering in the device */ 208 /* default buffering in the device */
@@ -226,19 +211,6 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s,
226 /* additional buffering needed to adjust for no-data packets */ 211 /* additional buffering needed to adjust for no-data packets */
227 s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate; 212 s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate;
228 213
229 /* init the position map for PCM and MIDI channels */
230 for (i = 0; i < pcm_channels; i++)
231 s->pcm_positions[i] = i;
232 s->midi_position = s->pcm_channels;
233
234 /*
235 * We do not know the actual MIDI FIFO size of most devices. Just
236 * assume two bytes, i.e., one byte can be received over the bus while
237 * the previous one is transmitted over MIDI.
238 * (The value here is adjusted for midi_ratelimit_per_packet().)
239 */
240 s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
241
242 return 0; 214 return 0;
243} 215}
244EXPORT_SYMBOL(amdtp_stream_set_parameters); 216EXPORT_SYMBOL(amdtp_stream_set_parameters);
@@ -261,51 +233,6 @@ unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
261} 233}
262EXPORT_SYMBOL(amdtp_stream_get_max_payload); 234EXPORT_SYMBOL(amdtp_stream_get_max_payload);
263 235
264static void write_pcm_s16(struct amdtp_stream *s,
265 struct snd_pcm_substream *pcm,
266 __be32 *buffer, unsigned int frames);
267static void write_pcm_s32(struct amdtp_stream *s,
268 struct snd_pcm_substream *pcm,
269 __be32 *buffer, unsigned int frames);
270static void read_pcm_s32(struct amdtp_stream *s,
271 struct snd_pcm_substream *pcm,
272 __be32 *buffer, unsigned int frames);
273
274/**
275 * amdtp_am824_set_pcm_format - set the PCM format
276 * @s: the AMDTP stream to configure
277 * @format: the format of the ALSA PCM device
278 *
279 * The sample format must be set after the other parameters (rate/PCM channels/
280 * MIDI) and before the stream is started, and must not be changed while the
281 * stream is running.
282 */
283void amdtp_am824_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format)
284{
285 if (WARN_ON(amdtp_stream_pcm_running(s)))
286 return;
287
288 switch (format) {
289 default:
290 WARN_ON(1);
291 /* fall through */
292 case SNDRV_PCM_FORMAT_S16:
293 if (s->direction == AMDTP_OUT_STREAM) {
294 s->transfer_samples = write_pcm_s16;
295 break;
296 }
297 WARN_ON(1);
298 /* fall through */
299 case SNDRV_PCM_FORMAT_S32:
300 if (s->direction == AMDTP_OUT_STREAM)
301 s->transfer_samples = write_pcm_s32;
302 else
303 s->transfer_samples = read_pcm_s32;
304 break;
305 }
306}
307EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_format);
308
309/** 236/**
310 * amdtp_stream_pcm_prepare - prepare PCM device for running 237 * amdtp_stream_pcm_prepare - prepare PCM device for running
311 * @s: the AMDTP stream 238 * @s: the AMDTP stream
@@ -408,168 +335,6 @@ static unsigned int calculate_syt(struct amdtp_stream *s,
408 } 335 }
409} 336}
410 337
411static void write_pcm_s32(struct amdtp_stream *s,
412 struct snd_pcm_substream *pcm,
413 __be32 *buffer, unsigned int frames)
414{
415 struct snd_pcm_runtime *runtime = pcm->runtime;
416 unsigned int channels, remaining_frames, i, c;
417 const u32 *src;
418
419 channels = s->pcm_channels;
420 src = (void *)runtime->dma_area +
421 frames_to_bytes(runtime, s->pcm_buffer_pointer);
422 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
423
424 for (i = 0; i < frames; ++i) {
425 for (c = 0; c < channels; ++c) {
426 buffer[s->pcm_positions[c]] =
427 cpu_to_be32((*src >> 8) | 0x40000000);
428 src++;
429 }
430 buffer += s->data_block_quadlets;
431 if (--remaining_frames == 0)
432 src = (void *)runtime->dma_area;
433 }
434}
435
436static void write_pcm_s16(struct amdtp_stream *s,
437 struct snd_pcm_substream *pcm,
438 __be32 *buffer, unsigned int frames)
439{
440 struct snd_pcm_runtime *runtime = pcm->runtime;
441 unsigned int channels, remaining_frames, i, c;
442 const u16 *src;
443
444 channels = s->pcm_channels;
445 src = (void *)runtime->dma_area +
446 frames_to_bytes(runtime, s->pcm_buffer_pointer);
447 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
448
449 for (i = 0; i < frames; ++i) {
450 for (c = 0; c < channels; ++c) {
451 buffer[s->pcm_positions[c]] =
452 cpu_to_be32((*src << 8) | 0x42000000);
453 src++;
454 }
455 buffer += s->data_block_quadlets;
456 if (--remaining_frames == 0)
457 src = (void *)runtime->dma_area;
458 }
459}
460
461static void read_pcm_s32(struct amdtp_stream *s,
462 struct snd_pcm_substream *pcm,
463 __be32 *buffer, unsigned int frames)
464{
465 struct snd_pcm_runtime *runtime = pcm->runtime;
466 unsigned int channels, remaining_frames, i, c;
467 u32 *dst;
468
469 channels = s->pcm_channels;
470 dst = (void *)runtime->dma_area +
471 frames_to_bytes(runtime, s->pcm_buffer_pointer);
472 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
473
474 for (i = 0; i < frames; ++i) {
475 for (c = 0; c < channels; ++c) {
476 *dst = be32_to_cpu(buffer[s->pcm_positions[c]]) << 8;
477 dst++;
478 }
479 buffer += s->data_block_quadlets;
480 if (--remaining_frames == 0)
481 dst = (void *)runtime->dma_area;
482 }
483}
484
485static void write_pcm_silence(struct amdtp_stream *s,
486 __be32 *buffer, unsigned int frames)
487{
488 unsigned int i, c;
489
490 for (i = 0; i < frames; ++i) {
491 for (c = 0; c < s->pcm_channels; ++c)
492 buffer[s->pcm_positions[c]] = cpu_to_be32(0x40000000);
493 buffer += s->data_block_quadlets;
494 }
495}
496
497/*
498 * To avoid sending MIDI bytes at too high a rate, assume that the receiving
499 * device has a FIFO, and track how much it is filled. This values increases
500 * by one whenever we send one byte in a packet, but the FIFO empties at
501 * a constant rate independent of our packet rate. One packet has syt_interval
502 * samples, so the number of bytes that empty out of the FIFO, per packet(!),
503 * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing
504 * fractional values, the values in midi_fifo_used[] are measured in bytes
505 * multiplied by the sample rate.
506 */
507static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
508{
509 int used;
510
511 used = s->midi_fifo_used[port];
512 if (used == 0) /* common shortcut */
513 return true;
514
515 used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
516 used = max(used, 0);
517 s->midi_fifo_used[port] = used;
518
519 return used < s->midi_fifo_limit;
520}
521
522static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
523{
524 s->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
525}
526
527static void write_midi_messages(struct amdtp_stream *s,
528 __be32 *buffer, unsigned int frames)
529{
530 unsigned int f, port;
531 u8 *b;
532
533 for (f = 0; f < frames; f++) {
534 b = (u8 *)&buffer[s->midi_position];
535
536 port = (s->data_block_counter + f) % 8;
537 if (f < MAX_MIDI_RX_BLOCKS &&
538 midi_ratelimit_per_packet(s, port) &&
539 s->midi[port] != NULL &&
540 snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) {
541 midi_rate_use_one_byte(s, port);
542 b[0] = 0x81;
543 } else {
544 b[0] = 0x80;
545 b[1] = 0;
546 }
547 b[2] = 0;
548 b[3] = 0;
549
550 buffer += s->data_block_quadlets;
551 }
552}
553
554static void read_midi_messages(struct amdtp_stream *s,
555 __be32 *buffer, unsigned int frames)
556{
557 unsigned int f, port;
558 int len;
559 u8 *b;
560
561 for (f = 0; f < frames; f++) {
562 port = (s->data_block_counter + f) % 8;
563 b = (u8 *)&buffer[s->midi_position];
564
565 len = b[0] - 0x80;
566 if ((1 <= len) && (len <= 3) && (s->midi[port]))
567 snd_rawmidi_receive(s->midi[port], b + 1, len);
568
569 buffer += s->data_block_quadlets;
570 }
571}
572
573static void update_pcm_pointers(struct amdtp_stream *s, 338static void update_pcm_pointers(struct amdtp_stream *s,
574 struct snd_pcm_substream *pcm, 339 struct snd_pcm_substream *pcm,
575 unsigned int frames) 340 unsigned int frames)
@@ -639,26 +404,6 @@ static inline int queue_in_packet(struct amdtp_stream *s)
639 amdtp_stream_get_max_payload(s), false); 404 amdtp_stream_get_max_payload(s), false);
640} 405}
641 406
642unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
643 unsigned int data_blocks, unsigned int *syt)
644{
645 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
646 unsigned int pcm_frames;
647
648 if (pcm) {
649 s->transfer_samples(s, pcm, buffer, data_blocks);
650 pcm_frames = data_blocks * s->frame_multiplier;
651 } else {
652 write_pcm_silence(s, buffer, data_blocks);
653 pcm_frames = 0;
654 }
655
656 if (s->midi_ports)
657 write_midi_messages(s, buffer, data_blocks);
658
659 return pcm_frames;
660}
661
662static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks, 407static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
663 unsigned int syt) 408 unsigned int syt)
664{ 409{
@@ -668,7 +413,7 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
668 struct snd_pcm_substream *pcm; 413 struct snd_pcm_substream *pcm;
669 414
670 buffer = s->buffer.packets[s->packet_index].buffer; 415 buffer = s->buffer.packets[s->packet_index].buffer;
671 pcm_frames = process_rx_data_blocks(s, buffer + 2, data_blocks, &syt); 416 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);
672 417
673 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | 418 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
674 (s->data_block_quadlets << CIP_DBS_SHIFT) | 419 (s->data_block_quadlets << CIP_DBS_SHIFT) |
@@ -692,25 +437,6 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
692 return 0; 437 return 0;
693} 438}
694 439
695unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
696 unsigned int data_blocks, unsigned int *syt)
697{
698 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
699 unsigned int pcm_frames;
700
701 if (pcm) {
702 s->transfer_samples(s, pcm, buffer, data_blocks);
703 pcm_frames = data_blocks * s->frame_multiplier;
704 } else {
705 pcm_frames = 0;
706 }
707
708 if (s->midi_ports)
709 read_midi_messages(s, buffer, data_blocks);
710
711 return pcm_frames;
712}
713
714static int handle_in_packet(struct amdtp_stream *s, 440static int handle_in_packet(struct amdtp_stream *s,
715 unsigned int payload_quadlets, __be32 *buffer, 441 unsigned int payload_quadlets, __be32 *buffer,
716 unsigned int *data_blocks, unsigned int syt) 442 unsigned int *data_blocks, unsigned int syt)
@@ -798,7 +524,7 @@ static int handle_in_packet(struct amdtp_stream *s,
798 return -EIO; 524 return -EIO;
799 } 525 }
800 526
801 pcm_frames = process_tx_data_blocks(s, buffer + 2, *data_blocks, &syt); 527 pcm_frames = s->process_data_blocks(s, buffer + 2, *data_blocks, &syt);
802 528
803 if (s->flags & CIP_DBC_IS_END_EVENT) 529 if (s->flags & CIP_DBC_IS_END_EVENT)
804 s->data_block_counter = data_block_counter; 530 s->data_block_counter = data_block_counter;
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index 71f4f751fabc..8775704a3665 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -81,39 +81,22 @@ enum cip_sfc {
81 CIP_SFC_COUNT 81 CIP_SFC_COUNT
82}; 82};
83 83
84#define AM824_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32
85
86#define AM824_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
87 SNDRV_PCM_FMTBIT_S32)
88
89
90/*
91 * This module supports maximum 64 PCM channels for one PCM stream
92 * This is for our convenience.
93 */
94#define AM824_MAX_CHANNELS_FOR_PCM 64
95
96/*
97 * AMDTP packet can include channels for MIDI conformant data.
98 * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
99 * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
100 *
101 * This module supports maximum 1 MIDI conformant data channels.
102 * Then this AMDTP packets can transfer maximum 8 MIDI data streams.
103 */
104#define AM824_MAX_CHANNELS_FOR_MIDI 1
105
106struct fw_unit; 84struct fw_unit;
107struct fw_iso_context; 85struct fw_iso_context;
108struct snd_pcm_substream; 86struct snd_pcm_substream;
109struct snd_pcm_runtime; 87struct snd_pcm_runtime;
110struct snd_rawmidi_substream;
111 88
112enum amdtp_stream_direction { 89enum amdtp_stream_direction {
113 AMDTP_OUT_STREAM = 0, 90 AMDTP_OUT_STREAM = 0,
114 AMDTP_IN_STREAM 91 AMDTP_IN_STREAM
115}; 92};
116 93
94struct amdtp_stream;
95typedef unsigned int (*amdtp_stream_process_data_blocks_t)(
96 struct amdtp_stream *s,
97 __be32 *buffer,
98 unsigned int data_blocks,
99 unsigned int *syt);
117struct amdtp_stream { 100struct amdtp_stream {
118 struct fw_unit *unit; 101 struct fw_unit *unit;
119 enum cip_flags flags; 102 enum cip_flags flags;
@@ -156,32 +139,20 @@ struct amdtp_stream {
156 wait_queue_head_t callback_wait; 139 wait_queue_head_t callback_wait;
157 struct amdtp_stream *sync_slave; 140 struct amdtp_stream *sync_slave;
158 141
159 /* For AM824 processing. */ 142 /* For backends to process data blocks. */
160 struct snd_rawmidi_substream *midi[AM824_MAX_CHANNELS_FOR_MIDI * 8]; 143 void *protocol;
161 int midi_fifo_limit; 144 amdtp_stream_process_data_blocks_t process_data_blocks;
162 int midi_fifo_used[AM824_MAX_CHANNELS_FOR_MIDI * 8];
163 unsigned int pcm_channels;
164 unsigned int midi_ports;
165
166 u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM];
167 u8 midi_position;
168
169 void (*transfer_samples)(struct amdtp_stream *s,
170 struct snd_pcm_substream *pcm,
171 __be32 *buffer, unsigned int frames);
172
173 unsigned int frame_multiplier;
174}; 145};
175 146
176int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 147int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
177 enum amdtp_stream_direction dir, 148 enum amdtp_stream_direction dir, enum cip_flags flags,
178 enum cip_flags flags, unsigned int fmt); 149 unsigned int fmt,
150 amdtp_stream_process_data_blocks_t process_data_blocks,
151 unsigned int protocol_size);
179void amdtp_stream_destroy(struct amdtp_stream *s); 152void amdtp_stream_destroy(struct amdtp_stream *s);
180 153
181int amdtp_stream_set_parameters(struct amdtp_stream *s, 154int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
182 unsigned int rate, 155 unsigned int data_block_quadlets);
183 unsigned int pcm_channels,
184 unsigned int midi_ports);
185unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s); 156unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s);
186 157
187int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed); 158int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed);
@@ -190,8 +161,7 @@ void amdtp_stream_stop(struct amdtp_stream *s);
190 161
191int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, 162int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
192 struct snd_pcm_runtime *runtime); 163 struct snd_pcm_runtime *runtime);
193void amdtp_am824_set_pcm_format(struct amdtp_stream *s, 164
194 snd_pcm_format_t format);
195void amdtp_stream_pcm_prepare(struct amdtp_stream *s); 165void amdtp_stream_pcm_prepare(struct amdtp_stream *s);
196unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); 166unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s);
197void amdtp_stream_pcm_abort(struct amdtp_stream *s); 167void amdtp_stream_pcm_abort(struct amdtp_stream *s);