Lines Matching +full:pcm +full:- +full:clock +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-only
3 * amdtp-motu.c - a part of driver for MOTU FireWire series
5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-[email protected]>
9 #include <sound/pcm.h>
13 #include "amdtp-motu-trace.h"
28 * Nominally 3125 bytes/second, but the MIDI port's clock might be
29 * 1% too slow, and the bus clock 100 ppm too fast.
52 struct amdtp_motu *p = s->protocol; in amdtp_motu_set_parameters()
54 unsigned int mode; in amdtp_motu_set_parameters() local
58 return -EBUSY; in amdtp_motu_set_parameters()
62 mode = i >> 1; in amdtp_motu_set_parameters()
67 return -EINVAL; in amdtp_motu_set_parameters()
72 pcm_chunks = formats->pcm_chunks[mode]; in amdtp_motu_set_parameters()
73 data_chunks = formats->msg_chunks + pcm_chunks; in amdtp_motu_set_parameters()
80 p->pcm_chunks = pcm_chunks; in amdtp_motu_set_parameters()
81 p->pcm_byte_offset = formats->pcm_byte_offset; in amdtp_motu_set_parameters()
83 p->midi_ports = midi_ports; in amdtp_motu_set_parameters()
84 p->midi_flag_offset = formats->midi_flag_offset; in amdtp_motu_set_parameters()
85 p->midi_byte_offset = formats->midi_byte_offset; in amdtp_motu_set_parameters()
87 p->midi_db_count = 0; in amdtp_motu_set_parameters()
88 p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND; in amdtp_motu_set_parameters()
93 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, in read_pcm_s32() argument
97 struct amdtp_motu *p = s->protocol; in read_pcm_s32()
98 unsigned int channels = p->pcm_chunks; in read_pcm_s32()
99 struct snd_pcm_runtime *runtime = pcm->runtime; in read_pcm_s32()
106 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in read_pcm_s32()
107 pcm_buffer_pointer %= runtime->buffer_size; in read_pcm_s32()
109 dst = (void *)runtime->dma_area + in read_pcm_s32()
111 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in read_pcm_s32()
114 byte = (u8 *)buffer + p->pcm_byte_offset; in read_pcm_s32()
123 buffer += s->data_block_quadlets; in read_pcm_s32()
124 if (--remaining_frames == 0) in read_pcm_s32()
125 dst = (void *)runtime->dma_area; in read_pcm_s32()
129 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, in write_pcm_s32() argument
133 struct amdtp_motu *p = s->protocol; in write_pcm_s32()
134 unsigned int channels = p->pcm_chunks; in write_pcm_s32()
135 struct snd_pcm_runtime *runtime = pcm->runtime; in write_pcm_s32()
142 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in write_pcm_s32()
143 pcm_buffer_pointer %= runtime->buffer_size; in write_pcm_s32()
145 src = (void *)runtime->dma_area + in write_pcm_s32()
147 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in write_pcm_s32()
150 byte = (u8 *)buffer + p->pcm_byte_offset; in write_pcm_s32()
160 buffer += s->data_block_quadlets; in write_pcm_s32()
161 if (--remaining_frames == 0) in write_pcm_s32()
162 src = (void *)runtime->dma_area; in write_pcm_s32()
169 struct amdtp_motu *p = s->protocol; in write_pcm_silence()
173 channels = p->pcm_chunks; in write_pcm_silence()
176 byte = (u8 *)buffer + p->pcm_byte_offset; in write_pcm_silence()
185 buffer += s->data_block_quadlets; in write_pcm_silence()
194 /* TODO: how to set an constraint for exactly 24bit PCM sample? */ in amdtp_motu_add_pcm_hw_constraints()
205 struct amdtp_motu *p = s->protocol; in amdtp_motu_midi_trigger()
207 if (port < p->midi_ports) in amdtp_motu_midi_trigger()
208 WRITE_ONCE(p->midi, midi); in amdtp_motu_midi_trigger()
214 struct amdtp_motu *p = s->protocol; in write_midi_messages()
215 struct snd_rawmidi_substream *midi = READ_ONCE(p->midi); in write_midi_messages()
222 if (midi && p->midi_db_count == 0 && in write_midi_messages()
223 snd_rawmidi_transmit(midi, b + p->midi_byte_offset, 1) == 1) { in write_midi_messages()
224 b[p->midi_flag_offset] = 0x01; in write_midi_messages()
226 b[p->midi_byte_offset] = 0x00; in write_midi_messages()
227 b[p->midi_flag_offset] = 0x00; in write_midi_messages()
230 buffer += s->data_block_quadlets; in write_midi_messages()
232 if (--p->midi_db_count < 0) in write_midi_messages()
233 p->midi_db_count = p->midi_db_interval; in write_midi_messages()
240 struct amdtp_motu *p = s->protocol; in read_midi_messages()
247 midi = READ_ONCE(p->midi); in read_midi_messages()
249 if (midi && (b[p->midi_flag_offset] & 0x01)) in read_midi_messages()
250 snd_rawmidi_receive(midi, b + p->midi_byte_offset, 1); in read_midi_messages()
252 buffer += s->data_block_quadlets; in read_midi_messages()
293 __be32 *buf = desc->ctx_payload; in probe_tracepoints_events()
294 unsigned int data_blocks = desc->data_blocks; in probe_tracepoints_events()
306 unsigned int *event_offsets = cache->event_offsets; in cache_event_offsets()
307 const unsigned int cache_size = cache->size; in cache_event_offsets()
308 unsigned int cache_tail = cache->tail; in cache_event_offsets()
309 unsigned int base_tick = cache->tx_cycle_count * TICKS_PER_CYCLE; in cache_event_offsets()
321 event_offsets[cache_tail] = tick - base_tick; in cache_event_offsets()
327 cache->tail = cache_tail; in cache_event_offsets()
328 cache->tx_cycle_count = (cache->tx_cycle_count + 1) % CYCLES_PER_SECOND; in cache_event_offsets()
332 unsigned int count, struct snd_pcm_substream *pcm) in process_ir_ctx_payloads() argument
335 struct amdtp_motu *p = s->protocol; in process_ir_ctx_payloads()
340 if (p->cache->tx_cycle_count == UINT_MAX) in process_ir_ctx_payloads()
341 p->cache->tx_cycle_count = (s->domain->processing_cycle.tx_start % CYCLES_PER_SECOND); in process_ir_ctx_payloads()
345 __be32 *buf = desc->ctx_payload; in process_ir_ctx_payloads()
346 unsigned int data_blocks = desc->data_blocks; in process_ir_ctx_payloads()
348 cache_event_offsets(p->cache, buf, data_blocks, s->data_block_quadlets); in process_ir_ctx_payloads()
350 if (pcm) { in process_ir_ctx_payloads()
351 read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); in process_ir_ctx_payloads()
355 if (p->midi_ports) in process_ir_ctx_payloads()
362 if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) in process_ir_ctx_payloads()
364 else if (motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP) in process_ir_ctx_payloads()
376 unsigned int *event_offsets = cache->event_offsets; in write_sph()
377 const unsigned int cache_size = cache->size; in write_sph()
378 unsigned int cache_head = cache->head; in write_sph()
379 unsigned int base_tick = cache->rx_cycle_count * TICKS_PER_CYCLE; in write_sph()
391 cache->head = cache_head; in write_sph()
392 cache->rx_cycle_count = (cache->rx_cycle_count + 1) % CYCLES_PER_SECOND; in write_sph()
396 unsigned int count, struct snd_pcm_substream *pcm) in process_it_ctx_payloads() argument
398 struct amdtp_motu *p = s->protocol; in process_it_ctx_payloads()
403 if (p->cache->rx_cycle_count == UINT_MAX) in process_it_ctx_payloads()
404 p->cache->rx_cycle_count = (s->domain->processing_cycle.rx_start % CYCLES_PER_SECOND); in process_it_ctx_payloads()
408 __be32 *buf = desc->ctx_payload; in process_it_ctx_payloads()
409 unsigned int data_blocks = desc->data_blocks; in process_it_ctx_payloads()
411 if (pcm) { in process_it_ctx_payloads()
412 write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); in process_it_ctx_payloads()
418 if (p->midi_ports) in process_it_ctx_payloads()
421 write_sph(p->cache, buf, data_blocks, s->data_block_quadlets); in process_it_ctx_payloads()
449 * against IEC 61883-1. in amdtp_motu_init()
451 if (spec->protocol_version == SND_MOTU_PROTOCOL_V3) { in amdtp_motu_init()
474 s->sph = 1; in amdtp_motu_init()
478 s->ctx_data.rx.fdf = MOTU_FDF_AM824; in amdtp_motu_init()
481 p = s->protocol; in amdtp_motu_init()
482 p->cache = cache; in amdtp_motu_init()