hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/firewire/digi00x/amdtp-dot.c
....@@ -1,11 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * amdtp-dot.c - a part of driver for Digidesign Digi 002/003 family
34 *
45 * Copyright (c) 2014-2015 Takashi Sakamoto
56 * Copyright (C) 2012 Robin Gareus <robin@gareus.org>
67 * Copyright (C) 2012 Damien Zammit <damien@zamaudio.com>
7
- *
8
- * Licensed under the terms of the GNU General Public License, version 2.
98 */
109
1110 #include <sound/pcm.h>
....@@ -128,7 +127,7 @@
128127 if (err < 0)
129128 return err;
130129
131
- s->fdf = AMDTP_FDF_AM824 | s->sfc;
130
+ s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
132131
133132 p->pcm_channels = pcm_channels;
134133
....@@ -144,17 +143,23 @@
144143 }
145144
146145 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
147
- __be32 *buffer, unsigned int frames)
146
+ __be32 *buffer, unsigned int frames,
147
+ unsigned int pcm_frames)
148148 {
149149 struct amdtp_dot *p = s->protocol;
150
+ unsigned int channels = p->pcm_channels;
150151 struct snd_pcm_runtime *runtime = pcm->runtime;
151
- unsigned int channels, remaining_frames, i, c;
152
+ unsigned int pcm_buffer_pointer;
153
+ int remaining_frames;
152154 const u32 *src;
155
+ int i, c;
153156
154
- channels = p->pcm_channels;
157
+ pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
158
+ pcm_buffer_pointer %= runtime->buffer_size;
159
+
155160 src = (void *)runtime->dma_area +
156
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
157
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
161
+ frames_to_bytes(runtime, pcm_buffer_pointer);
162
+ remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
158163
159164 buffer++;
160165 for (i = 0; i < frames; ++i) {
....@@ -170,17 +175,23 @@
170175 }
171176
172177 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
173
- __be32 *buffer, unsigned int frames)
178
+ __be32 *buffer, unsigned int frames,
179
+ unsigned int pcm_frames)
174180 {
175181 struct amdtp_dot *p = s->protocol;
182
+ unsigned int channels = p->pcm_channels;
176183 struct snd_pcm_runtime *runtime = pcm->runtime;
177
- unsigned int channels, remaining_frames, i, c;
184
+ unsigned int pcm_buffer_pointer;
185
+ int remaining_frames;
178186 u32 *dst;
187
+ int i, c;
179188
180
- channels = p->pcm_channels;
189
+ pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
190
+ pcm_buffer_pointer %= runtime->buffer_size;
191
+
181192 dst = (void *)runtime->dma_area +
182
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
183
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
193
+ frames_to_bytes(runtime, pcm_buffer_pointer);
194
+ remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
184195
185196 buffer++;
186197 for (i = 0; i < frames; ++i) {
....@@ -235,7 +246,7 @@
235246 }
236247
237248 static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
238
- unsigned int data_blocks)
249
+ unsigned int data_blocks, unsigned int data_block_counter)
239250 {
240251 struct amdtp_dot *p = s->protocol;
241252 unsigned int f, port;
....@@ -243,7 +254,7 @@
243254 u8 *b;
244255
245256 for (f = 0; f < data_blocks; f++) {
246
- port = (s->data_block_counter + f) % 8;
257
+ port = (data_block_counter + f) % 8;
247258 b = (u8 *)&buffer[0];
248259
249260 len = 0;
....@@ -330,45 +341,53 @@
330341 WRITE_ONCE(p->midi[port], midi);
331342 }
332343
333
-static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
334
- __be32 *buffer,
335
- unsigned int data_blocks,
336
- unsigned int *syt)
344
+static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
345
+ const struct pkt_desc *descs,
346
+ unsigned int packets,
347
+ struct snd_pcm_substream *pcm)
337348 {
338
- struct snd_pcm_substream *pcm;
339
- unsigned int pcm_frames;
349
+ unsigned int pcm_frames = 0;
350
+ int i;
340351
341
- pcm = READ_ONCE(s->pcm);
342
- if (pcm) {
343
- read_pcm_s32(s, pcm, buffer, data_blocks);
344
- pcm_frames = data_blocks;
345
- } else {
346
- pcm_frames = 0;
352
+ for (i = 0; i < packets; ++i) {
353
+ const struct pkt_desc *desc = descs + i;
354
+ __be32 *buf = desc->ctx_payload;
355
+ unsigned int data_blocks = desc->data_blocks;
356
+
357
+ if (pcm) {
358
+ read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
359
+ pcm_frames += data_blocks;
360
+ }
361
+
362
+ read_midi_messages(s, buf, data_blocks);
347363 }
348
-
349
- read_midi_messages(s, buffer, data_blocks);
350364
351365 return pcm_frames;
352366 }
353367
354
-static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
355
- __be32 *buffer,
356
- unsigned int data_blocks,
357
- unsigned int *syt)
368
+static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
369
+ const struct pkt_desc *descs,
370
+ unsigned int packets,
371
+ struct snd_pcm_substream *pcm)
358372 {
359
- struct snd_pcm_substream *pcm;
360
- unsigned int pcm_frames;
373
+ unsigned int pcm_frames = 0;
374
+ int i;
361375
362
- pcm = READ_ONCE(s->pcm);
363
- if (pcm) {
364
- write_pcm_s32(s, pcm, buffer, data_blocks);
365
- pcm_frames = data_blocks;
366
- } else {
367
- write_pcm_silence(s, buffer, data_blocks);
368
- pcm_frames = 0;
376
+ for (i = 0; i < packets; ++i) {
377
+ const struct pkt_desc *desc = descs + i;
378
+ __be32 *buf = desc->ctx_payload;
379
+ unsigned int data_blocks = desc->data_blocks;
380
+
381
+ if (pcm) {
382
+ write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
383
+ pcm_frames += data_blocks;
384
+ } else {
385
+ write_pcm_silence(s, buf, data_blocks);
386
+ }
387
+
388
+ write_midi_messages(s, buf, data_blocks,
389
+ desc->data_block_counter);
369390 }
370
-
371
- write_midi_messages(s, buffer, data_blocks);
372391
373392 return pcm_frames;
374393 }
....@@ -376,20 +395,20 @@
376395 int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
377396 enum amdtp_stream_direction dir)
378397 {
379
- amdtp_stream_process_data_blocks_t process_data_blocks;
398
+ amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
380399 enum cip_flags flags;
381400
382
- /* Use different mode between incoming/outgoing. */
401
+ // Use different mode between incoming/outgoing.
383402 if (dir == AMDTP_IN_STREAM) {
384403 flags = CIP_NONBLOCKING;
385
- process_data_blocks = process_tx_data_blocks;
404
+ process_ctx_payloads = process_ir_ctx_payloads;
386405 } else {
387406 flags = CIP_BLOCKING;
388
- process_data_blocks = process_rx_data_blocks;
407
+ process_ctx_payloads = process_it_ctx_payloads;
389408 }
390409
391410 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
392
- process_data_blocks, sizeof(struct amdtp_dot));
411
+ process_ctx_payloads, sizeof(struct amdtp_dot));
393412 }
394413
395414 void amdtp_dot_reset(struct amdtp_stream *s)