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-takashi@sakamocchi.jp>
9 #include <sound/pcm.h>
13 #include "amdtp-motu-trace.h"
20 * Nominally 3125 bytes/second, but the MIDI port's clock might be
21 * 1% too slow, and the bus clock 100 ppm too fast.
61 struct amdtp_motu *p = s->protocol; in amdtp_motu_set_parameters()
64 unsigned int mode; in amdtp_motu_set_parameters() local
68 return -EBUSY; in amdtp_motu_set_parameters()
72 mode = i >> 1; in amdtp_motu_set_parameters()
77 return -EINVAL; in amdtp_motu_set_parameters()
82 pcm_chunks = formats->pcm_chunks[mode]; in amdtp_motu_set_parameters()
83 data_chunks = formats->msg_chunks + pcm_chunks; in amdtp_motu_set_parameters()
90 p->pcm_chunks = pcm_chunks; in amdtp_motu_set_parameters()
91 p->pcm_byte_offset = formats->pcm_byte_offset; in amdtp_motu_set_parameters()
93 p->midi_ports = midi_ports; in amdtp_motu_set_parameters()
94 p->midi_flag_offset = formats->midi_flag_offset; in amdtp_motu_set_parameters()
95 p->midi_byte_offset = formats->midi_byte_offset; in amdtp_motu_set_parameters()
97 p->midi_db_count = 0; in amdtp_motu_set_parameters()
98 p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND; in amdtp_motu_set_parameters()
103 /* For no-data or empty packets to adjust PCM sampling frequency. */ in amdtp_motu_set_parameters()
104 delay += 8000 * 3072 * s->syt_interval / rate; in amdtp_motu_set_parameters()
106 p->next_seconds = 0; in amdtp_motu_set_parameters()
107 p->next_cycles = delay / 3072; in amdtp_motu_set_parameters()
108 p->quotient_ticks_per_event = params[s->sfc].quotient_ticks_per_event; in amdtp_motu_set_parameters()
109 p->remainder_ticks_per_event = params[s->sfc].remainder_ticks_per_event; in amdtp_motu_set_parameters()
110 p->next_ticks = delay % 3072; in amdtp_motu_set_parameters()
111 p->next_accumulated = 0; in amdtp_motu_set_parameters()
116 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, in read_pcm_s32() argument
120 struct amdtp_motu *p = s->protocol; in read_pcm_s32()
121 unsigned int channels = p->pcm_chunks; in read_pcm_s32()
122 struct snd_pcm_runtime *runtime = pcm->runtime; in read_pcm_s32()
129 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in read_pcm_s32()
130 pcm_buffer_pointer %= runtime->buffer_size; in read_pcm_s32()
132 dst = (void *)runtime->dma_area + in read_pcm_s32()
134 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in read_pcm_s32()
137 byte = (u8 *)buffer + p->pcm_byte_offset; in read_pcm_s32()
146 buffer += s->data_block_quadlets; in read_pcm_s32()
147 if (--remaining_frames == 0) in read_pcm_s32()
148 dst = (void *)runtime->dma_area; in read_pcm_s32()
152 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, in write_pcm_s32() argument
156 struct amdtp_motu *p = s->protocol; in write_pcm_s32()
157 unsigned int channels = p->pcm_chunks; in write_pcm_s32()
158 struct snd_pcm_runtime *runtime = pcm->runtime; in write_pcm_s32()
165 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in write_pcm_s32()
166 pcm_buffer_pointer %= runtime->buffer_size; in write_pcm_s32()
168 src = (void *)runtime->dma_area + in write_pcm_s32()
170 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in write_pcm_s32()
173 byte = (u8 *)buffer + p->pcm_byte_offset; in write_pcm_s32()
183 buffer += s->data_block_quadlets; in write_pcm_s32()
184 if (--remaining_frames == 0) in write_pcm_s32()
185 src = (void *)runtime->dma_area; in write_pcm_s32()
192 struct amdtp_motu *p = s->protocol; in write_pcm_silence()
196 channels = p->pcm_chunks; in write_pcm_silence()
199 byte = (u8 *)buffer + p->pcm_byte_offset; in write_pcm_silence()
208 buffer += s->data_block_quadlets; in write_pcm_silence()
217 /* TODO: how to set an constraint for exactly 24bit PCM sample? */ in amdtp_motu_add_pcm_hw_constraints()
228 struct amdtp_motu *p = s->protocol; in amdtp_motu_midi_trigger()
230 if (port < p->midi_ports) in amdtp_motu_midi_trigger()
231 WRITE_ONCE(p->midi, midi); in amdtp_motu_midi_trigger()
237 struct amdtp_motu *p = s->protocol; in write_midi_messages()
238 struct snd_rawmidi_substream *midi = READ_ONCE(p->midi); in write_midi_messages()
245 if (midi && p->midi_db_count == 0 && in write_midi_messages()
246 snd_rawmidi_transmit(midi, b + p->midi_byte_offset, 1) == 1) { in write_midi_messages()
247 b[p->midi_flag_offset] = 0x01; in write_midi_messages()
249 b[p->midi_byte_offset] = 0x00; in write_midi_messages()
250 b[p->midi_flag_offset] = 0x00; in write_midi_messages()
253 buffer += s->data_block_quadlets; in write_midi_messages()
255 if (--p->midi_db_count < 0) in write_midi_messages()
256 p->midi_db_count = p->midi_db_interval; in write_midi_messages()
263 struct amdtp_motu *p = s->protocol; in read_midi_messages()
270 midi = READ_ONCE(p->midi); in read_midi_messages()
272 if (midi && (b[p->midi_flag_offset] & 0x01)) in read_midi_messages()
273 snd_rawmidi_receive(midi, b + p->midi_byte_offset, 1); in read_midi_messages()
275 buffer += s->data_block_quadlets; in read_midi_messages()
317 __be32 *buf = desc->ctx_payload; in probe_tracepoints_events()
318 unsigned int data_blocks = desc->data_blocks; in probe_tracepoints_events()
328 struct snd_pcm_substream *pcm) in process_ir_ctx_payloads() argument
330 struct amdtp_motu *p = s->protocol; in process_ir_ctx_payloads()
337 __be32 *buf = desc->ctx_payload; in process_ir_ctx_payloads()
338 unsigned int data_blocks = desc->data_blocks; in process_ir_ctx_payloads()
340 if (pcm) { in process_ir_ctx_payloads()
341 read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); in process_ir_ctx_payloads()
345 if (p->midi_ports) in process_ir_ctx_payloads()
359 p->next_accumulated += p->remainder_ticks_per_event; in compute_next_elapse_from_start()
360 if (p->next_accumulated >= 441) { in compute_next_elapse_from_start()
361 p->next_accumulated -= 441; in compute_next_elapse_from_start()
362 p->next_ticks++; in compute_next_elapse_from_start()
365 p->next_ticks += p->quotient_ticks_per_event; in compute_next_elapse_from_start()
366 if (p->next_ticks >= 3072) { in compute_next_elapse_from_start()
367 p->next_ticks -= 3072; in compute_next_elapse_from_start()
368 p->next_cycles++; in compute_next_elapse_from_start()
371 if (p->next_cycles >= 8000) { in compute_next_elapse_from_start()
372 p->next_cycles -= 8000; in compute_next_elapse_from_start()
373 p->next_seconds++; in compute_next_elapse_from_start()
376 if (p->next_seconds >= 128) in compute_next_elapse_from_start()
377 p->next_seconds -= 128; in compute_next_elapse_from_start()
383 struct amdtp_motu *p = s->protocol; in write_sph()
389 next_cycles = (s->start_cycle + p->next_cycles) % 8000; in write_sph()
390 sph = ((next_cycles << 12) | p->next_ticks) & 0x01ffffff; in write_sph()
395 buffer += s->data_block_quadlets; in write_sph()
402 struct snd_pcm_substream *pcm) in process_it_ctx_payloads() argument
404 struct amdtp_motu *p = s->protocol; in process_it_ctx_payloads()
411 __be32 *buf = desc->ctx_payload; in process_it_ctx_payloads()
412 unsigned int data_blocks = desc->data_blocks; in process_it_ctx_payloads()
414 if (pcm) { in process_it_ctx_payloads()
415 write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); in process_it_ctx_payloads()
421 if (p->midi_ports) in process_it_ctx_payloads()
451 * against IEC 61883-1. in amdtp_motu_init()
453 if (spec->protocol_version == SND_MOTU_PROTOCOL_V3) { in amdtp_motu_init()
476 s->sph = 1; in amdtp_motu_init()
480 s->ctx_data.rx.fdf = MOTU_FDF_AM824; in amdtp_motu_init()
482 s->ctx_data.rx.syt_override = 0xffff; in amdtp_motu_init()