hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/sound/firewire/dice/dice-stream.c
....@@ -1,10 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * dice_stream.c - a part of driver for DICE based devices
34 *
45 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
56 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6
- *
7
- * Licensed under the terms of the GNU General Public License, version 2.
87 */
98
109 #include "dice.h"
....@@ -138,18 +137,9 @@
138137
139138 static void release_resources(struct snd_dice *dice)
140139 {
141
- unsigned int i;
140
+ int i;
142141
143
- for (i = 0; i < MAX_STREAMS; i++) {
144
- if (amdtp_stream_running(&dice->tx_stream[i])) {
145
- amdtp_stream_pcm_abort(&dice->tx_stream[i]);
146
- amdtp_stream_stop(&dice->tx_stream[i]);
147
- }
148
- if (amdtp_stream_running(&dice->rx_stream[i])) {
149
- amdtp_stream_pcm_abort(&dice->rx_stream[i]);
150
- amdtp_stream_stop(&dice->rx_stream[i]);
151
- }
152
-
142
+ for (i = 0; i < MAX_STREAMS; ++i) {
153143 fw_iso_resources_free(&dice->tx_resources[i]);
154144 fw_iso_resources_free(&dice->rx_resources[i]);
155145 }
....@@ -175,35 +165,22 @@
175165 }
176166 }
177167
178
-static int keep_resources(struct snd_dice *dice,
179
- enum amdtp_stream_direction dir, unsigned int index,
180
- unsigned int rate, unsigned int pcm_chs,
181
- unsigned int midi_ports)
168
+static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream,
169
+ struct fw_iso_resources *resources, unsigned int rate,
170
+ unsigned int pcm_chs, unsigned int midi_ports)
182171 {
183
- struct amdtp_stream *stream;
184
- struct fw_iso_resources *resources;
185172 bool double_pcm_frames;
186173 unsigned int i;
187174 int err;
188175
189
- if (dir == AMDTP_IN_STREAM) {
190
- stream = &dice->tx_stream[index];
191
- resources = &dice->tx_resources[index];
192
- } else {
193
- stream = &dice->rx_stream[index];
194
- resources = &dice->rx_resources[index];
195
- }
196
-
197
- /*
198
- * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
199
- * one data block of AMDTP packet. Thus sampling transfer frequency is
200
- * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
201
- * transferred on AMDTP packets at 96 kHz. Two successive samples of a
202
- * channel are stored consecutively in the packet. This quirk is called
203
- * as 'Dual Wire'.
204
- * For this quirk, blocking mode is required and PCM buffer size should
205
- * be aligned to SYT_INTERVAL.
206
- */
176
+ // At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
177
+ // one data block of AMDTP packet. Thus sampling transfer frequency is
178
+ // a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
179
+ // transferred on AMDTP packets at 96 kHz. Two successive samples of a
180
+ // channel are stored consecutively in the packet. This quirk is called
181
+ // as 'Dual Wire'.
182
+ // For this quirk, blocking mode is required and PCM buffer size should
183
+ // be aligned to SYT_INTERVAL.
207184 double_pcm_frames = rate > 96000;
208185 if (double_pcm_frames) {
209186 rate /= 2;
....@@ -230,42 +207,39 @@
230207 fw_parent_device(dice->unit)->max_speed);
231208 }
232209
233
-static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
234
- unsigned int rate, struct reg_params *params)
210
+static int keep_dual_resources(struct snd_dice *dice, unsigned int rate,
211
+ enum amdtp_stream_direction dir,
212
+ struct reg_params *params)
235213 {
236
- __be32 reg[2];
237214 enum snd_dice_rate_mode mode;
238
- unsigned int i, pcm_chs, midi_ports;
239
- struct amdtp_stream *streams;
240
- struct fw_iso_resources *resources;
241
- struct fw_device *fw_dev = fw_parent_device(dice->unit);
242
- int err = 0;
243
-
244
- if (dir == AMDTP_IN_STREAM) {
245
- streams = dice->tx_stream;
246
- resources = dice->tx_resources;
247
- } else {
248
- streams = dice->rx_stream;
249
- resources = dice->rx_resources;
250
- }
215
+ int i;
216
+ int err;
251217
252218 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
253219 if (err < 0)
254220 return err;
255221
256
- for (i = 0; i < params->count; i++) {
222
+ for (i = 0; i < params->count; ++i) {
223
+ __be32 reg[2];
224
+ struct amdtp_stream *stream;
225
+ struct fw_iso_resources *resources;
257226 unsigned int pcm_cache;
258
- unsigned int midi_cache;
227
+ unsigned int pcm_chs;
228
+ unsigned int midi_ports;
259229
260230 if (dir == AMDTP_IN_STREAM) {
231
+ stream = &dice->tx_stream[i];
232
+ resources = &dice->tx_resources[i];
233
+
261234 pcm_cache = dice->tx_pcm_chs[i][mode];
262
- midi_cache = dice->tx_midi_ports[i];
263235 err = snd_dice_transaction_read_tx(dice,
264236 params->size * i + TX_NUMBER_AUDIO,
265237 reg, sizeof(reg));
266238 } else {
239
+ stream = &dice->rx_stream[i];
240
+ resources = &dice->rx_resources[i];
241
+
267242 pcm_cache = dice->rx_pcm_chs[i][mode];
268
- midi_cache = dice->rx_midi_ports[i];
269243 err = snd_dice_transaction_read_rx(dice,
270244 params->size * i + RX_NUMBER_AUDIO,
271245 reg, sizeof(reg));
....@@ -275,109 +249,142 @@
275249 pcm_chs = be32_to_cpu(reg[0]);
276250 midi_ports = be32_to_cpu(reg[1]);
277251
278
- /* These are important for developer of this driver. */
279
- if (pcm_chs != pcm_cache || midi_ports != midi_cache) {
252
+ // These are important for developer of this driver.
253
+ if (pcm_chs != pcm_cache) {
280254 dev_info(&dice->unit->device,
281
- "cache mismatch: pcm: %u:%u, midi: %u:%u\n",
282
- pcm_chs, pcm_cache, midi_ports, midi_cache);
255
+ "cache mismatch: pcm: %u:%u, midi: %u\n",
256
+ pcm_chs, pcm_cache, midi_ports);
283257 return -EPROTO;
284258 }
285259
286
- err = keep_resources(dice, dir, i, rate, pcm_chs, midi_ports);
287
- if (err < 0)
288
- return err;
289
-
290
- reg[0] = cpu_to_be32(resources[i].channel);
291
- if (dir == AMDTP_IN_STREAM) {
292
- err = snd_dice_transaction_write_tx(dice,
293
- params->size * i + TX_ISOCHRONOUS,
294
- reg, sizeof(reg[0]));
295
- } else {
296
- err = snd_dice_transaction_write_rx(dice,
297
- params->size * i + RX_ISOCHRONOUS,
298
- reg, sizeof(reg[0]));
299
- }
300
- if (err < 0)
301
- return err;
302
-
303
- if (dir == AMDTP_IN_STREAM) {
304
- reg[0] = cpu_to_be32(fw_dev->max_speed);
305
- err = snd_dice_transaction_write_tx(dice,
306
- params->size * i + TX_SPEED,
307
- reg, sizeof(reg[0]));
308
- if (err < 0)
309
- return err;
310
- }
311
-
312
- err = amdtp_stream_start(&streams[i], resources[i].channel,
313
- fw_dev->max_speed);
260
+ err = keep_resources(dice, stream, resources, rate, pcm_chs,
261
+ midi_ports);
314262 if (err < 0)
315263 return err;
316264 }
317265
318
- return err;
266
+ return 0;
319267 }
320268
321
-static int start_duplex_streams(struct snd_dice *dice, unsigned int rate)
269
+static void finish_session(struct snd_dice *dice, struct reg_params *tx_params,
270
+ struct reg_params *rx_params)
322271 {
323
- struct reg_params tx_params, rx_params;
324
- int i;
272
+ stop_streams(dice, AMDTP_IN_STREAM, tx_params);
273
+ stop_streams(dice, AMDTP_OUT_STREAM, rx_params);
274
+
275
+ snd_dice_transaction_clear_enable(dice);
276
+}
277
+
278
+int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate,
279
+ unsigned int events_per_period,
280
+ unsigned int events_per_buffer)
281
+{
282
+ unsigned int curr_rate;
325283 int err;
326284
327
- err = get_register_params(dice, &tx_params, &rx_params);
285
+ // Check sampling transmission frequency.
286
+ err = snd_dice_transaction_get_rate(dice, &curr_rate);
328287 if (err < 0)
329288 return err;
289
+ if (rate == 0)
290
+ rate = curr_rate;
330291
331
- /* Stop transmission. */
332
- stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
333
- stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
334
- snd_dice_transaction_clear_enable(dice);
335
- release_resources(dice);
292
+ if (dice->substreams_counter == 0 || curr_rate != rate) {
293
+ struct reg_params tx_params, rx_params;
336294
337
- err = ensure_phase_lock(dice, rate);
338
- if (err < 0) {
339
- dev_err(&dice->unit->device, "fail to ensure phase lock\n");
340
- return err;
341
- }
295
+ amdtp_domain_stop(&dice->domain);
342296
343
- /* Likely to have changed stream formats. */
344
- err = get_register_params(dice, &tx_params, &rx_params);
345
- if (err < 0)
346
- return err;
297
+ err = get_register_params(dice, &tx_params, &rx_params);
298
+ if (err < 0)
299
+ return err;
300
+ finish_session(dice, &tx_params, &rx_params);
347301
348
- /* Start both streams. */
349
- err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params);
350
- if (err < 0)
351
- goto error;
352
- err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params);
353
- if (err < 0)
354
- goto error;
302
+ release_resources(dice);
355303
356
- err = snd_dice_transaction_set_enable(dice);
357
- if (err < 0) {
358
- dev_err(&dice->unit->device, "fail to enable interface\n");
359
- goto error;
360
- }
304
+ // Just after owning the unit (GLOBAL_OWNER), the unit can
305
+ // return invalid stream formats. Selecting clock parameters
306
+ // have an effect for the unit to refine it.
307
+ err = ensure_phase_lock(dice, rate);
308
+ if (err < 0)
309
+ return err;
361310
362
- for (i = 0; i < MAX_STREAMS; i++) {
363
- if ((i < tx_params.count &&
364
- !amdtp_stream_wait_callback(&dice->tx_stream[i],
365
- CALLBACK_TIMEOUT)) ||
366
- (i < rx_params.count &&
367
- !amdtp_stream_wait_callback(&dice->rx_stream[i],
368
- CALLBACK_TIMEOUT))) {
369
- err = -ETIMEDOUT;
311
+ // After changing sampling transfer frequency, the value of
312
+ // register can be changed.
313
+ err = get_register_params(dice, &tx_params, &rx_params);
314
+ if (err < 0)
315
+ return err;
316
+
317
+ err = keep_dual_resources(dice, rate, AMDTP_IN_STREAM,
318
+ &tx_params);
319
+ if (err < 0)
370320 goto error;
371
- }
321
+
322
+ err = keep_dual_resources(dice, rate, AMDTP_OUT_STREAM,
323
+ &rx_params);
324
+ if (err < 0)
325
+ goto error;
326
+
327
+ err = amdtp_domain_set_events_per_period(&dice->domain,
328
+ events_per_period, events_per_buffer);
329
+ if (err < 0)
330
+ goto error;
372331 }
373332
374333 return 0;
375334 error:
376
- stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
377
- stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
378
- snd_dice_transaction_clear_enable(dice);
379335 release_resources(dice);
380336 return err;
337
+}
338
+
339
+static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
340
+ unsigned int rate, struct reg_params *params)
341
+{
342
+ unsigned int max_speed = fw_parent_device(dice->unit)->max_speed;
343
+ int i;
344
+ int err;
345
+
346
+ for (i = 0; i < params->count; i++) {
347
+ struct amdtp_stream *stream;
348
+ struct fw_iso_resources *resources;
349
+ __be32 reg;
350
+
351
+ if (dir == AMDTP_IN_STREAM) {
352
+ stream = dice->tx_stream + i;
353
+ resources = dice->tx_resources + i;
354
+ } else {
355
+ stream = dice->rx_stream + i;
356
+ resources = dice->rx_resources + i;
357
+ }
358
+
359
+ reg = cpu_to_be32(resources->channel);
360
+ if (dir == AMDTP_IN_STREAM) {
361
+ err = snd_dice_transaction_write_tx(dice,
362
+ params->size * i + TX_ISOCHRONOUS,
363
+ &reg, sizeof(reg));
364
+ } else {
365
+ err = snd_dice_transaction_write_rx(dice,
366
+ params->size * i + RX_ISOCHRONOUS,
367
+ &reg, sizeof(reg));
368
+ }
369
+ if (err < 0)
370
+ return err;
371
+
372
+ if (dir == AMDTP_IN_STREAM) {
373
+ reg = cpu_to_be32(max_speed);
374
+ err = snd_dice_transaction_write_tx(dice,
375
+ params->size * i + TX_SPEED,
376
+ &reg, sizeof(reg));
377
+ if (err < 0)
378
+ return err;
379
+ }
380
+
381
+ err = amdtp_domain_add_stream(&dice->domain, stream,
382
+ resources->channel, max_speed);
383
+ if (err < 0)
384
+ return err;
385
+ }
386
+
387
+ return 0;
381388 }
382389
383390 /*
....@@ -385,39 +392,45 @@
385392 * - None streams are running.
386393 * - All streams are running.
387394 */
388
-int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
395
+int snd_dice_stream_start_duplex(struct snd_dice *dice)
389396 {
390
- unsigned int curr_rate;
397
+ unsigned int generation = dice->rx_resources[0].generation;
398
+ struct reg_params tx_params, rx_params;
391399 unsigned int i;
400
+ unsigned int rate;
392401 enum snd_dice_rate_mode mode;
393402 int err;
394403
395404 if (dice->substreams_counter == 0)
396405 return -EIO;
397406
398
- /* Check sampling transmission frequency. */
399
- err = snd_dice_transaction_get_rate(dice, &curr_rate);
400
- if (err < 0) {
401
- dev_err(&dice->unit->device,
402
- "fail to get sampling rate\n");
407
+ err = get_register_params(dice, &tx_params, &rx_params);
408
+ if (err < 0)
403409 return err;
404
- }
405
- if (rate == 0)
406
- rate = curr_rate;
407
- if (rate != curr_rate)
408
- goto restart;
409410
410
- /* Check error of packet streaming. */
411
+ // Check error of packet streaming.
411412 for (i = 0; i < MAX_STREAMS; ++i) {
412
- if (amdtp_streaming_error(&dice->tx_stream[i]))
413
+ if (amdtp_streaming_error(&dice->tx_stream[i]) ||
414
+ amdtp_streaming_error(&dice->rx_stream[i])) {
415
+ amdtp_domain_stop(&dice->domain);
416
+ finish_session(dice, &tx_params, &rx_params);
413417 break;
414
- if (amdtp_streaming_error(&dice->rx_stream[i]))
415
- break;
418
+ }
416419 }
417
- if (i < MAX_STREAMS)
418
- goto restart;
419420
420
- /* Check required streams are running or not. */
421
+ if (generation != fw_parent_device(dice->unit)->card->generation) {
422
+ for (i = 0; i < MAX_STREAMS; ++i) {
423
+ if (i < tx_params.count)
424
+ fw_iso_resources_update(dice->tx_resources + i);
425
+ if (i < rx_params.count)
426
+ fw_iso_resources_update(dice->rx_resources + i);
427
+ }
428
+ }
429
+
430
+ // Check required streams are running or not.
431
+ err = snd_dice_transaction_get_rate(dice, &rate);
432
+ if (err < 0)
433
+ return err;
421434 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
422435 if (err < 0)
423436 return err;
....@@ -429,12 +442,45 @@
429442 !amdtp_stream_running(&dice->rx_stream[i]))
430443 break;
431444 }
432
- if (i < MAX_STREAMS)
433
- goto restart;
445
+ if (i < MAX_STREAMS) {
446
+ // Start both streams.
447
+ err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params);
448
+ if (err < 0)
449
+ goto error;
450
+
451
+ err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params);
452
+ if (err < 0)
453
+ goto error;
454
+
455
+ err = snd_dice_transaction_set_enable(dice);
456
+ if (err < 0) {
457
+ dev_err(&dice->unit->device,
458
+ "fail to enable interface\n");
459
+ goto error;
460
+ }
461
+
462
+ err = amdtp_domain_start(&dice->domain, 0);
463
+ if (err < 0)
464
+ goto error;
465
+
466
+ for (i = 0; i < MAX_STREAMS; i++) {
467
+ if ((i < tx_params.count &&
468
+ !amdtp_stream_wait_callback(&dice->tx_stream[i],
469
+ CALLBACK_TIMEOUT)) ||
470
+ (i < rx_params.count &&
471
+ !amdtp_stream_wait_callback(&dice->rx_stream[i],
472
+ CALLBACK_TIMEOUT))) {
473
+ err = -ETIMEDOUT;
474
+ goto error;
475
+ }
476
+ }
477
+ }
434478
435479 return 0;
436
-restart:
437
- return start_duplex_streams(dice, rate);
480
+error:
481
+ amdtp_domain_stop(&dice->domain);
482
+ finish_session(dice, &tx_params, &rx_params);
483
+ return err;
438484 }
439485
440486 /*
....@@ -446,17 +492,13 @@
446492 {
447493 struct reg_params tx_params, rx_params;
448494
449
- if (dice->substreams_counter > 0)
450
- return;
495
+ if (dice->substreams_counter == 0) {
496
+ if (get_register_params(dice, &tx_params, &rx_params) >= 0)
497
+ finish_session(dice, &tx_params, &rx_params);
451498
452
- snd_dice_transaction_clear_enable(dice);
453
-
454
- if (get_register_params(dice, &tx_params, &rx_params) == 0) {
455
- stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
456
- stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
499
+ amdtp_domain_stop(&dice->domain);
500
+ release_resources(dice);
457501 }
458
-
459
- release_resources(dice);
460502 }
461503
462504 static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir,
....@@ -531,7 +573,15 @@
531573 destroy_stream(dice, AMDTP_OUT_STREAM, i);
532574 for (i = 0; i < MAX_STREAMS; i++)
533575 destroy_stream(dice, AMDTP_IN_STREAM, i);
534
- break;
576
+ goto end;
577
+ }
578
+ }
579
+
580
+ err = amdtp_domain_init(&dice->domain);
581
+ if (err < 0) {
582
+ for (i = 0; i < MAX_STREAMS; ++i) {
583
+ destroy_stream(dice, AMDTP_OUT_STREAM, i);
584
+ destroy_stream(dice, AMDTP_IN_STREAM, i);
535585 }
536586 }
537587 end:
....@@ -546,6 +596,8 @@
546596 destroy_stream(dice, AMDTP_IN_STREAM, i);
547597 destroy_stream(dice, AMDTP_OUT_STREAM, i);
548598 }
599
+
600
+ amdtp_domain_destroy(&dice->domain);
549601 }
550602
551603 void snd_dice_stream_update_duplex(struct snd_dice *dice)
....@@ -563,6 +615,8 @@
563615 dice->global_enabled = false;
564616
565617 if (get_register_params(dice, &tx_params, &rx_params) == 0) {
618
+ amdtp_domain_stop(&dice->domain);
619
+
566620 stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
567621 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
568622 }