hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/firewire/bebob/bebob_stream.c
....@@ -1,14 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * bebob_stream.c - a part of driver for BeBoB based devices
34 *
45 * Copyright (c) 2013-2014 Takashi Sakamoto
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include "./bebob.h"
109
11
-#define CALLBACK_TIMEOUT 2000
10
+#define CALLBACK_TIMEOUT 2500
1211 #define FW_ISO_RESOURCE_DELAY 1000
1312
1413 /*
....@@ -376,24 +375,6 @@
376375 }
377376
378377 static int
379
-init_both_connections(struct snd_bebob *bebob)
380
-{
381
- int err;
382
-
383
- err = cmp_connection_init(&bebob->in_conn,
384
- bebob->unit, CMP_INPUT, 0);
385
- if (err < 0)
386
- goto end;
387
-
388
- err = cmp_connection_init(&bebob->out_conn,
389
- bebob->unit, CMP_OUTPUT, 0);
390
- if (err < 0)
391
- cmp_connection_destroy(&bebob->in_conn);
392
-end:
393
- return err;
394
-}
395
-
396
-static int
397378 check_connection_used_by_others(struct snd_bebob *bebob, struct amdtp_stream *s)
398379 {
399380 struct cmp_connection *conn;
....@@ -417,74 +398,19 @@
417398 return err;
418399 }
419400
420
-static int
421
-make_both_connections(struct snd_bebob *bebob, unsigned int rate)
422
-{
423
- int index, pcm_channels, midi_channels, err = 0;
424
-
425
- if (bebob->connected)
426
- goto end;
427
-
428
- /* confirm params for both streams */
429
- err = get_formation_index(rate, &index);
430
- if (err < 0)
431
- goto end;
432
- pcm_channels = bebob->tx_stream_formations[index].pcm;
433
- midi_channels = bebob->tx_stream_formations[index].midi;
434
- err = amdtp_am824_set_parameters(&bebob->tx_stream, rate,
435
- pcm_channels, midi_channels * 8,
436
- false);
437
- if (err < 0)
438
- goto end;
439
-
440
- pcm_channels = bebob->rx_stream_formations[index].pcm;
441
- midi_channels = bebob->rx_stream_formations[index].midi;
442
- err = amdtp_am824_set_parameters(&bebob->rx_stream, rate,
443
- pcm_channels, midi_channels * 8,
444
- false);
445
- if (err < 0)
446
- goto end;
447
-
448
- /* establish connections for both streams */
449
- err = cmp_connection_establish(&bebob->out_conn,
450
- amdtp_stream_get_max_payload(&bebob->tx_stream));
451
- if (err < 0)
452
- goto end;
453
- err = cmp_connection_establish(&bebob->in_conn,
454
- amdtp_stream_get_max_payload(&bebob->rx_stream));
455
- if (err < 0) {
456
- cmp_connection_break(&bebob->out_conn);
457
- goto end;
458
- }
459
-
460
- bebob->connected = true;
461
-end:
462
- return err;
463
-}
464
-
465
-static void
466
-break_both_connections(struct snd_bebob *bebob)
401
+static void break_both_connections(struct snd_bebob *bebob)
467402 {
468403 cmp_connection_break(&bebob->in_conn);
469404 cmp_connection_break(&bebob->out_conn);
470405
471
- bebob->connected = false;
472
-
473
- /* These models seems to be in transition state for a longer time. */
474
- if (bebob->maudio_special_quirk != NULL)
475
- msleep(200);
406
+ // These models seem to be in transition state for a longer time. When
407
+ // accessing in the state, any transactions is corrupted. In the worst
408
+ // case, the device is going to reboot.
409
+ if (bebob->version < 2)
410
+ msleep(600);
476411 }
477412
478
-static void
479
-destroy_both_connections(struct snd_bebob *bebob)
480
-{
481
- cmp_connection_destroy(&bebob->in_conn);
482
- cmp_connection_destroy(&bebob->out_conn);
483
-}
484
-
485
-static int
486
-start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream,
487
- unsigned int rate)
413
+static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
488414 {
489415 struct cmp_connection *conn;
490416 int err = 0;
....@@ -494,205 +420,294 @@
494420 else
495421 conn = &bebob->out_conn;
496422
497
- /* channel mapping */
423
+ // channel mapping.
498424 if (bebob->maudio_special_quirk == NULL) {
499425 err = map_data_channels(bebob, stream);
500426 if (err < 0)
501
- goto end;
427
+ return err;
502428 }
503429
504
- /* start amdtp stream */
505
- err = amdtp_stream_start(stream,
506
- conn->resources.channel,
507
- conn->speed);
508
-end:
509
- return err;
430
+ err = cmp_connection_establish(conn);
431
+ if (err < 0)
432
+ return err;
433
+
434
+ return amdtp_domain_add_stream(&bebob->domain, stream,
435
+ conn->resources.channel, conn->speed);
436
+}
437
+
438
+static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
439
+{
440
+ enum amdtp_stream_direction dir_stream;
441
+ struct cmp_connection *conn;
442
+ enum cmp_direction dir_conn;
443
+ int err;
444
+
445
+ if (stream == &bebob->tx_stream) {
446
+ dir_stream = AMDTP_IN_STREAM;
447
+ conn = &bebob->out_conn;
448
+ dir_conn = CMP_OUTPUT;
449
+ } else {
450
+ dir_stream = AMDTP_OUT_STREAM;
451
+ conn = &bebob->in_conn;
452
+ dir_conn = CMP_INPUT;
453
+ }
454
+
455
+ err = cmp_connection_init(conn, bebob->unit, dir_conn, 0);
456
+ if (err < 0)
457
+ return err;
458
+
459
+ err = amdtp_am824_init(stream, bebob->unit, dir_stream, CIP_BLOCKING);
460
+ if (err < 0) {
461
+ cmp_connection_destroy(conn);
462
+ return err;
463
+ }
464
+
465
+ if (stream == &bebob->tx_stream) {
466
+ // BeBoB v3 transfers packets with these qurks:
467
+ // - In the beginning of streaming, the value of dbc is
468
+ // incremented even if no data blocks are transferred.
469
+ // - The value of dbc is reset suddenly.
470
+ if (bebob->version > 2)
471
+ bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC |
472
+ CIP_SKIP_DBC_ZERO_CHECK;
473
+
474
+ // At high sampling rate, M-Audio special firmware transmits
475
+ // empty packet with the value of dbc incremented by 8 but the
476
+ // others are valid to IEC 61883-1.
477
+ if (bebob->maudio_special_quirk)
478
+ bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
479
+ }
480
+
481
+ return 0;
482
+}
483
+
484
+static void destroy_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
485
+{
486
+ amdtp_stream_destroy(stream);
487
+
488
+ if (stream == &bebob->tx_stream)
489
+ cmp_connection_destroy(&bebob->out_conn);
490
+ else
491
+ cmp_connection_destroy(&bebob->in_conn);
510492 }
511493
512494 int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
513495 {
514496 int err;
515497
516
- err = init_both_connections(bebob);
498
+ err = init_stream(bebob, &bebob->tx_stream);
517499 if (err < 0)
518
- goto end;
500
+ return err;
519501
520
- err = amdtp_am824_init(&bebob->tx_stream, bebob->unit,
521
- AMDTP_IN_STREAM, CIP_BLOCKING);
502
+ err = init_stream(bebob, &bebob->rx_stream);
522503 if (err < 0) {
523
- amdtp_stream_destroy(&bebob->tx_stream);
524
- destroy_both_connections(bebob);
525
- goto end;
504
+ destroy_stream(bebob, &bebob->tx_stream);
505
+ return err;
526506 }
527507
528
- /*
529
- * BeBoB v3 transfers packets with these qurks:
530
- * - In the beginning of streaming, the value of dbc is incremented
531
- * even if no data blocks are transferred.
532
- * - The value of dbc is reset suddenly.
533
- */
534
- if (bebob->version > 2)
535
- bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC |
536
- CIP_SKIP_DBC_ZERO_CHECK;
537
-
538
- /*
539
- * At high sampling rate, M-Audio special firmware transmits empty
540
- * packet with the value of dbc incremented by 8 but the others are
541
- * valid to IEC 61883-1.
542
- */
543
- if (bebob->maudio_special_quirk)
544
- bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
545
-
546
- err = amdtp_am824_init(&bebob->rx_stream, bebob->unit,
547
- AMDTP_OUT_STREAM, CIP_BLOCKING);
508
+ err = amdtp_domain_init(&bebob->domain);
548509 if (err < 0) {
549
- amdtp_stream_destroy(&bebob->tx_stream);
550
- amdtp_stream_destroy(&bebob->rx_stream);
551
- destroy_both_connections(bebob);
510
+ destroy_stream(bebob, &bebob->tx_stream);
511
+ destroy_stream(bebob, &bebob->rx_stream);
552512 }
553
-end:
513
+
554514 return err;
555515 }
556516
557
-int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
517
+static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
518
+ unsigned int rate, unsigned int index)
558519 {
559
- const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
520
+ unsigned int pcm_channels;
521
+ unsigned int midi_ports;
522
+ struct cmp_connection *conn;
523
+ int err;
524
+
525
+ if (stream == &bebob->tx_stream) {
526
+ pcm_channels = bebob->tx_stream_formations[index].pcm;
527
+ midi_ports = bebob->midi_input_ports;
528
+ conn = &bebob->out_conn;
529
+ } else {
530
+ pcm_channels = bebob->rx_stream_formations[index].pcm;
531
+ midi_ports = bebob->midi_output_ports;
532
+ conn = &bebob->in_conn;
533
+ }
534
+
535
+ err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false);
536
+ if (err < 0)
537
+ return err;
538
+
539
+ return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
540
+}
541
+
542
+int snd_bebob_stream_reserve_duplex(struct snd_bebob *bebob, unsigned int rate,
543
+ unsigned int frames_per_period,
544
+ unsigned int frames_per_buffer)
545
+{
560546 unsigned int curr_rate;
561
- int err = 0;
547
+ int err;
562548
563
- /* Need no substreams */
564
- if (bebob->substreams_counter == 0)
565
- goto end;
566
-
567
- /*
568
- * Considering JACK/FFADO streaming:
569
- * TODO: This can be removed hwdep functionality becomes popular.
570
- */
549
+ // Considering JACK/FFADO streaming:
550
+ // TODO: This can be removed hwdep functionality becomes popular.
571551 err = check_connection_used_by_others(bebob, &bebob->rx_stream);
572552 if (err < 0)
573
- goto end;
553
+ return err;
574554
575
- /*
576
- * packet queueing error or detecting discontinuity
577
- *
578
- * At bus reset, connections should not be broken here. So streams need
579
- * to be re-started. This is a reason to use SKIP_INIT_DBC_CHECK flag.
580
- */
581
- if (amdtp_streaming_error(&bebob->rx_stream))
582
- amdtp_stream_stop(&bebob->rx_stream);
583
- if (amdtp_streaming_error(&bebob->tx_stream))
584
- amdtp_stream_stop(&bebob->tx_stream);
585
- if (!amdtp_stream_running(&bebob->rx_stream) &&
586
- !amdtp_stream_running(&bebob->tx_stream))
587
- break_both_connections(bebob);
588
-
589
- /* stop streams if rate is different */
590
- err = rate_spec->get(bebob, &curr_rate);
591
- if (err < 0) {
592
- dev_err(&bebob->unit->device,
593
- "fail to get sampling rate: %d\n", err);
594
- goto end;
595
- }
555
+ err = bebob->spec->rate->get(bebob, &curr_rate);
556
+ if (err < 0)
557
+ return err;
596558 if (rate == 0)
597559 rate = curr_rate;
598
- if (rate != curr_rate) {
599
- amdtp_stream_stop(&bebob->rx_stream);
600
- amdtp_stream_stop(&bebob->tx_stream);
560
+ if (curr_rate != rate) {
561
+ amdtp_domain_stop(&bebob->domain);
562
+ break_both_connections(bebob);
563
+
564
+ cmp_connection_release(&bebob->out_conn);
565
+ cmp_connection_release(&bebob->in_conn);
566
+ }
567
+
568
+ if (bebob->substreams_counter == 0 || curr_rate != rate) {
569
+ unsigned int index;
570
+
571
+ // NOTE:
572
+ // If establishing connections at first, Yamaha GO46
573
+ // (and maybe Terratec X24) don't generate sound.
574
+ //
575
+ // For firmware customized by M-Audio, refer to next NOTE.
576
+ err = bebob->spec->rate->set(bebob, rate);
577
+ if (err < 0) {
578
+ dev_err(&bebob->unit->device,
579
+ "fail to set sampling rate: %d\n",
580
+ err);
581
+ return err;
582
+ }
583
+
584
+ err = get_formation_index(rate, &index);
585
+ if (err < 0)
586
+ return err;
587
+
588
+ err = keep_resources(bebob, &bebob->tx_stream, rate, index);
589
+ if (err < 0)
590
+ return err;
591
+
592
+ err = keep_resources(bebob, &bebob->rx_stream, rate, index);
593
+ if (err < 0) {
594
+ cmp_connection_release(&bebob->out_conn);
595
+ return err;
596
+ }
597
+
598
+ err = amdtp_domain_set_events_per_period(&bebob->domain,
599
+ frames_per_period, frames_per_buffer);
600
+ if (err < 0) {
601
+ cmp_connection_release(&bebob->out_conn);
602
+ cmp_connection_release(&bebob->in_conn);
603
+ return err;
604
+ }
605
+ }
606
+
607
+ return 0;
608
+}
609
+
610
+int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
611
+{
612
+ int err;
613
+
614
+ // Need no substreams.
615
+ if (bebob->substreams_counter == 0)
616
+ return -EIO;
617
+
618
+ // packet queueing error or detecting discontinuity
619
+ if (amdtp_streaming_error(&bebob->rx_stream) ||
620
+ amdtp_streaming_error(&bebob->tx_stream)) {
621
+ amdtp_domain_stop(&bebob->domain);
601622 break_both_connections(bebob);
602623 }
603624
604
- /* master should be always running */
605625 if (!amdtp_stream_running(&bebob->rx_stream)) {
606
- /*
607
- * NOTE:
608
- * If establishing connections at first, Yamaha GO46
609
- * (and maybe Terratec X24) don't generate sound.
610
- *
611
- * For firmware customized by M-Audio, refer to next NOTE.
612
- */
613
- if (bebob->maudio_special_quirk == NULL) {
614
- err = rate_spec->set(bebob, rate);
615
- if (err < 0) {
616
- dev_err(&bebob->unit->device,
617
- "fail to set sampling rate: %d\n",
618
- err);
619
- goto end;
620
- }
626
+ enum snd_bebob_clock_type src;
627
+ struct amdtp_stream *master, *slave;
628
+ unsigned int curr_rate;
629
+ unsigned int ir_delay_cycle;
630
+
631
+ if (bebob->maudio_special_quirk) {
632
+ err = bebob->spec->rate->get(bebob, &curr_rate);
633
+ if (err < 0)
634
+ return err;
621635 }
622636
623
- err = make_both_connections(bebob, rate);
637
+ err = snd_bebob_stream_get_clock_src(bebob, &src);
624638 if (err < 0)
625
- goto end;
639
+ return err;
626640
627
- err = start_stream(bebob, &bebob->rx_stream, rate);
628
- if (err < 0) {
629
- dev_err(&bebob->unit->device,
630
- "fail to run AMDTP master stream:%d\n", err);
631
- break_both_connections(bebob);
632
- goto end;
641
+ if (src != SND_BEBOB_CLOCK_TYPE_SYT) {
642
+ master = &bebob->tx_stream;
643
+ slave = &bebob->rx_stream;
644
+ } else {
645
+ master = &bebob->rx_stream;
646
+ slave = &bebob->tx_stream;
633647 }
634648
635
- /*
636
- * NOTE:
637
- * The firmware customized by M-Audio uses these commands to
638
- * start transmitting stream. This is not usual way.
639
- */
640
- if (bebob->maudio_special_quirk != NULL) {
641
- err = rate_spec->set(bebob, rate);
649
+ err = start_stream(bebob, master);
650
+ if (err < 0)
651
+ goto error;
652
+
653
+ err = start_stream(bebob, slave);
654
+ if (err < 0)
655
+ goto error;
656
+
657
+ // The device postpones start of transmission mostly for 1 sec
658
+ // after receives packets firstly. For safe, IR context starts
659
+ // 0.4 sec (=3200 cycles) later to version 1 or 2 firmware,
660
+ // 2.0 sec (=16000 cycles) for version 3 firmware. This is
661
+ // within 2.5 sec (=CALLBACK_TIMEOUT).
662
+ // Furthermore, some devices transfer isoc packets with
663
+ // discontinuous counter in the beginning of packet streaming.
664
+ // The delay has an effect to avoid detection of this
665
+ // discontinuity.
666
+ if (bebob->version < 2)
667
+ ir_delay_cycle = 3200;
668
+ else
669
+ ir_delay_cycle = 16000;
670
+ err = amdtp_domain_start(&bebob->domain, ir_delay_cycle);
671
+ if (err < 0)
672
+ goto error;
673
+
674
+ // NOTE:
675
+ // The firmware customized by M-Audio uses these commands to
676
+ // start transmitting stream. This is not usual way.
677
+ if (bebob->maudio_special_quirk) {
678
+ err = bebob->spec->rate->set(bebob, curr_rate);
642679 if (err < 0) {
643680 dev_err(&bebob->unit->device,
644681 "fail to ensure sampling rate: %d\n",
645682 err);
646
- amdtp_stream_stop(&bebob->rx_stream);
647
- break_both_connections(bebob);
648
- goto end;
683
+ goto error;
649684 }
650685 }
651686
652
- /* wait first callback */
653687 if (!amdtp_stream_wait_callback(&bebob->rx_stream,
688
+ CALLBACK_TIMEOUT) ||
689
+ !amdtp_stream_wait_callback(&bebob->tx_stream,
654690 CALLBACK_TIMEOUT)) {
655
- amdtp_stream_stop(&bebob->rx_stream);
656
- break_both_connections(bebob);
657691 err = -ETIMEDOUT;
658
- goto end;
692
+ goto error;
659693 }
660694 }
661695
662
- /* start slave if needed */
663
- if (!amdtp_stream_running(&bebob->tx_stream)) {
664
- err = start_stream(bebob, &bebob->tx_stream, rate);
665
- if (err < 0) {
666
- dev_err(&bebob->unit->device,
667
- "fail to run AMDTP slave stream:%d\n", err);
668
- amdtp_stream_stop(&bebob->rx_stream);
669
- break_both_connections(bebob);
670
- goto end;
671
- }
672
-
673
- /* wait first callback */
674
- if (!amdtp_stream_wait_callback(&bebob->tx_stream,
675
- CALLBACK_TIMEOUT)) {
676
- amdtp_stream_stop(&bebob->tx_stream);
677
- amdtp_stream_stop(&bebob->rx_stream);
678
- break_both_connections(bebob);
679
- err = -ETIMEDOUT;
680
- }
681
- }
682
-end:
696
+ return 0;
697
+error:
698
+ amdtp_domain_stop(&bebob->domain);
699
+ break_both_connections(bebob);
683700 return err;
684701 }
685702
686703 void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob)
687704 {
688705 if (bebob->substreams_counter == 0) {
689
- amdtp_stream_pcm_abort(&bebob->rx_stream);
690
- amdtp_stream_stop(&bebob->rx_stream);
691
-
692
- amdtp_stream_pcm_abort(&bebob->tx_stream);
693
- amdtp_stream_stop(&bebob->tx_stream);
694
-
706
+ amdtp_domain_stop(&bebob->domain);
695707 break_both_connections(bebob);
708
+
709
+ cmp_connection_release(&bebob->out_conn);
710
+ cmp_connection_release(&bebob->in_conn);
696711 }
697712 }
698713
....@@ -702,10 +717,10 @@
702717 */
703718 void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
704719 {
705
- amdtp_stream_destroy(&bebob->rx_stream);
706
- amdtp_stream_destroy(&bebob->tx_stream);
720
+ amdtp_domain_destroy(&bebob->domain);
707721
708
- destroy_both_connections(bebob);
722
+ destroy_stream(bebob, &bebob->tx_stream);
723
+ destroy_stream(bebob, &bebob->rx_stream);
709724 }
710725
711726 /*