linux/sound/firewire/digi00x/amdtp-dot.c
<<
>>
Prefs
   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 */
  37struct dot_state {
  38        u8 carry;
  39        u8 idx;
  40        unsigned int off;
  41};
  42
  43struct 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)
  62static 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
 101static 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
 113int 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
 145static 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
 177static 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
 208static 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
 224static 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
 240static 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
 248static 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
 292static 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
 322int 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
 335void 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
 344static 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
 368static 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
 395int 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        unsigned int flags = CIP_NONBLOCKING | CIP_UNAWARE_SYT;
 400
 401        // Use different mode between incoming/outgoing.
 402        if (dir == AMDTP_IN_STREAM)
 403                process_ctx_payloads = process_ir_ctx_payloads;
 404        else
 405                process_ctx_payloads = process_it_ctx_payloads;
 406
 407        return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
 408                                process_ctx_payloads, sizeof(struct amdtp_dot));
 409}
 410
 411void amdtp_dot_reset(struct amdtp_stream *s)
 412{
 413        struct amdtp_dot *p = s->protocol;
 414
 415        p->state.carry = 0x00;
 416        p->state.idx = 0x00;
 417        p->state.off = 0;
 418}
 419