Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/firewire/digi00x/amdtp-dot.c
26451 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* amdtp-dot.c - a part of driver for Digidesign Digi 002/003 family
4
*
5
* Copyright (c) 2014-2015 Takashi Sakamoto
6
* Copyright (C) 2012 Robin Gareus <[email protected]>
7
* Copyright (C) 2012 Damien Zammit <[email protected]>
8
*/
9
10
#include <sound/pcm.h>
11
#include "digi00x.h"
12
13
#define CIP_FMT_AM 0x10
14
15
/* 'Clock-based rate control mode' is just supported. */
16
#define AMDTP_FDF_AM824 0x00
17
18
/*
19
* Nominally 3125 bytes/second, but the MIDI port's clock might be
20
* 1% too slow, and the bus clock 100 ppm too fast.
21
*/
22
#define MIDI_BYTES_PER_SECOND 3093
23
24
/*
25
* Several devices look only at the first eight data blocks.
26
* In any case, this is more than enough for the MIDI data rate.
27
*/
28
#define MAX_MIDI_RX_BLOCKS 8
29
30
/* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */
31
#define MAX_MIDI_PORTS 3
32
33
/*
34
* The double-oh-three algorithm was discovered by Robin Gareus and Damien
35
* Zammit in 2012, with reverse-engineering for Digi 003 Rack.
36
*/
37
struct dot_state {
38
u8 carry;
39
u8 idx;
40
unsigned int off;
41
};
42
43
struct amdtp_dot {
44
unsigned int pcm_channels;
45
struct dot_state state;
46
47
struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];
48
int midi_fifo_used[MAX_MIDI_PORTS];
49
int midi_fifo_limit;
50
};
51
52
/*
53
* double-oh-three look up table
54
*
55
* @param idx index byte (audio-sample data) 0x00..0xff
56
* @param off channel offset shift
57
* @return salt to XOR with given data
58
*/
59
#define BYTE_PER_SAMPLE (4)
60
#define MAGIC_DOT_BYTE (2)
61
#define MAGIC_BYTE_OFF(x) (((x) * BYTE_PER_SAMPLE) + MAGIC_DOT_BYTE)
62
static u8 dot_scrt(const u8 idx, const unsigned int off)
63
{
64
/*
65
* the length of the added pattern only depends on the lower nibble
66
* of the last non-zero data
67
*/
68
static const u8 len[16] = {0, 1, 3, 5, 7, 9, 11, 13, 14,
69
12, 10, 8, 6, 4, 2, 0};
70
71
/*
72
* the lower nibble of the salt. Interleaved sequence.
73
* this is walked backwards according to len[]
74
*/
75
static const u8 nib[15] = {0x8, 0x7, 0x9, 0x6, 0xa, 0x5, 0xb, 0x4,
76
0xc, 0x3, 0xd, 0x2, 0xe, 0x1, 0xf};
77
78
/* circular list for the salt's hi nibble. */
79
static const u8 hir[15] = {0x0, 0x6, 0xf, 0x8, 0x7, 0x5, 0x3, 0x4,
80
0xc, 0xd, 0xe, 0x1, 0x2, 0xb, 0xa};
81
82
/*
83
* start offset for upper nibble mapping.
84
* note: 9 is /special/. In the case where the high nibble == 0x9,
85
* hir[] is not used and - coincidentally - the salt's hi nibble is
86
* 0x09 regardless of the offset.
87
*/
88
static const u8 hio[16] = {0, 11, 12, 6, 7, 5, 1, 4,
89
3, 0x00, 14, 13, 8, 9, 10, 2};
90
91
const u8 ln = idx & 0xf;
92
const u8 hn = (idx >> 4) & 0xf;
93
const u8 hr = (hn == 0x9) ? 0x9 : hir[(hio[hn] + off) % 15];
94
95
if (len[ln] < off)
96
return 0x00;
97
98
return ((nib[14 + off - len[ln]]) | (hr << 4));
99
}
100
101
static void dot_encode_step(struct dot_state *state, __be32 *const buffer)
102
{
103
u8 * const data = (u8 *) buffer;
104
105
if (data[MAGIC_DOT_BYTE] != 0x00) {
106
state->off = 0;
107
state->idx = data[MAGIC_DOT_BYTE] ^ state->carry;
108
}
109
data[MAGIC_DOT_BYTE] ^= state->carry;
110
state->carry = dot_scrt(state->idx, ++(state->off));
111
}
112
113
int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
114
unsigned int pcm_channels)
115
{
116
struct amdtp_dot *p = s->protocol;
117
int err;
118
119
if (amdtp_stream_running(s))
120
return -EBUSY;
121
122
/*
123
* A first data channel is for MIDI messages, the rest is Multi Bit
124
* Linear Audio data channel.
125
*/
126
err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1, 1);
127
if (err < 0)
128
return err;
129
130
s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
131
132
p->pcm_channels = pcm_channels;
133
134
/*
135
* We do not know the actual MIDI FIFO size of most devices. Just
136
* assume two bytes, i.e., one byte can be received over the bus while
137
* the previous one is transmitted over MIDI.
138
* (The value here is adjusted for midi_ratelimit_per_packet().)
139
*/
140
p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
141
142
return 0;
143
}
144
145
static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
146
__be32 *buffer, unsigned int frames,
147
unsigned int pcm_frames)
148
{
149
struct amdtp_dot *p = s->protocol;
150
unsigned int channels = p->pcm_channels;
151
struct snd_pcm_runtime *runtime = pcm->runtime;
152
unsigned int pcm_buffer_pointer;
153
int remaining_frames;
154
const u32 *src;
155
int i, c;
156
157
pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
158
pcm_buffer_pointer %= runtime->buffer_size;
159
160
src = (void *)runtime->dma_area +
161
frames_to_bytes(runtime, pcm_buffer_pointer);
162
remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
163
164
buffer++;
165
for (i = 0; i < frames; ++i) {
166
for (c = 0; c < channels; ++c) {
167
buffer[c] = cpu_to_be32((*src >> 8) | 0x40000000);
168
dot_encode_step(&p->state, &buffer[c]);
169
src++;
170
}
171
buffer += s->data_block_quadlets;
172
if (--remaining_frames == 0)
173
src = (void *)runtime->dma_area;
174
}
175
}
176
177
static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
178
__be32 *buffer, unsigned int frames,
179
unsigned int pcm_frames)
180
{
181
struct amdtp_dot *p = s->protocol;
182
unsigned int channels = p->pcm_channels;
183
struct snd_pcm_runtime *runtime = pcm->runtime;
184
unsigned int pcm_buffer_pointer;
185
int remaining_frames;
186
u32 *dst;
187
int i, c;
188
189
pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
190
pcm_buffer_pointer %= runtime->buffer_size;
191
192
dst = (void *)runtime->dma_area +
193
frames_to_bytes(runtime, pcm_buffer_pointer);
194
remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
195
196
buffer++;
197
for (i = 0; i < frames; ++i) {
198
for (c = 0; c < channels; ++c) {
199
*dst = be32_to_cpu(buffer[c]) << 8;
200
dst++;
201
}
202
buffer += s->data_block_quadlets;
203
if (--remaining_frames == 0)
204
dst = (void *)runtime->dma_area;
205
}
206
}
207
208
static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer,
209
unsigned int data_blocks)
210
{
211
struct amdtp_dot *p = s->protocol;
212
unsigned int channels, i, c;
213
214
channels = p->pcm_channels;
215
216
buffer++;
217
for (i = 0; i < data_blocks; ++i) {
218
for (c = 0; c < channels; ++c)
219
buffer[c] = cpu_to_be32(0x40000000);
220
buffer += s->data_block_quadlets;
221
}
222
}
223
224
static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
225
{
226
struct amdtp_dot *p = s->protocol;
227
int used;
228
229
used = p->midi_fifo_used[port];
230
if (used == 0)
231
return true;
232
233
used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
234
used = max(used, 0);
235
p->midi_fifo_used[port] = used;
236
237
return used < p->midi_fifo_limit;
238
}
239
240
static inline void midi_use_bytes(struct amdtp_stream *s,
241
unsigned int port, unsigned int count)
242
{
243
struct amdtp_dot *p = s->protocol;
244
245
p->midi_fifo_used[port] += amdtp_rate_table[s->sfc] * count;
246
}
247
248
static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
249
unsigned int data_blocks, unsigned int data_block_counter)
250
{
251
struct amdtp_dot *p = s->protocol;
252
unsigned int f, port;
253
int len;
254
u8 *b;
255
256
for (f = 0; f < data_blocks; f++) {
257
port = (data_block_counter + f) % 8;
258
b = (u8 *)&buffer[0];
259
260
len = 0;
261
if (port < MAX_MIDI_PORTS &&
262
midi_ratelimit_per_packet(s, port) &&
263
p->midi[port] != NULL)
264
len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);
265
266
if (len > 0) {
267
/*
268
* Upper 4 bits of LSB represent port number.
269
* - 0000b: physical MIDI port 1.
270
* - 0010b: physical MIDI port 2.
271
* - 1110b: console MIDI port.
272
*/
273
if (port == 2)
274
b[3] = 0xe0;
275
else if (port == 1)
276
b[3] = 0x20;
277
else
278
b[3] = 0x00;
279
b[3] |= len;
280
midi_use_bytes(s, port, len);
281
} else {
282
b[1] = 0;
283
b[2] = 0;
284
b[3] = 0;
285
}
286
b[0] = 0x80;
287
288
buffer += s->data_block_quadlets;
289
}
290
}
291
292
static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
293
unsigned int data_blocks)
294
{
295
struct amdtp_dot *p = s->protocol;
296
unsigned int f, port, len;
297
u8 *b;
298
299
for (f = 0; f < data_blocks; f++) {
300
b = (u8 *)&buffer[0];
301
302
len = b[3] & 0x0f;
303
if (len > 0) {
304
/*
305
* Upper 4 bits of LSB represent port number.
306
* - 0000b: physical MIDI port 1. Use port 0.
307
* - 1110b: console MIDI port. Use port 2.
308
*/
309
if (b[3] >> 4 > 0)
310
port = 2;
311
else
312
port = 0;
313
314
if (port < MAX_MIDI_PORTS && p->midi[port])
315
snd_rawmidi_receive(p->midi[port], b + 1, len);
316
}
317
318
buffer += s->data_block_quadlets;
319
}
320
}
321
322
int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s,
323
struct snd_pcm_runtime *runtime)
324
{
325
int err;
326
327
/* This protocol delivers 24 bit data in 32bit data channel. */
328
err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
329
if (err < 0)
330
return err;
331
332
return amdtp_stream_add_pcm_hw_constraints(s, runtime);
333
}
334
335
void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
336
struct snd_rawmidi_substream *midi)
337
{
338
struct amdtp_dot *p = s->protocol;
339
340
if (port < MAX_MIDI_PORTS)
341
WRITE_ONCE(p->midi[port], midi);
342
}
343
344
static void process_ir_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *desc,
345
unsigned int count, struct snd_pcm_substream *pcm)
346
{
347
unsigned int pcm_frames = 0;
348
int i;
349
350
for (i = 0; i < count; ++i) {
351
__be32 *buf = desc->ctx_payload;
352
unsigned int data_blocks = desc->data_blocks;
353
354
if (pcm) {
355
read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
356
pcm_frames += data_blocks;
357
}
358
359
read_midi_messages(s, buf, data_blocks);
360
361
desc = amdtp_stream_next_packet_desc(s, desc);
362
}
363
}
364
365
static void process_it_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *desc,
366
unsigned int count, struct snd_pcm_substream *pcm)
367
{
368
unsigned int pcm_frames = 0;
369
int i;
370
371
for (i = 0; i < count; ++i) {
372
__be32 *buf = desc->ctx_payload;
373
unsigned int data_blocks = desc->data_blocks;
374
375
if (pcm) {
376
write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
377
pcm_frames += data_blocks;
378
} else {
379
write_pcm_silence(s, buf, data_blocks);
380
}
381
382
write_midi_messages(s, buf, data_blocks,
383
desc->data_block_counter);
384
385
desc = amdtp_stream_next_packet_desc(s, desc);
386
}
387
}
388
389
int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
390
enum amdtp_stream_direction dir)
391
{
392
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
393
unsigned int flags = CIP_NONBLOCKING | CIP_UNAWARE_SYT;
394
395
// Use different mode between incoming/outgoing.
396
if (dir == AMDTP_IN_STREAM)
397
process_ctx_payloads = process_ir_ctx_payloads;
398
else
399
process_ctx_payloads = process_it_ctx_payloads;
400
401
return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
402
process_ctx_payloads, sizeof(struct amdtp_dot));
403
}
404
405
void amdtp_dot_reset(struct amdtp_stream *s)
406
{
407
struct amdtp_dot *p = s->protocol;
408
409
p->state.carry = 0x00;
410
p->state.idx = 0x00;
411
p->state.off = 0;
412
}
413
414