0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <sound/pcm.h>
0011 #include "digi00x.h"
0012
0013 #define CIP_FMT_AM 0x10
0014
0015
0016 #define AMDTP_FDF_AM824 0x00
0017
0018
0019
0020
0021
0022 #define MIDI_BYTES_PER_SECOND 3093
0023
0024
0025
0026
0027
0028 #define MAX_MIDI_RX_BLOCKS 8
0029
0030
0031 #define MAX_MIDI_PORTS 3
0032
0033
0034
0035
0036
0037 struct dot_state {
0038 u8 carry;
0039 u8 idx;
0040 unsigned int off;
0041 };
0042
0043 struct amdtp_dot {
0044 unsigned int pcm_channels;
0045 struct dot_state state;
0046
0047 struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];
0048 int midi_fifo_used[MAX_MIDI_PORTS];
0049 int midi_fifo_limit;
0050 };
0051
0052
0053
0054
0055
0056
0057
0058
0059 #define BYTE_PER_SAMPLE (4)
0060 #define MAGIC_DOT_BYTE (2)
0061 #define MAGIC_BYTE_OFF(x) (((x) * BYTE_PER_SAMPLE) + MAGIC_DOT_BYTE)
0062 static u8 dot_scrt(const u8 idx, const unsigned int off)
0063 {
0064
0065
0066
0067
0068 static const u8 len[16] = {0, 1, 3, 5, 7, 9, 11, 13, 14,
0069 12, 10, 8, 6, 4, 2, 0};
0070
0071
0072
0073
0074
0075 static const u8 nib[15] = {0x8, 0x7, 0x9, 0x6, 0xa, 0x5, 0xb, 0x4,
0076 0xc, 0x3, 0xd, 0x2, 0xe, 0x1, 0xf};
0077
0078
0079 static const u8 hir[15] = {0x0, 0x6, 0xf, 0x8, 0x7, 0x5, 0x3, 0x4,
0080 0xc, 0xd, 0xe, 0x1, 0x2, 0xb, 0xa};
0081
0082
0083
0084
0085
0086
0087
0088 static const u8 hio[16] = {0, 11, 12, 6, 7, 5, 1, 4,
0089 3, 0x00, 14, 13, 8, 9, 10, 2};
0090
0091 const u8 ln = idx & 0xf;
0092 const u8 hn = (idx >> 4) & 0xf;
0093 const u8 hr = (hn == 0x9) ? 0x9 : hir[(hio[hn] + off) % 15];
0094
0095 if (len[ln] < off)
0096 return 0x00;
0097
0098 return ((nib[14 + off - len[ln]]) | (hr << 4));
0099 }
0100
0101 static void dot_encode_step(struct dot_state *state, __be32 *const buffer)
0102 {
0103 u8 * const data = (u8 *) buffer;
0104
0105 if (data[MAGIC_DOT_BYTE] != 0x00) {
0106 state->off = 0;
0107 state->idx = data[MAGIC_DOT_BYTE] ^ state->carry;
0108 }
0109 data[MAGIC_DOT_BYTE] ^= state->carry;
0110 state->carry = dot_scrt(state->idx, ++(state->off));
0111 }
0112
0113 int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
0114 unsigned int pcm_channels)
0115 {
0116 struct amdtp_dot *p = s->protocol;
0117 int err;
0118
0119 if (amdtp_stream_running(s))
0120 return -EBUSY;
0121
0122
0123
0124
0125
0126 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);
0127 if (err < 0)
0128 return err;
0129
0130 s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
0131
0132 p->pcm_channels = pcm_channels;
0133
0134
0135
0136
0137
0138
0139
0140 p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
0141
0142 return 0;
0143 }
0144
0145 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
0146 __be32 *buffer, unsigned int frames,
0147 unsigned int pcm_frames)
0148 {
0149 struct amdtp_dot *p = s->protocol;
0150 unsigned int channels = p->pcm_channels;
0151 struct snd_pcm_runtime *runtime = pcm->runtime;
0152 unsigned int pcm_buffer_pointer;
0153 int remaining_frames;
0154 const u32 *src;
0155 int i, c;
0156
0157 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
0158 pcm_buffer_pointer %= runtime->buffer_size;
0159
0160 src = (void *)runtime->dma_area +
0161 frames_to_bytes(runtime, pcm_buffer_pointer);
0162 remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
0163
0164 buffer++;
0165 for (i = 0; i < frames; ++i) {
0166 for (c = 0; c < channels; ++c) {
0167 buffer[c] = cpu_to_be32((*src >> 8) | 0x40000000);
0168 dot_encode_step(&p->state, &buffer[c]);
0169 src++;
0170 }
0171 buffer += s->data_block_quadlets;
0172 if (--remaining_frames == 0)
0173 src = (void *)runtime->dma_area;
0174 }
0175 }
0176
0177 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
0178 __be32 *buffer, unsigned int frames,
0179 unsigned int pcm_frames)
0180 {
0181 struct amdtp_dot *p = s->protocol;
0182 unsigned int channels = p->pcm_channels;
0183 struct snd_pcm_runtime *runtime = pcm->runtime;
0184 unsigned int pcm_buffer_pointer;
0185 int remaining_frames;
0186 u32 *dst;
0187 int i, c;
0188
0189 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
0190 pcm_buffer_pointer %= runtime->buffer_size;
0191
0192 dst = (void *)runtime->dma_area +
0193 frames_to_bytes(runtime, pcm_buffer_pointer);
0194 remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
0195
0196 buffer++;
0197 for (i = 0; i < frames; ++i) {
0198 for (c = 0; c < channels; ++c) {
0199 *dst = be32_to_cpu(buffer[c]) << 8;
0200 dst++;
0201 }
0202 buffer += s->data_block_quadlets;
0203 if (--remaining_frames == 0)
0204 dst = (void *)runtime->dma_area;
0205 }
0206 }
0207
0208 static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer,
0209 unsigned int data_blocks)
0210 {
0211 struct amdtp_dot *p = s->protocol;
0212 unsigned int channels, i, c;
0213
0214 channels = p->pcm_channels;
0215
0216 buffer++;
0217 for (i = 0; i < data_blocks; ++i) {
0218 for (c = 0; c < channels; ++c)
0219 buffer[c] = cpu_to_be32(0x40000000);
0220 buffer += s->data_block_quadlets;
0221 }
0222 }
0223
0224 static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
0225 {
0226 struct amdtp_dot *p = s->protocol;
0227 int used;
0228
0229 used = p->midi_fifo_used[port];
0230 if (used == 0)
0231 return true;
0232
0233 used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
0234 used = max(used, 0);
0235 p->midi_fifo_used[port] = used;
0236
0237 return used < p->midi_fifo_limit;
0238 }
0239
0240 static inline void midi_use_bytes(struct amdtp_stream *s,
0241 unsigned int port, unsigned int count)
0242 {
0243 struct amdtp_dot *p = s->protocol;
0244
0245 p->midi_fifo_used[port] += amdtp_rate_table[s->sfc] * count;
0246 }
0247
0248 static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
0249 unsigned int data_blocks, unsigned int data_block_counter)
0250 {
0251 struct amdtp_dot *p = s->protocol;
0252 unsigned int f, port;
0253 int len;
0254 u8 *b;
0255
0256 for (f = 0; f < data_blocks; f++) {
0257 port = (data_block_counter + f) % 8;
0258 b = (u8 *)&buffer[0];
0259
0260 len = 0;
0261 if (port < MAX_MIDI_PORTS &&
0262 midi_ratelimit_per_packet(s, port) &&
0263 p->midi[port] != NULL)
0264 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);
0265
0266 if (len > 0) {
0267
0268
0269
0270
0271
0272
0273 if (port == 2)
0274 b[3] = 0xe0;
0275 else if (port == 1)
0276 b[3] = 0x20;
0277 else
0278 b[3] = 0x00;
0279 b[3] |= len;
0280 midi_use_bytes(s, port, len);
0281 } else {
0282 b[1] = 0;
0283 b[2] = 0;
0284 b[3] = 0;
0285 }
0286 b[0] = 0x80;
0287
0288 buffer += s->data_block_quadlets;
0289 }
0290 }
0291
0292 static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
0293 unsigned int data_blocks)
0294 {
0295 struct amdtp_dot *p = s->protocol;
0296 unsigned int f, port, len;
0297 u8 *b;
0298
0299 for (f = 0; f < data_blocks; f++) {
0300 b = (u8 *)&buffer[0];
0301
0302 len = b[3] & 0x0f;
0303 if (len > 0) {
0304
0305
0306
0307
0308
0309 if (b[3] >> 4 > 0)
0310 port = 2;
0311 else
0312 port = 0;
0313
0314 if (port < MAX_MIDI_PORTS && p->midi[port])
0315 snd_rawmidi_receive(p->midi[port], b + 1, len);
0316 }
0317
0318 buffer += s->data_block_quadlets;
0319 }
0320 }
0321
0322 int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s,
0323 struct snd_pcm_runtime *runtime)
0324 {
0325 int err;
0326
0327
0328 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
0329 if (err < 0)
0330 return err;
0331
0332 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
0333 }
0334
0335 void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
0336 struct snd_rawmidi_substream *midi)
0337 {
0338 struct amdtp_dot *p = s->protocol;
0339
0340 if (port < MAX_MIDI_PORTS)
0341 WRITE_ONCE(p->midi[port], midi);
0342 }
0343
0344 static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
0345 const struct pkt_desc *descs,
0346 unsigned int packets,
0347 struct snd_pcm_substream *pcm)
0348 {
0349 unsigned int pcm_frames = 0;
0350 int i;
0351
0352 for (i = 0; i < packets; ++i) {
0353 const struct pkt_desc *desc = descs + i;
0354 __be32 *buf = desc->ctx_payload;
0355 unsigned int data_blocks = desc->data_blocks;
0356
0357 if (pcm) {
0358 read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
0359 pcm_frames += data_blocks;
0360 }
0361
0362 read_midi_messages(s, buf, data_blocks);
0363 }
0364
0365 return pcm_frames;
0366 }
0367
0368 static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
0369 const struct pkt_desc *descs,
0370 unsigned int packets,
0371 struct snd_pcm_substream *pcm)
0372 {
0373 unsigned int pcm_frames = 0;
0374 int i;
0375
0376 for (i = 0; i < packets; ++i) {
0377 const struct pkt_desc *desc = descs + i;
0378 __be32 *buf = desc->ctx_payload;
0379 unsigned int data_blocks = desc->data_blocks;
0380
0381 if (pcm) {
0382 write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
0383 pcm_frames += data_blocks;
0384 } else {
0385 write_pcm_silence(s, buf, data_blocks);
0386 }
0387
0388 write_midi_messages(s, buf, data_blocks,
0389 desc->data_block_counter);
0390 }
0391
0392 return pcm_frames;
0393 }
0394
0395 int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
0396 enum amdtp_stream_direction dir)
0397 {
0398 amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
0399 unsigned int flags = CIP_NONBLOCKING | CIP_UNAWARE_SYT;
0400
0401
0402 if (dir == AMDTP_IN_STREAM)
0403 process_ctx_payloads = process_ir_ctx_payloads;
0404 else
0405 process_ctx_payloads = process_it_ctx_payloads;
0406
0407 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
0408 process_ctx_payloads, sizeof(struct amdtp_dot));
0409 }
0410
0411 void amdtp_dot_reset(struct amdtp_stream *s)
0412 {
0413 struct amdtp_dot *p = s->protocol;
0414
0415 p->state.carry = 0x00;
0416 p->state.idx = 0x00;
0417 p->state.off = 0;
0418 }