0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009 #include <sound/pcm.h>
0010 #include "motu.h"
0011
0012 #define CREATE_TRACE_POINTS
0013 #include "amdtp-motu-trace.h"
0014
0015 #define CIP_FMT_MOTU 0x02
0016 #define CIP_FMT_MOTU_TX_V3 0x22
0017 #define MOTU_FDF_AM824 0x22
0018
0019 #define TICKS_PER_CYCLE 3072
0020 #define CYCLES_PER_SECOND 8000
0021 #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
0022
0023 #define CIP_SPH_CYCLE_SHIFT 12
0024 #define CIP_SPH_CYCLE_MASK 0x01fff000
0025 #define CIP_SPH_OFFSET_MASK 0x00000fff
0026
0027
0028
0029
0030
0031 #define MIDI_BYTES_PER_SECOND 3093
0032
0033 struct amdtp_motu {
0034 unsigned int pcm_chunks;
0035 unsigned int pcm_byte_offset;
0036
0037 struct snd_rawmidi_substream *midi;
0038 unsigned int midi_ports;
0039 unsigned int midi_flag_offset;
0040 unsigned int midi_byte_offset;
0041
0042 int midi_db_count;
0043 unsigned int midi_db_interval;
0044
0045 struct amdtp_motu_cache *cache;
0046 };
0047
0048 int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
0049 unsigned int midi_ports,
0050 struct snd_motu_packet_format *formats)
0051 {
0052 struct amdtp_motu *p = s->protocol;
0053 unsigned int pcm_chunks, data_chunks, data_block_quadlets;
0054 unsigned int mode;
0055 int i, err;
0056
0057 if (amdtp_stream_running(s))
0058 return -EBUSY;
0059
0060 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
0061 if (snd_motu_clock_rates[i] == rate) {
0062 mode = i >> 1;
0063 break;
0064 }
0065 }
0066 if (i == ARRAY_SIZE(snd_motu_clock_rates))
0067 return -EINVAL;
0068
0069
0070
0071
0072 pcm_chunks = formats->pcm_chunks[mode];
0073 data_chunks = formats->msg_chunks + pcm_chunks;
0074 data_block_quadlets = 1 + DIV_ROUND_UP(data_chunks * 3, 4);
0075
0076 err = amdtp_stream_set_parameters(s, rate, data_block_quadlets);
0077 if (err < 0)
0078 return err;
0079
0080 p->pcm_chunks = pcm_chunks;
0081 p->pcm_byte_offset = formats->pcm_byte_offset;
0082
0083 p->midi_ports = midi_ports;
0084 p->midi_flag_offset = formats->midi_flag_offset;
0085 p->midi_byte_offset = formats->midi_byte_offset;
0086
0087 p->midi_db_count = 0;
0088 p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND;
0089
0090 return 0;
0091 }
0092
0093 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
0094 __be32 *buffer, unsigned int data_blocks,
0095 unsigned int pcm_frames)
0096 {
0097 struct amdtp_motu *p = s->protocol;
0098 unsigned int channels = p->pcm_chunks;
0099 struct snd_pcm_runtime *runtime = pcm->runtime;
0100 unsigned int pcm_buffer_pointer;
0101 int remaining_frames;
0102 u8 *byte;
0103 u32 *dst;
0104 int i, c;
0105
0106 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
0107 pcm_buffer_pointer %= runtime->buffer_size;
0108
0109 dst = (void *)runtime->dma_area +
0110 frames_to_bytes(runtime, pcm_buffer_pointer);
0111 remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
0112
0113 for (i = 0; i < data_blocks; ++i) {
0114 byte = (u8 *)buffer + p->pcm_byte_offset;
0115
0116 for (c = 0; c < channels; ++c) {
0117 *dst = (byte[0] << 24) |
0118 (byte[1] << 16) |
0119 (byte[2] << 8);
0120 byte += 3;
0121 dst++;
0122 }
0123 buffer += s->data_block_quadlets;
0124 if (--remaining_frames == 0)
0125 dst = (void *)runtime->dma_area;
0126 }
0127 }
0128
0129 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
0130 __be32 *buffer, unsigned int data_blocks,
0131 unsigned int pcm_frames)
0132 {
0133 struct amdtp_motu *p = s->protocol;
0134 unsigned int channels = p->pcm_chunks;
0135 struct snd_pcm_runtime *runtime = pcm->runtime;
0136 unsigned int pcm_buffer_pointer;
0137 int remaining_frames;
0138 u8 *byte;
0139 const u32 *src;
0140 int i, c;
0141
0142 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
0143 pcm_buffer_pointer %= runtime->buffer_size;
0144
0145 src = (void *)runtime->dma_area +
0146 frames_to_bytes(runtime, pcm_buffer_pointer);
0147 remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
0148
0149 for (i = 0; i < data_blocks; ++i) {
0150 byte = (u8 *)buffer + p->pcm_byte_offset;
0151
0152 for (c = 0; c < channels; ++c) {
0153 byte[0] = (*src >> 24) & 0xff;
0154 byte[1] = (*src >> 16) & 0xff;
0155 byte[2] = (*src >> 8) & 0xff;
0156 byte += 3;
0157 src++;
0158 }
0159
0160 buffer += s->data_block_quadlets;
0161 if (--remaining_frames == 0)
0162 src = (void *)runtime->dma_area;
0163 }
0164 }
0165
0166 static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer,
0167 unsigned int data_blocks)
0168 {
0169 struct amdtp_motu *p = s->protocol;
0170 unsigned int channels, i, c;
0171 u8 *byte;
0172
0173 channels = p->pcm_chunks;
0174
0175 for (i = 0; i < data_blocks; ++i) {
0176 byte = (u8 *)buffer + p->pcm_byte_offset;
0177
0178 for (c = 0; c < channels; ++c) {
0179 byte[0] = 0;
0180 byte[1] = 0;
0181 byte[2] = 0;
0182 byte += 3;
0183 }
0184
0185 buffer += s->data_block_quadlets;
0186 }
0187 }
0188
0189 int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
0190 struct snd_pcm_runtime *runtime)
0191 {
0192 int err;
0193
0194
0195 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
0196 if (err < 0)
0197 return err;
0198
0199 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
0200 }
0201
0202 void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
0203 struct snd_rawmidi_substream *midi)
0204 {
0205 struct amdtp_motu *p = s->protocol;
0206
0207 if (port < p->midi_ports)
0208 WRITE_ONCE(p->midi, midi);
0209 }
0210
0211 static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
0212 unsigned int data_blocks)
0213 {
0214 struct amdtp_motu *p = s->protocol;
0215 struct snd_rawmidi_substream *midi = READ_ONCE(p->midi);
0216 u8 *b;
0217 int i;
0218
0219 for (i = 0; i < data_blocks; i++) {
0220 b = (u8 *)buffer;
0221
0222 if (midi && p->midi_db_count == 0 &&
0223 snd_rawmidi_transmit(midi, b + p->midi_byte_offset, 1) == 1) {
0224 b[p->midi_flag_offset] = 0x01;
0225 } else {
0226 b[p->midi_byte_offset] = 0x00;
0227 b[p->midi_flag_offset] = 0x00;
0228 }
0229
0230 buffer += s->data_block_quadlets;
0231
0232 if (--p->midi_db_count < 0)
0233 p->midi_db_count = p->midi_db_interval;
0234 }
0235 }
0236
0237 static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
0238 unsigned int data_blocks)
0239 {
0240 struct amdtp_motu *p = s->protocol;
0241 struct snd_rawmidi_substream *midi;
0242 u8 *b;
0243 int i;
0244
0245 for (i = 0; i < data_blocks; i++) {
0246 b = (u8 *)buffer;
0247 midi = READ_ONCE(p->midi);
0248
0249 if (midi && (b[p->midi_flag_offset] & 0x01))
0250 snd_rawmidi_receive(midi, b + p->midi_byte_offset, 1);
0251
0252 buffer += s->data_block_quadlets;
0253 }
0254 }
0255
0256
0257 static void __maybe_unused copy_sph(u32 *frames, __be32 *buffer,
0258 unsigned int data_blocks,
0259 unsigned int data_block_quadlets)
0260 {
0261 unsigned int i;
0262
0263 for (i = 0; i < data_blocks; ++i) {
0264 *frames = be32_to_cpu(*buffer);
0265 buffer += data_block_quadlets;
0266 frames++;
0267 }
0268 }
0269
0270
0271 static void __maybe_unused copy_message(u64 *frames, __be32 *buffer,
0272 unsigned int data_blocks,
0273 unsigned int data_block_quadlets)
0274 {
0275 unsigned int i;
0276
0277
0278 for (i = 0; i < data_blocks; ++i) {
0279 *frames = be32_to_cpu(buffer[1]);
0280 *frames <<= 16;
0281 *frames |= be32_to_cpu(buffer[2]) >> 16;
0282 ++frames;
0283 buffer += data_block_quadlets;
0284 }
0285 }
0286
0287 static void probe_tracepoints_events(struct amdtp_stream *s,
0288 const struct pkt_desc *descs,
0289 unsigned int packets)
0290 {
0291 int i;
0292
0293 for (i = 0; i < packets; ++i) {
0294 const struct pkt_desc *desc = descs + i;
0295 __be32 *buf = desc->ctx_payload;
0296 unsigned int data_blocks = desc->data_blocks;
0297
0298 trace_data_block_sph(s, data_blocks, buf);
0299 trace_data_block_message(s, data_blocks, buf);
0300 }
0301 }
0302
0303 static void cache_event_offsets(struct amdtp_motu_cache *cache, const __be32 *buf,
0304 unsigned int data_blocks, unsigned int data_block_quadlets)
0305 {
0306 unsigned int *event_offsets = cache->event_offsets;
0307 const unsigned int cache_size = cache->size;
0308 unsigned int cache_tail = cache->tail;
0309 unsigned int base_tick = cache->tx_cycle_count * TICKS_PER_CYCLE;
0310 int i;
0311
0312 for (i = 0; i < data_blocks; ++i) {
0313 u32 sph = be32_to_cpu(*buf);
0314 unsigned int tick;
0315
0316 tick = ((sph & CIP_SPH_CYCLE_MASK) >> CIP_SPH_CYCLE_SHIFT) * TICKS_PER_CYCLE +
0317 (sph & CIP_SPH_OFFSET_MASK);
0318
0319 if (tick < base_tick)
0320 tick += TICKS_PER_SECOND;
0321 event_offsets[cache_tail] = tick - base_tick;
0322
0323 cache_tail = (cache_tail + 1) % cache_size;
0324 buf += data_block_quadlets;
0325 }
0326
0327 cache->tail = cache_tail;
0328 cache->tx_cycle_count = (cache->tx_cycle_count + 1) % CYCLES_PER_SECOND;
0329 }
0330
0331 static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
0332 const struct pkt_desc *descs,
0333 unsigned int packets,
0334 struct snd_pcm_substream *pcm)
0335 {
0336 struct snd_motu *motu = container_of(s, struct snd_motu, tx_stream);
0337 struct amdtp_motu *p = s->protocol;
0338 unsigned int pcm_frames = 0;
0339 int i;
0340
0341 if (p->cache->tx_cycle_count == UINT_MAX)
0342 p->cache->tx_cycle_count = (s->domain->processing_cycle.tx_start % CYCLES_PER_SECOND);
0343
0344
0345 for (i = 0; i < packets; ++i) {
0346 const struct pkt_desc *desc = descs + i;
0347 __be32 *buf = desc->ctx_payload;
0348 unsigned int data_blocks = desc->data_blocks;
0349
0350 cache_event_offsets(p->cache, buf, data_blocks, s->data_block_quadlets);
0351
0352 if (pcm) {
0353 read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
0354 pcm_frames += data_blocks;
0355 }
0356
0357 if (p->midi_ports)
0358 read_midi_messages(s, buf, data_blocks);
0359 }
0360
0361 if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) {
0362 snd_motu_register_dsp_message_parser_parse(motu, descs, packets,
0363 s->data_block_quadlets);
0364 } else if (motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP) {
0365 snd_motu_command_dsp_message_parser_parse(motu, descs, packets,
0366 s->data_block_quadlets);
0367 }
0368
0369
0370 if (trace_data_block_sph_enabled() ||
0371 trace_data_block_message_enabled())
0372 probe_tracepoints_events(s, descs, packets);
0373
0374 return pcm_frames;
0375 }
0376
0377 static void write_sph(struct amdtp_motu_cache *cache, __be32 *buffer, unsigned int data_blocks,
0378 unsigned int data_block_quadlets)
0379 {
0380 unsigned int *event_offsets = cache->event_offsets;
0381 const unsigned int cache_size = cache->size;
0382 unsigned int cache_head = cache->head;
0383 unsigned int base_tick = cache->rx_cycle_count * TICKS_PER_CYCLE;
0384 int i;
0385
0386 for (i = 0; i < data_blocks; i++) {
0387 unsigned int tick = (base_tick + event_offsets[cache_head]) % TICKS_PER_SECOND;
0388 u32 sph = ((tick / TICKS_PER_CYCLE) << CIP_SPH_CYCLE_SHIFT) | (tick % TICKS_PER_CYCLE);
0389 *buffer = cpu_to_be32(sph);
0390
0391 cache_head = (cache_head + 1) % cache_size;
0392 buffer += data_block_quadlets;
0393 }
0394
0395 cache->head = cache_head;
0396 cache->rx_cycle_count = (cache->rx_cycle_count + 1) % CYCLES_PER_SECOND;
0397 }
0398
0399 static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
0400 const struct pkt_desc *descs,
0401 unsigned int packets,
0402 struct snd_pcm_substream *pcm)
0403 {
0404 struct amdtp_motu *p = s->protocol;
0405 unsigned int pcm_frames = 0;
0406 int i;
0407
0408 if (p->cache->rx_cycle_count == UINT_MAX)
0409 p->cache->rx_cycle_count = (s->domain->processing_cycle.rx_start % CYCLES_PER_SECOND);
0410
0411
0412 for (i = 0; i < packets; ++i) {
0413 const struct pkt_desc *desc = descs + i;
0414 __be32 *buf = desc->ctx_payload;
0415 unsigned int data_blocks = desc->data_blocks;
0416
0417 if (pcm) {
0418 write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
0419 pcm_frames += data_blocks;
0420 } else {
0421 write_pcm_silence(s, buf, data_blocks);
0422 }
0423
0424 if (p->midi_ports)
0425 write_midi_messages(s, buf, data_blocks);
0426
0427 write_sph(p->cache, buf, data_blocks, s->data_block_quadlets);
0428 }
0429
0430
0431 if (trace_data_block_sph_enabled() ||
0432 trace_data_block_message_enabled())
0433 probe_tracepoints_events(s, descs, packets);
0434
0435 return pcm_frames;
0436 }
0437
0438 int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
0439 enum amdtp_stream_direction dir,
0440 const struct snd_motu_spec *spec, struct amdtp_motu_cache *cache)
0441 {
0442 amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
0443 int fmt = CIP_FMT_MOTU;
0444 unsigned int flags = CIP_BLOCKING | CIP_UNAWARE_SYT;
0445 struct amdtp_motu *p;
0446 int err;
0447
0448 if (dir == AMDTP_IN_STREAM) {
0449 process_ctx_payloads = process_ir_ctx_payloads;
0450
0451
0452
0453
0454
0455 if (spec->protocol_version == SND_MOTU_PROTOCOL_V3) {
0456 flags |= CIP_WRONG_DBS |
0457 CIP_SKIP_DBC_ZERO_CHECK |
0458 CIP_HEADER_WITHOUT_EOH;
0459 fmt = CIP_FMT_MOTU_TX_V3;
0460 }
0461
0462 if (spec == &snd_motu_spec_8pre ||
0463 spec == &snd_motu_spec_ultralite) {
0464
0465 flags |= CIP_WRONG_DBS |
0466 CIP_SKIP_DBC_ZERO_CHECK;
0467 }
0468 } else {
0469 process_ctx_payloads = process_it_ctx_payloads;
0470 flags |= CIP_DBC_IS_END_EVENT;
0471 }
0472
0473 err = amdtp_stream_init(s, unit, dir, flags, fmt, process_ctx_payloads,
0474 sizeof(struct amdtp_motu));
0475 if (err < 0)
0476 return err;
0477
0478 s->sph = 1;
0479
0480 if (dir == AMDTP_OUT_STREAM) {
0481
0482 s->ctx_data.rx.fdf = MOTU_FDF_AM824;
0483 }
0484
0485 p = s->protocol;
0486 p->cache = cache;
0487
0488 return 0;
0489 }