linux/sound/firewire/amdtp-am824.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
   4 *
   5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
   6 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
   7 */
   8
   9#include <linux/slab.h>
  10
  11#include "amdtp-am824.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
  30struct amdtp_am824 {
  31        struct snd_rawmidi_substream *midi[AM824_MAX_CHANNELS_FOR_MIDI * 8];
  32        int midi_fifo_limit;
  33        int midi_fifo_used[AM824_MAX_CHANNELS_FOR_MIDI * 8];
  34        unsigned int pcm_channels;
  35        unsigned int midi_ports;
  36
  37        u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM];
  38        u8 midi_position;
  39
  40        unsigned int frame_multiplier;
  41};
  42
  43/**
  44 * amdtp_am824_set_parameters - set stream parameters
  45 * @s: the AMDTP stream to configure
  46 * @rate: the sample rate
  47 * @pcm_channels: the number of PCM samples in each data block, to be encoded
  48 *                as AM824 multi-bit linear audio
  49 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
  50 * @double_pcm_frames: one data block transfers two PCM frames
  51 *
  52 * The parameters must be set before the stream is started, and must not be
  53 * changed while the stream is running.
  54 */
  55int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
  56                               unsigned int pcm_channels,
  57                               unsigned int midi_ports,
  58                               bool double_pcm_frames)
  59{
  60        struct amdtp_am824 *p = s->protocol;
  61        unsigned int midi_channels;
  62        unsigned int i;
  63        int err;
  64
  65        if (amdtp_stream_running(s))
  66                return -EINVAL;
  67
  68        if (pcm_channels > AM824_MAX_CHANNELS_FOR_PCM)
  69                return -EINVAL;
  70
  71        midi_channels = DIV_ROUND_UP(midi_ports, 8);
  72        if (midi_channels > AM824_MAX_CHANNELS_FOR_MIDI)
  73                return -EINVAL;
  74
  75        if (WARN_ON(amdtp_stream_running(s)) ||
  76            WARN_ON(pcm_channels > AM824_MAX_CHANNELS_FOR_PCM) ||
  77            WARN_ON(midi_channels > AM824_MAX_CHANNELS_FOR_MIDI))
  78                return -EINVAL;
  79
  80        err = amdtp_stream_set_parameters(s, rate,
  81                                          pcm_channels + midi_channels);
  82        if (err < 0)
  83                return err;
  84
  85        if (s->direction == AMDTP_OUT_STREAM)
  86                s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
  87
  88        p->pcm_channels = pcm_channels;
  89        p->midi_ports = midi_ports;
  90
  91        /*
  92         * In IEC 61883-6, one data block represents one event. In ALSA, one
  93         * event equals to one PCM frame. But Dice has a quirk at higher
  94         * sampling rate to transfer two PCM frames in one data block.
  95         */
  96        if (double_pcm_frames)
  97                p->frame_multiplier = 2;
  98        else
  99                p->frame_multiplier = 1;
 100
 101        /* init the position map for PCM and MIDI channels */
 102        for (i = 0; i < pcm_channels; i++)
 103                p->pcm_positions[i] = i;
 104        p->midi_position = p->pcm_channels;
 105
 106        /*
 107         * We do not know the actual MIDI FIFO size of most devices.  Just
 108         * assume two bytes, i.e., one byte can be received over the bus while
 109         * the previous one is transmitted over MIDI.
 110         * (The value here is adjusted for midi_ratelimit_per_packet().)
 111         */
 112        p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
 113
 114        return 0;
 115}
 116EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters);
 117
 118/**
 119 * amdtp_am824_set_pcm_position - set an index of data channel for a channel
 120 *                                of PCM frame
 121 * @s: the AMDTP stream
 122 * @index: the index of data channel in an data block
 123 * @position: the channel of PCM frame
 124 */
 125void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
 126                                 unsigned int position)
 127{
 128        struct amdtp_am824 *p = s->protocol;
 129
 130        if (index < p->pcm_channels)
 131                p->pcm_positions[index] = position;
 132}
 133EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
 134
 135/**
 136 * amdtp_am824_set_midi_position - set a index of data channel for MIDI
 137 *                                 conformant data channel
 138 * @s: the AMDTP stream
 139 * @position: the index of data channel in an data block
 140 */
 141void amdtp_am824_set_midi_position(struct amdtp_stream *s,
 142                                   unsigned int position)
 143{
 144        struct amdtp_am824 *p = s->protocol;
 145
 146        p->midi_position = position;
 147}
 148EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
 149
 150static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
 151                          __be32 *buffer, unsigned int frames,
 152                          unsigned int pcm_frames)
 153{
 154        struct amdtp_am824 *p = s->protocol;
 155        unsigned int channels = p->pcm_channels;
 156        struct snd_pcm_runtime *runtime = pcm->runtime;
 157        unsigned int pcm_buffer_pointer;
 158        int remaining_frames;
 159        const u32 *src;
 160        int i, c;
 161
 162        pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
 163        pcm_buffer_pointer %= runtime->buffer_size;
 164
 165        src = (void *)runtime->dma_area +
 166                                frames_to_bytes(runtime, pcm_buffer_pointer);
 167        remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
 168
 169        for (i = 0; i < frames; ++i) {
 170                for (c = 0; c < channels; ++c) {
 171                        buffer[p->pcm_positions[c]] =
 172                                        cpu_to_be32((*src >> 8) | 0x40000000);
 173                        src++;
 174                }
 175                buffer += s->data_block_quadlets;
 176                if (--remaining_frames == 0)
 177                        src = (void *)runtime->dma_area;
 178        }
 179}
 180
 181static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
 182                         __be32 *buffer, unsigned int frames,
 183                         unsigned int pcm_frames)
 184{
 185        struct amdtp_am824 *p = s->protocol;
 186        unsigned int channels = p->pcm_channels;
 187        struct snd_pcm_runtime *runtime = pcm->runtime;
 188        unsigned int pcm_buffer_pointer;
 189        int remaining_frames;
 190        u32 *dst;
 191        int i, c;
 192
 193        pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
 194        pcm_buffer_pointer %= runtime->buffer_size;
 195
 196        dst  = (void *)runtime->dma_area +
 197                                frames_to_bytes(runtime, pcm_buffer_pointer);
 198        remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
 199
 200        for (i = 0; i < frames; ++i) {
 201                for (c = 0; c < channels; ++c) {
 202                        *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8;
 203                        dst++;
 204                }
 205                buffer += s->data_block_quadlets;
 206                if (--remaining_frames == 0)
 207                        dst = (void *)runtime->dma_area;
 208        }
 209}
 210
 211static void write_pcm_silence(struct amdtp_stream *s,
 212                              __be32 *buffer, unsigned int frames)
 213{
 214        struct amdtp_am824 *p = s->protocol;
 215        unsigned int i, c, channels = p->pcm_channels;
 216
 217        for (i = 0; i < frames; ++i) {
 218                for (c = 0; c < channels; ++c)
 219                        buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000);
 220                buffer += s->data_block_quadlets;
 221        }
 222}
 223
 224/**
 225 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
 226 * @s:          the AMDTP stream for AM824 data block, must be initialized.
 227 * @runtime:    the PCM substream runtime
 228 *
 229 */
 230int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
 231                                       struct snd_pcm_runtime *runtime)
 232{
 233        int err;
 234
 235        err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
 236        if (err < 0)
 237                return err;
 238
 239        /* AM824 in IEC 61883-6 can deliver 24bit data. */
 240        return snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
 241}
 242EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints);
 243
 244/**
 245 * amdtp_am824_midi_trigger - start/stop playback/capture with a MIDI device
 246 * @s: the AMDTP stream
 247 * @port: index of MIDI port
 248 * @midi: the MIDI device to be started, or %NULL to stop the current device
 249 *
 250 * Call this function on a running isochronous stream to enable the actual
 251 * transmission of MIDI data.  This function should be called from the MIDI
 252 * device's .trigger callback.
 253 */
 254void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
 255                              struct snd_rawmidi_substream *midi)
 256{
 257        struct amdtp_am824 *p = s->protocol;
 258
 259        if (port < p->midi_ports)
 260                WRITE_ONCE(p->midi[port], midi);
 261}
 262EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger);
 263
 264/*
 265 * To avoid sending MIDI bytes at too high a rate, assume that the receiving
 266 * device has a FIFO, and track how much it is filled.  This values increases
 267 * by one whenever we send one byte in a packet, but the FIFO empties at
 268 * a constant rate independent of our packet rate.  One packet has syt_interval
 269 * samples, so the number of bytes that empty out of the FIFO, per packet(!),
 270 * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate.  To avoid storing
 271 * fractional values, the values in midi_fifo_used[] are measured in bytes
 272 * multiplied by the sample rate.
 273 */
 274static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
 275{
 276        struct amdtp_am824 *p = s->protocol;
 277        int used;
 278
 279        used = p->midi_fifo_used[port];
 280        if (used == 0) /* common shortcut */
 281                return true;
 282
 283        used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
 284        used = max(used, 0);
 285        p->midi_fifo_used[port] = used;
 286
 287        return used < p->midi_fifo_limit;
 288}
 289
 290static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
 291{
 292        struct amdtp_am824 *p = s->protocol;
 293
 294        p->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
 295}
 296
 297static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
 298                        unsigned int frames, unsigned int data_block_counter)
 299{
 300        struct amdtp_am824 *p = s->protocol;
 301        unsigned int f, port;
 302        u8 *b;
 303
 304        for (f = 0; f < frames; f++) {
 305                b = (u8 *)&buffer[p->midi_position];
 306
 307                port = (data_block_counter + f) % 8;
 308                if (f < MAX_MIDI_RX_BLOCKS &&
 309                    midi_ratelimit_per_packet(s, port) &&
 310                    p->midi[port] != NULL &&
 311                    snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) {
 312                        midi_rate_use_one_byte(s, port);
 313                        b[0] = 0x81;
 314                } else {
 315                        b[0] = 0x80;
 316                        b[1] = 0;
 317                }
 318                b[2] = 0;
 319                b[3] = 0;
 320
 321                buffer += s->data_block_quadlets;
 322        }
 323}
 324
 325static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
 326                        unsigned int frames, unsigned int data_block_counter)
 327{
 328        struct amdtp_am824 *p = s->protocol;
 329        int len;
 330        u8 *b;
 331        int f;
 332
 333        for (f = 0; f < frames; f++) {
 334                unsigned int port = f;
 335
 336                if (!(s->flags & CIP_UNALIGHED_DBC))
 337                        port += data_block_counter;
 338                port %= 8;
 339                b = (u8 *)&buffer[p->midi_position];
 340
 341                len = b[0] - 0x80;
 342                if ((1 <= len) &&  (len <= 3) && (p->midi[port]))
 343                        snd_rawmidi_receive(p->midi[port], b + 1, len);
 344
 345                buffer += s->data_block_quadlets;
 346        }
 347}
 348
 349static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
 350                                            const struct pkt_desc *descs,
 351                                            unsigned int packets,
 352                                            struct snd_pcm_substream *pcm)
 353{
 354        struct amdtp_am824 *p = s->protocol;
 355        unsigned int pcm_frames = 0;
 356        int i;
 357
 358        for (i = 0; i < packets; ++i) {
 359                const struct pkt_desc *desc = descs + i;
 360                __be32 *buf = desc->ctx_payload;
 361                unsigned int data_blocks = desc->data_blocks;
 362
 363                if (pcm) {
 364                        write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
 365                        pcm_frames += data_blocks * p->frame_multiplier;
 366                } else {
 367                        write_pcm_silence(s, buf, data_blocks);
 368                }
 369
 370                if (p->midi_ports) {
 371                        write_midi_messages(s, buf, data_blocks,
 372                                            desc->data_block_counter);
 373                }
 374        }
 375
 376        return pcm_frames;
 377}
 378
 379static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
 380                                            const struct pkt_desc *descs,
 381                                            unsigned int packets,
 382                                            struct snd_pcm_substream *pcm)
 383{
 384        struct amdtp_am824 *p = s->protocol;
 385        unsigned int pcm_frames = 0;
 386        int i;
 387
 388        for (i = 0; i < packets; ++i) {
 389                const struct pkt_desc *desc = descs + i;
 390                __be32 *buf = desc->ctx_payload;
 391                unsigned int data_blocks = desc->data_blocks;
 392
 393                if (pcm) {
 394                        read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
 395                        pcm_frames += data_blocks * p->frame_multiplier;
 396                }
 397
 398                if (p->midi_ports) {
 399                        read_midi_messages(s, buf, data_blocks,
 400                                           desc->data_block_counter);
 401                }
 402        }
 403
 404        return pcm_frames;
 405}
 406
 407/**
 408 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
 409 *                    data block
 410 * @s: the AMDTP stream to initialize
 411 * @unit: the target of the stream
 412 * @dir: the direction of stream
 413 * @flags: the packet transmission method to use
 414 */
 415int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
 416                     enum amdtp_stream_direction dir, enum cip_flags flags)
 417{
 418        amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
 419
 420        if (dir == AMDTP_IN_STREAM)
 421                process_ctx_payloads = process_ir_ctx_payloads;
 422        else
 423                process_ctx_payloads = process_it_ctx_payloads;
 424
 425        return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
 426                        process_ctx_payloads, sizeof(struct amdtp_am824));
 427}
 428EXPORT_SYMBOL_GPL(amdtp_am824_init);
 429