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

1 // SPDX-License-Identifier: GPL-2.0-only
3 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
6 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
11 #include "amdtp-am824.h"
15 /* "Clock-based rate control mode" is just supported. */
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.
42 * amdtp_am824_set_parameters - set stream parameters
45 * @pcm_channels: the number of PCM samples in each data block, to be encoded
46 * as AM824 multi-bit linear audio
47 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
48 * @double_pcm_frames: one data block transfers two PCM frames
58 struct amdtp_am824 *p = s->protocol; in amdtp_am824_set_parameters()
64 return -EINVAL; in amdtp_am824_set_parameters()
67 return -EINVAL; in amdtp_am824_set_parameters()
71 return -EINVAL; in amdtp_am824_set_parameters()
76 return -EINVAL; in amdtp_am824_set_parameters()
79 * In IEC 61883-6, one data block represents one event. In ALSA, one in amdtp_am824_set_parameters()
80 * event equals to one PCM frame. But Dice has a quirk at higher in amdtp_am824_set_parameters()
81 * sampling rate to transfer two PCM frames in one data block. in amdtp_am824_set_parameters()
93 if (s->direction == AMDTP_OUT_STREAM) in amdtp_am824_set_parameters()
94 s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc; in amdtp_am824_set_parameters()
96 p->pcm_channels = pcm_channels; in amdtp_am824_set_parameters()
97 p->midi_ports = midi_ports; in amdtp_am824_set_parameters()
99 /* init the position map for PCM and MIDI channels */ in amdtp_am824_set_parameters()
101 p->pcm_positions[i] = i; in amdtp_am824_set_parameters()
102 p->midi_position = p->pcm_channels; in amdtp_am824_set_parameters()
110 p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1; in amdtp_am824_set_parameters()
117 * amdtp_am824_set_pcm_position - set an index of data channel for a channel
118 * of PCM frame
121 * @position: the channel of PCM frame
126 struct amdtp_am824 *p = s->protocol; in amdtp_am824_set_pcm_position()
128 if (index < p->pcm_channels) in amdtp_am824_set_pcm_position()
129 p->pcm_positions[index] = position; in amdtp_am824_set_pcm_position()
134 * amdtp_am824_set_midi_position - set a index of data channel for MIDI
142 struct amdtp_am824 *p = s->protocol; in amdtp_am824_set_midi_position()
144 p->midi_position = position; in amdtp_am824_set_midi_position()
148 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, in write_pcm_s32() argument
152 struct amdtp_am824 *p = s->protocol; in write_pcm_s32()
153 unsigned int channels = p->pcm_channels; in write_pcm_s32()
154 struct snd_pcm_runtime *runtime = pcm->runtime; in write_pcm_s32()
160 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in write_pcm_s32()
161 pcm_buffer_pointer %= runtime->buffer_size; in write_pcm_s32()
163 src = (void *)runtime->dma_area + in write_pcm_s32()
165 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in write_pcm_s32()
169 buffer[p->pcm_positions[c]] = in write_pcm_s32()
173 buffer += s->data_block_quadlets; in write_pcm_s32()
174 if (--remaining_frames == 0) in write_pcm_s32()
175 src = (void *)runtime->dma_area; in write_pcm_s32()
179 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, in read_pcm_s32() argument
183 struct amdtp_am824 *p = s->protocol; in read_pcm_s32()
184 unsigned int channels = p->pcm_channels; in read_pcm_s32()
185 struct snd_pcm_runtime *runtime = pcm->runtime; in read_pcm_s32()
191 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; in read_pcm_s32()
192 pcm_buffer_pointer %= runtime->buffer_size; in read_pcm_s32()
194 dst = (void *)runtime->dma_area + in read_pcm_s32()
196 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; in read_pcm_s32()
200 *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8; in read_pcm_s32()
203 buffer += s->data_block_quadlets; in read_pcm_s32()
204 if (--remaining_frames == 0) in read_pcm_s32()
205 dst = (void *)runtime->dma_area; in read_pcm_s32()
212 struct amdtp_am824 *p = s->protocol; in write_pcm_silence()
213 unsigned int i, c, channels = p->pcm_channels; in write_pcm_silence()
217 buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000); in write_pcm_silence()
218 buffer += s->data_block_quadlets; in write_pcm_silence()
223 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
225 * @runtime: the PCM substream runtime
237 /* AM824 in IEC 61883-6 can deliver 24bit data. */ in amdtp_am824_add_pcm_hw_constraints()
243 * amdtp_am824_midi_trigger - start/stop playback/capture with a MIDI device
255 struct amdtp_am824 *p = s->protocol; in amdtp_am824_midi_trigger()
257 if (port < p->midi_ports) in amdtp_am824_midi_trigger()
258 WRITE_ONCE(p->midi[port], midi); in amdtp_am824_midi_trigger()
274 struct amdtp_am824 *p = s->protocol; in midi_ratelimit_per_packet()
277 used = p->midi_fifo_used[port]; in midi_ratelimit_per_packet()
281 used -= MIDI_BYTES_PER_SECOND * s->syt_interval; in midi_ratelimit_per_packet()
283 p->midi_fifo_used[port] = used; in midi_ratelimit_per_packet()
285 return used < p->midi_fifo_limit; in midi_ratelimit_per_packet()
290 struct amdtp_am824 *p = s->protocol; in midi_rate_use_one_byte()
292 p->midi_fifo_used[port] += amdtp_rate_table[s->sfc]; in midi_rate_use_one_byte()
298 struct amdtp_am824 *p = s->protocol; in write_midi_messages()
303 b = (u8 *)&buffer[p->midi_position]; in write_midi_messages()
308 p->midi[port] != NULL && in write_midi_messages()
309 snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) { in write_midi_messages()
319 buffer += s->data_block_quadlets; in write_midi_messages()
326 struct amdtp_am824 *p = s->protocol; in read_midi_messages()
334 if (!(s->flags & CIP_UNALIGHED_DBC)) in read_midi_messages()
337 b = (u8 *)&buffer[p->midi_position]; in read_midi_messages()
339 len = b[0] - 0x80; in read_midi_messages()
340 if ((1 <= len) && (len <= 3) && (p->midi[port])) in read_midi_messages()
341 snd_rawmidi_receive(p->midi[port], b + 1, len); in read_midi_messages()
343 buffer += s->data_block_quadlets; in read_midi_messages()
348 unsigned int count, struct snd_pcm_substream *pcm) in process_it_ctx_payloads() argument
350 struct amdtp_am824 *p = s->protocol; in process_it_ctx_payloads()
355 __be32 *buf = desc->ctx_payload; in process_it_ctx_payloads()
356 unsigned int data_blocks = desc->data_blocks; in process_it_ctx_payloads()
358 if (pcm) { in process_it_ctx_payloads()
359 write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); in process_it_ctx_payloads()
360 pcm_frames += data_blocks * s->pcm_frame_multiplier; in process_it_ctx_payloads()
365 if (p->midi_ports) { in process_it_ctx_payloads()
367 desc->data_block_counter); in process_it_ctx_payloads()
375 unsigned int count, struct snd_pcm_substream *pcm) in process_ir_ctx_payloads() argument
377 struct amdtp_am824 *p = s->protocol; in process_ir_ctx_payloads()
382 __be32 *buf = desc->ctx_payload; in process_ir_ctx_payloads()
383 unsigned int data_blocks = desc->data_blocks; in process_ir_ctx_payloads()
385 if (pcm) { in process_ir_ctx_payloads()
386 read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); in process_ir_ctx_payloads()
387 pcm_frames += data_blocks * s->pcm_frame_multiplier; in process_ir_ctx_payloads()
390 if (p->midi_ports) { in process_ir_ctx_payloads()
392 desc->data_block_counter); in process_ir_ctx_payloads()
400 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
405 * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants.