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