root/sound/firewire/digi00x/amdtp-dot.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dot_scrt
  2. dot_encode_step
  3. amdtp_dot_set_parameters
  4. write_pcm_s32
  5. read_pcm_s32
  6. write_pcm_silence
  7. midi_ratelimit_per_packet
  8. midi_use_bytes
  9. write_midi_messages
  10. read_midi_messages
  11. amdtp_dot_add_pcm_hw_constraints
  12. amdtp_dot_midi_trigger
  13. process_ir_ctx_payloads
  14. process_it_ctx_payloads
  15. amdtp_dot_init
  16. amdtp_dot_reset

   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 <robin@gareus.org>
   7  * Copyright (C) 2012 Damien Zammit <damien@zamaudio.com>
   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);
 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 unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
 345                                             const struct pkt_desc *descs,
 346                                             unsigned int packets,
 347                                             struct snd_pcm_substream *pcm)
 348 {
 349         unsigned int pcm_frames = 0;
 350         int i;
 351 
 352         for (i = 0; i < packets; ++i) {
 353                 const struct pkt_desc *desc = descs + i;
 354                 __be32 *buf = desc->ctx_payload;
 355                 unsigned int data_blocks = desc->data_blocks;
 356 
 357                 if (pcm) {
 358                         read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
 359                         pcm_frames += data_blocks;
 360                 }
 361 
 362                 read_midi_messages(s, buf, data_blocks);
 363         }
 364 
 365         return pcm_frames;
 366 }
 367 
 368 static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
 369                                             const struct pkt_desc *descs,
 370                                             unsigned int packets,
 371                                             struct snd_pcm_substream *pcm)
 372 {
 373         unsigned int pcm_frames = 0;
 374         int i;
 375 
 376         for (i = 0; i < packets; ++i) {
 377                 const struct pkt_desc *desc = descs + i;
 378                 __be32 *buf = desc->ctx_payload;
 379                 unsigned int data_blocks = desc->data_blocks;
 380 
 381                 if (pcm) {
 382                         write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
 383                         pcm_frames += data_blocks;
 384                 } else {
 385                         write_pcm_silence(s, buf, data_blocks);
 386                 }
 387 
 388                 write_midi_messages(s, buf, data_blocks,
 389                                     desc->data_block_counter);
 390         }
 391 
 392         return pcm_frames;
 393 }
 394 
 395 int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
 396                  enum amdtp_stream_direction dir)
 397 {
 398         amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
 399         enum cip_flags flags;
 400 
 401         // Use different mode between incoming/outgoing.
 402         if (dir == AMDTP_IN_STREAM) {
 403                 flags = CIP_NONBLOCKING;
 404                 process_ctx_payloads = process_ir_ctx_payloads;
 405         } else {
 406                 flags = CIP_BLOCKING;
 407                 process_ctx_payloads = process_it_ctx_payloads;
 408         }
 409 
 410         return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
 411                                 process_ctx_payloads, sizeof(struct amdtp_dot));
 412 }
 413 
 414 void amdtp_dot_reset(struct amdtp_stream *s)
 415 {
 416         struct amdtp_dot *p = s->protocol;
 417 
 418         p->state.carry = 0x00;
 419         p->state.idx = 0x00;
 420         p->state.off = 0;
 421 }

/* [<][>][^][v][top][bottom][index][help] */