Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/firewire/bebob/bebob_stream.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* bebob_stream.c - a part of driver for BeBoB based devices
4
*
5
* Copyright (c) 2013-2014 Takashi Sakamoto
6
*/
7
8
#include "./bebob.h"
9
10
#define READY_TIMEOUT_MS 4000
11
12
/*
13
* NOTE;
14
* For BeBoB streams, Both of input and output CMP connection are important.
15
*
16
* For most devices, each CMP connection starts to transmit/receive a
17
* corresponding stream. But for a few devices, both of CMP connection needs
18
* to start transmitting stream. An example is 'M-Audio Firewire 410'.
19
*/
20
21
/* 128 is an arbitrary length but it seems to be enough */
22
#define FORMAT_MAXIMUM_LENGTH 128
23
24
const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES] = {
25
[0] = 32000,
26
[1] = 44100,
27
[2] = 48000,
28
[3] = 88200,
29
[4] = 96000,
30
[5] = 176400,
31
[6] = 192000,
32
};
33
34
/*
35
* See: Table 51: Extended Stream Format Info ‘Sampling Frequency’
36
* in Additional AVC commands (Nov 2003, BridgeCo)
37
*/
38
static const unsigned int bridgeco_freq_table[] = {
39
[0] = 0x02,
40
[1] = 0x03,
41
[2] = 0x04,
42
[3] = 0x0a,
43
[4] = 0x05,
44
[5] = 0x06,
45
[6] = 0x07,
46
};
47
48
static int
49
get_formation_index(unsigned int rate, unsigned int *index)
50
{
51
unsigned int i;
52
53
for (i = 0; i < ARRAY_SIZE(snd_bebob_rate_table); i++) {
54
if (snd_bebob_rate_table[i] == rate) {
55
*index = i;
56
return 0;
57
}
58
}
59
return -EINVAL;
60
}
61
62
int
63
snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *curr_rate)
64
{
65
unsigned int tx_rate, rx_rate, trials;
66
int err;
67
68
trials = 0;
69
do {
70
err = avc_general_get_sig_fmt(bebob->unit, &tx_rate,
71
AVC_GENERAL_PLUG_DIR_OUT, 0);
72
} while (err == -EAGAIN && ++trials < 3);
73
if (err < 0)
74
goto end;
75
76
trials = 0;
77
do {
78
err = avc_general_get_sig_fmt(bebob->unit, &rx_rate,
79
AVC_GENERAL_PLUG_DIR_IN, 0);
80
} while (err == -EAGAIN && ++trials < 3);
81
if (err < 0)
82
goto end;
83
84
*curr_rate = rx_rate;
85
if (rx_rate == tx_rate)
86
goto end;
87
88
/* synchronize receive stream rate to transmit stream rate */
89
err = avc_general_set_sig_fmt(bebob->unit, rx_rate,
90
AVC_GENERAL_PLUG_DIR_IN, 0);
91
end:
92
return err;
93
}
94
95
int
96
snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate)
97
{
98
int err;
99
100
err = avc_general_set_sig_fmt(bebob->unit, rate,
101
AVC_GENERAL_PLUG_DIR_OUT, 0);
102
if (err < 0)
103
goto end;
104
105
err = avc_general_set_sig_fmt(bebob->unit, rate,
106
AVC_GENERAL_PLUG_DIR_IN, 0);
107
if (err < 0)
108
goto end;
109
110
/*
111
* Some devices need a bit time for transition.
112
* 300msec is got by some experiments.
113
*/
114
msleep(300);
115
end:
116
return err;
117
}
118
119
int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob,
120
enum snd_bebob_clock_type *src)
121
{
122
const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
123
u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7];
124
unsigned int id;
125
enum avc_bridgeco_plug_type type;
126
int err = 0;
127
128
/* 1.The device has its own operation to switch source of clock */
129
if (clk_spec) {
130
err = clk_spec->get(bebob, &id);
131
if (err < 0) {
132
dev_err(&bebob->unit->device,
133
"fail to get clock source: %d\n", err);
134
goto end;
135
}
136
137
if (id >= clk_spec->num) {
138
dev_err(&bebob->unit->device,
139
"clock source %d out of range 0..%d\n",
140
id, clk_spec->num - 1);
141
err = -EIO;
142
goto end;
143
}
144
145
*src = clk_spec->types[id];
146
goto end;
147
}
148
149
/*
150
* 2.The device don't support to switch source of clock then assumed
151
* to use internal clock always
152
*/
153
if (bebob->sync_input_plug < 0) {
154
*src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
155
goto end;
156
}
157
158
/*
159
* 3.The device supports to switch source of clock by an usual way.
160
* Let's check input for 'Music Sub Unit Sync Input' plug.
161
*/
162
avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
163
bebob->sync_input_plug);
164
err = avc_bridgeco_get_plug_input(bebob->unit, addr, input);
165
if (err < 0) {
166
dev_err(&bebob->unit->device,
167
"fail to get an input for MSU in plug %d: %d\n",
168
bebob->sync_input_plug, err);
169
goto end;
170
}
171
172
/*
173
* If there are no input plugs, all of fields are 0xff.
174
* Here check the first field. This field is used for direction.
175
*/
176
if (input[0] == 0xff) {
177
*src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
178
goto end;
179
}
180
181
/* The source from any output plugs is for one purpose only. */
182
if (input[0] == AVC_BRIDGECO_PLUG_DIR_OUT) {
183
/*
184
* In BeBoB architecture, the source from music subunit may
185
* bypass from oPCR[0]. This means that this source gives
186
* synchronization to IEEE 1394 cycle start packet.
187
*/
188
if (input[1] == AVC_BRIDGECO_PLUG_MODE_SUBUNIT &&
189
input[2] == 0x0c) {
190
*src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
191
goto end;
192
}
193
/* The source from any input units is for several purposes. */
194
} else if (input[1] == AVC_BRIDGECO_PLUG_MODE_UNIT) {
195
if (input[2] == AVC_BRIDGECO_PLUG_UNIT_ISOC) {
196
if (input[3] == 0x00) {
197
/*
198
* This source comes from iPCR[0]. This means
199
* that presentation timestamp calculated by
200
* SYT series of the received packets. In
201
* short, this driver is the master of
202
* synchronization.
203
*/
204
*src = SND_BEBOB_CLOCK_TYPE_SYT;
205
goto end;
206
} else {
207
/*
208
* This source comes from iPCR[1-29]. This
209
* means that the synchronization stream is not
210
* the Audio/MIDI compound stream.
211
*/
212
*src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
213
goto end;
214
}
215
} else if (input[2] == AVC_BRIDGECO_PLUG_UNIT_EXT) {
216
/* Check type of this plug. */
217
avc_bridgeco_fill_unit_addr(addr,
218
AVC_BRIDGECO_PLUG_DIR_IN,
219
AVC_BRIDGECO_PLUG_UNIT_EXT,
220
input[3]);
221
err = avc_bridgeco_get_plug_type(bebob->unit, addr,
222
&type);
223
if (err < 0)
224
goto end;
225
226
if (type == AVC_BRIDGECO_PLUG_TYPE_DIG) {
227
/*
228
* SPDIF/ADAT or sometimes (not always) word
229
* clock.
230
*/
231
*src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
232
goto end;
233
} else if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) {
234
/* Often word clock. */
235
*src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
236
goto end;
237
} else if (type == AVC_BRIDGECO_PLUG_TYPE_ADDITION) {
238
/*
239
* Not standard.
240
* Mostly, additional internal clock.
241
*/
242
*src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
243
goto end;
244
}
245
}
246
}
247
248
/* Not supported. */
249
err = -EIO;
250
end:
251
return err;
252
}
253
254
static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
255
{
256
unsigned int sec, sections, ch, channels;
257
unsigned int pcm, midi, location;
258
unsigned int stm_pos, sec_loc, pos;
259
u8 *buf, addr[AVC_BRIDGECO_ADDR_BYTES], type;
260
enum avc_bridgeco_plug_dir dir;
261
int err;
262
263
/*
264
* The length of return value of this command cannot be expected. Here
265
* use the maximum length of FCP.
266
*/
267
buf = kzalloc(256, GFP_KERNEL);
268
if (buf == NULL)
269
return -ENOMEM;
270
271
if (s == &bebob->tx_stream)
272
dir = AVC_BRIDGECO_PLUG_DIR_OUT;
273
else
274
dir = AVC_BRIDGECO_PLUG_DIR_IN;
275
276
avc_bridgeco_fill_unit_addr(addr, dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
277
err = avc_bridgeco_get_plug_ch_pos(bebob->unit, addr, buf, 256);
278
if (err < 0) {
279
dev_err(&bebob->unit->device,
280
"fail to get channel position for isoc %s plug 0: %d\n",
281
(dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : "out",
282
err);
283
goto end;
284
}
285
pos = 0;
286
287
/* positions in I/O buffer */
288
pcm = 0;
289
midi = 0;
290
291
/* the number of sections in AMDTP packet */
292
sections = buf[pos++];
293
294
for (sec = 0; sec < sections; sec++) {
295
/* type of this section */
296
avc_bridgeco_fill_unit_addr(addr, dir,
297
AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
298
err = avc_bridgeco_get_plug_section_type(bebob->unit, addr,
299
sec, &type);
300
if (err < 0) {
301
dev_err(&bebob->unit->device,
302
"fail to get section type for isoc %s plug 0: %d\n",
303
(dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" :
304
"out",
305
err);
306
goto end;
307
}
308
/* NoType */
309
if (type == 0xff) {
310
err = -ENOSYS;
311
goto end;
312
}
313
314
/* the number of channels in this section */
315
channels = buf[pos++];
316
317
for (ch = 0; ch < channels; ch++) {
318
/* position of this channel in AMDTP packet */
319
stm_pos = buf[pos++] - 1;
320
/* location of this channel in this section */
321
sec_loc = buf[pos++] - 1;
322
323
/*
324
* Basically the number of location is within the
325
* number of channels in this section. But some models
326
* of M-Audio don't follow this. Its location for MIDI
327
* is the position of MIDI channels in AMDTP packet.
328
*/
329
if (sec_loc >= channels)
330
sec_loc = ch;
331
332
switch (type) {
333
/* for MIDI conformant data channel */
334
case 0x0a:
335
/* AMDTP_MAX_CHANNELS_FOR_MIDI is 1. */
336
if ((midi > 0) && (stm_pos != midi)) {
337
err = -ENOSYS;
338
goto end;
339
}
340
amdtp_am824_set_midi_position(s, stm_pos);
341
midi = stm_pos;
342
break;
343
/* for PCM data channel */
344
case 0x01: /* Headphone */
345
case 0x02: /* Microphone */
346
case 0x03: /* Line */
347
case 0x04: /* SPDIF */
348
case 0x05: /* ADAT */
349
case 0x06: /* TDIF */
350
case 0x07: /* MADI */
351
/* for undefined/changeable signal */
352
case 0x08: /* Analog */
353
case 0x09: /* Digital */
354
default:
355
location = pcm + sec_loc;
356
if (location >= AM824_MAX_CHANNELS_FOR_PCM) {
357
err = -ENOSYS;
358
goto end;
359
}
360
amdtp_am824_set_pcm_position(s, location,
361
stm_pos);
362
break;
363
}
364
}
365
366
if (type != 0x0a)
367
pcm += channels;
368
else
369
midi += channels;
370
}
371
end:
372
kfree(buf);
373
return err;
374
}
375
376
static int
377
check_connection_used_by_others(struct snd_bebob *bebob, struct amdtp_stream *s)
378
{
379
struct cmp_connection *conn;
380
bool used;
381
int err;
382
383
if (s == &bebob->tx_stream)
384
conn = &bebob->out_conn;
385
else
386
conn = &bebob->in_conn;
387
388
err = cmp_connection_check_used(conn, &used);
389
if ((err >= 0) && used && !amdtp_stream_running(s)) {
390
dev_err(&bebob->unit->device,
391
"Connection established by others: %cPCR[%d]\n",
392
(conn->direction == CMP_OUTPUT) ? 'o' : 'i',
393
conn->pcr_index);
394
err = -EBUSY;
395
}
396
397
return err;
398
}
399
400
static void break_both_connections(struct snd_bebob *bebob)
401
{
402
cmp_connection_break(&bebob->in_conn);
403
cmp_connection_break(&bebob->out_conn);
404
}
405
406
static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
407
{
408
struct cmp_connection *conn;
409
int err = 0;
410
411
if (stream == &bebob->rx_stream)
412
conn = &bebob->in_conn;
413
else
414
conn = &bebob->out_conn;
415
416
// channel mapping.
417
if (bebob->maudio_special_quirk == NULL) {
418
err = map_data_channels(bebob, stream);
419
if (err < 0)
420
return err;
421
}
422
423
err = cmp_connection_establish(conn);
424
if (err < 0)
425
return err;
426
427
return amdtp_domain_add_stream(&bebob->domain, stream,
428
conn->resources.channel, conn->speed);
429
}
430
431
static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
432
{
433
unsigned int flags = CIP_BLOCKING;
434
enum amdtp_stream_direction dir_stream;
435
struct cmp_connection *conn;
436
enum cmp_direction dir_conn;
437
int err;
438
439
if (stream == &bebob->tx_stream) {
440
dir_stream = AMDTP_IN_STREAM;
441
conn = &bebob->out_conn;
442
dir_conn = CMP_OUTPUT;
443
} else {
444
dir_stream = AMDTP_OUT_STREAM;
445
conn = &bebob->in_conn;
446
dir_conn = CMP_INPUT;
447
}
448
449
if (stream == &bebob->tx_stream) {
450
if (bebob->quirks & SND_BEBOB_QUIRK_WRONG_DBC)
451
flags |= CIP_EMPTY_HAS_WRONG_DBC;
452
}
453
454
err = cmp_connection_init(conn, bebob->unit, dir_conn, 0);
455
if (err < 0)
456
return err;
457
458
err = amdtp_am824_init(stream, bebob->unit, dir_stream, flags);
459
if (err < 0) {
460
cmp_connection_destroy(conn);
461
return err;
462
}
463
464
return 0;
465
}
466
467
static void destroy_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
468
{
469
amdtp_stream_destroy(stream);
470
471
if (stream == &bebob->tx_stream)
472
cmp_connection_destroy(&bebob->out_conn);
473
else
474
cmp_connection_destroy(&bebob->in_conn);
475
}
476
477
int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
478
{
479
int err;
480
481
err = init_stream(bebob, &bebob->tx_stream);
482
if (err < 0)
483
return err;
484
485
err = init_stream(bebob, &bebob->rx_stream);
486
if (err < 0) {
487
destroy_stream(bebob, &bebob->tx_stream);
488
return err;
489
}
490
491
err = amdtp_domain_init(&bebob->domain);
492
if (err < 0) {
493
destroy_stream(bebob, &bebob->tx_stream);
494
destroy_stream(bebob, &bebob->rx_stream);
495
}
496
497
return err;
498
}
499
500
static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
501
unsigned int rate, unsigned int index)
502
{
503
unsigned int pcm_channels;
504
unsigned int midi_ports;
505
struct cmp_connection *conn;
506
int err;
507
508
if (stream == &bebob->tx_stream) {
509
pcm_channels = bebob->tx_stream_formations[index].pcm;
510
midi_ports = bebob->midi_input_ports;
511
conn = &bebob->out_conn;
512
} else {
513
pcm_channels = bebob->rx_stream_formations[index].pcm;
514
midi_ports = bebob->midi_output_ports;
515
conn = &bebob->in_conn;
516
}
517
518
err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false);
519
if (err < 0)
520
return err;
521
522
return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
523
}
524
525
int snd_bebob_stream_reserve_duplex(struct snd_bebob *bebob, unsigned int rate,
526
unsigned int frames_per_period,
527
unsigned int frames_per_buffer)
528
{
529
unsigned int curr_rate;
530
int err;
531
532
// Considering JACK/FFADO streaming:
533
// TODO: This can be removed hwdep functionality becomes popular.
534
err = check_connection_used_by_others(bebob, &bebob->rx_stream);
535
if (err < 0)
536
return err;
537
538
err = bebob->spec->rate->get(bebob, &curr_rate);
539
if (err < 0)
540
return err;
541
if (rate == 0)
542
rate = curr_rate;
543
if (curr_rate != rate) {
544
amdtp_domain_stop(&bebob->domain);
545
break_both_connections(bebob);
546
547
cmp_connection_release(&bebob->out_conn);
548
cmp_connection_release(&bebob->in_conn);
549
}
550
551
if (bebob->substreams_counter == 0 || curr_rate != rate) {
552
unsigned int index;
553
554
// NOTE:
555
// If establishing connections at first, Yamaha GO46
556
// (and maybe Terratec X24) don't generate sound.
557
//
558
// For firmware customized by M-Audio, refer to next NOTE.
559
err = bebob->spec->rate->set(bebob, rate);
560
if (err < 0) {
561
dev_err(&bebob->unit->device,
562
"fail to set sampling rate: %d\n",
563
err);
564
return err;
565
}
566
567
err = get_formation_index(rate, &index);
568
if (err < 0)
569
return err;
570
571
err = keep_resources(bebob, &bebob->tx_stream, rate, index);
572
if (err < 0)
573
return err;
574
575
err = keep_resources(bebob, &bebob->rx_stream, rate, index);
576
if (err < 0) {
577
cmp_connection_release(&bebob->out_conn);
578
return err;
579
}
580
581
err = amdtp_domain_set_events_per_period(&bebob->domain,
582
frames_per_period, frames_per_buffer);
583
if (err < 0) {
584
cmp_connection_release(&bebob->out_conn);
585
cmp_connection_release(&bebob->in_conn);
586
return err;
587
}
588
}
589
590
return 0;
591
}
592
593
int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
594
{
595
int err;
596
597
// Need no substreams.
598
if (bebob->substreams_counter == 0)
599
return -EIO;
600
601
// packet queueing error or detecting discontinuity
602
if (amdtp_streaming_error(&bebob->rx_stream) ||
603
amdtp_streaming_error(&bebob->tx_stream)) {
604
amdtp_domain_stop(&bebob->domain);
605
break_both_connections(bebob);
606
}
607
608
if (!amdtp_stream_running(&bebob->rx_stream)) {
609
enum snd_bebob_clock_type src;
610
unsigned int curr_rate;
611
unsigned int tx_init_skip_cycles;
612
613
if (bebob->maudio_special_quirk) {
614
err = bebob->spec->rate->get(bebob, &curr_rate);
615
if (err < 0)
616
return err;
617
}
618
619
err = snd_bebob_stream_get_clock_src(bebob, &src);
620
if (err < 0)
621
return err;
622
623
err = start_stream(bebob, &bebob->rx_stream);
624
if (err < 0)
625
goto error;
626
627
err = start_stream(bebob, &bebob->tx_stream);
628
if (err < 0)
629
goto error;
630
631
if (!(bebob->quirks & SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC))
632
tx_init_skip_cycles = 0;
633
else
634
tx_init_skip_cycles = 16000;
635
636
// MEMO: Some devices start packet transmission long enough after establishment of
637
// CMP connection. In the early stage of packet streaming, any device transfers
638
// NODATA packets. After several hundred cycles, it begins to multiplex event into
639
// the packet with adequate value of syt field in CIP header. Some devices are
640
// strictly to generate any discontinuity in the sequence of tx packet when they
641
// receives inadequate sequence of value in syt field of CIP header. In the case,
642
// the request to break CMP connection is often corrupted, then any transaction
643
// results in unrecoverable error, sometimes generate bus-reset.
644
err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles, true, false);
645
if (err < 0)
646
goto error;
647
648
// NOTE:
649
// The firmware customized by M-Audio uses these commands to
650
// start transmitting stream. This is not usual way.
651
if (bebob->maudio_special_quirk) {
652
err = bebob->spec->rate->set(bebob, curr_rate);
653
if (err < 0) {
654
dev_err(&bebob->unit->device,
655
"fail to ensure sampling rate: %d\n",
656
err);
657
goto error;
658
}
659
}
660
661
// Some devices postpone start of transmission mostly for 1 sec after receives
662
// packets firstly.
663
if (!amdtp_domain_wait_ready(&bebob->domain, READY_TIMEOUT_MS)) {
664
err = -ETIMEDOUT;
665
goto error;
666
}
667
}
668
669
return 0;
670
error:
671
amdtp_domain_stop(&bebob->domain);
672
break_both_connections(bebob);
673
return err;
674
}
675
676
void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob)
677
{
678
if (bebob->substreams_counter == 0) {
679
amdtp_domain_stop(&bebob->domain);
680
break_both_connections(bebob);
681
682
cmp_connection_release(&bebob->out_conn);
683
cmp_connection_release(&bebob->in_conn);
684
}
685
}
686
687
/*
688
* This function should be called before starting streams or after stopping
689
* streams.
690
*/
691
void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
692
{
693
amdtp_domain_destroy(&bebob->domain);
694
695
destroy_stream(bebob, &bebob->tx_stream);
696
destroy_stream(bebob, &bebob->rx_stream);
697
}
698
699
/*
700
* See: Table 50: Extended Stream Format Info Format Hierarchy Level 2’
701
* in Additional AVC commands (Nov 2003, BridgeCo)
702
* Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
703
*/
704
static int
705
parse_stream_formation(u8 *buf, unsigned int len,
706
struct snd_bebob_stream_formation *formation)
707
{
708
unsigned int i, e, channels, format;
709
710
/*
711
* this module can support a hierarchy combination that:
712
* Root: Audio and Music (0x90)
713
* Level 1: AM824 Compound (0x40)
714
*/
715
if ((buf[0] != 0x90) || (buf[1] != 0x40))
716
return -ENOSYS;
717
718
/* check sampling rate */
719
for (i = 0; i < ARRAY_SIZE(bridgeco_freq_table); i++) {
720
if (buf[2] == bridgeco_freq_table[i])
721
break;
722
}
723
if (i == ARRAY_SIZE(bridgeco_freq_table))
724
return -ENOSYS;
725
726
/* Avoid double count by different entries for the same rate. */
727
memset(&formation[i], 0, sizeof(struct snd_bebob_stream_formation));
728
729
for (e = 0; e < buf[4]; e++) {
730
channels = buf[5 + e * 2];
731
format = buf[6 + e * 2];
732
733
switch (format) {
734
/* IEC 60958 Conformant, currently handled as MBLA */
735
case 0x00:
736
/* Multi bit linear audio */
737
case 0x06: /* Raw */
738
formation[i].pcm += channels;
739
break;
740
/* MIDI Conformant */
741
case 0x0d:
742
formation[i].midi += channels;
743
break;
744
/* IEC 61937-3 to 7 */
745
case 0x01:
746
case 0x02:
747
case 0x03:
748
case 0x04:
749
case 0x05:
750
/* Multi bit linear audio */
751
case 0x07: /* DVD-Audio */
752
case 0x0c: /* High Precision */
753
/* One Bit Audio */
754
case 0x08: /* (Plain) Raw */
755
case 0x09: /* (Plain) SACD */
756
case 0x0a: /* (Encoded) Raw */
757
case 0x0b: /* (Encoded) SACD */
758
/* Synchronization Stream (Stereo Raw audio) */
759
case 0x40:
760
/* Don't care */
761
case 0xff:
762
default:
763
return -ENOSYS; /* not supported */
764
}
765
}
766
767
if (formation[i].pcm > AM824_MAX_CHANNELS_FOR_PCM ||
768
formation[i].midi > AM824_MAX_CHANNELS_FOR_MIDI)
769
return -ENOSYS;
770
771
return 0;
772
}
773
774
static int fill_stream_formations(struct snd_bebob *bebob, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
775
enum avc_bridgeco_plug_dir plug_dir, unsigned int plug_id,
776
struct snd_bebob_stream_formation *formations)
777
{
778
enum avc_bridgeco_plug_type plug_type;
779
u8 *buf;
780
unsigned int len, eid;
781
int err;
782
783
avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id);
784
785
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type);
786
if (err < 0) {
787
dev_err(&bebob->unit->device,
788
"Fail to get type for isoc %d plug 0: %d\n", plug_dir, err);
789
return err;
790
} else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_ISOC)
791
return -ENXIO;
792
793
buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL);
794
if (buf == NULL)
795
return -ENOMEM;
796
797
for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; ++eid) {
798
avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id);
799
800
len = FORMAT_MAXIMUM_LENGTH;
801
err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf, &len, eid);
802
// No entries remained.
803
if (err == -EINVAL && eid > 0) {
804
err = 0;
805
break;
806
} else if (err < 0) {
807
dev_err(&bebob->unit->device,
808
"fail to get stream format %d for isoc %d plug %d:%d\n",
809
eid, plug_dir, plug_id, err);
810
break;
811
}
812
813
err = parse_stream_formation(buf, len, formations);
814
if (err < 0)
815
break;
816
}
817
818
kfree(buf);
819
return err;
820
}
821
822
static int detect_midi_ports(struct snd_bebob *bebob,
823
const struct snd_bebob_stream_formation *formats,
824
u8 addr[AVC_BRIDGECO_ADDR_BYTES], enum avc_bridgeco_plug_dir plug_dir,
825
unsigned int plug_count, unsigned int *midi_ports)
826
{
827
int i;
828
int err = 0;
829
830
*midi_ports = 0;
831
832
/// Detect the number of available MIDI ports when packet has MIDI conformant data channel.
833
for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; ++i) {
834
if (formats[i].midi > 0)
835
break;
836
}
837
if (i >= SND_BEBOB_STRM_FMT_ENTRIES)
838
return 0;
839
840
for (i = 0; i < plug_count; ++i) {
841
enum avc_bridgeco_plug_type plug_type;
842
unsigned int ch_count;
843
844
avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_EXT, i);
845
846
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type);
847
if (err < 0) {
848
dev_err(&bebob->unit->device,
849
"fail to get type for external %d plug %d: %d\n",
850
plug_dir, i, err);
851
break;
852
} else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_MIDI) {
853
continue;
854
}
855
856
err = avc_bridgeco_get_plug_ch_count(bebob->unit, addr, &ch_count);
857
if (err < 0)
858
break;
859
// Yamaha GO44, GO46, Terratec Phase 24, Phase x24 reports 0 for the number of
860
// channels in external output plug 3 (MIDI type) even if it has a pair of physical
861
// MIDI jacks. As a workaround, assume it as one.
862
if (ch_count == 0)
863
ch_count = 1;
864
*midi_ports += ch_count;
865
}
866
867
return err;
868
}
869
870
static int
871
seek_msu_sync_input_plug(struct snd_bebob *bebob)
872
{
873
u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
874
unsigned int i;
875
enum avc_bridgeco_plug_type type;
876
int err;
877
878
/* Get the number of Music Sub Unit for both direction. */
879
err = avc_general_get_plug_info(bebob->unit, 0x0c, 0x00, 0x00, plugs);
880
if (err < 0) {
881
dev_err(&bebob->unit->device,
882
"fail to get info for MSU in/out plugs: %d\n",
883
err);
884
goto end;
885
}
886
887
/* seek destination plugs for 'MSU sync input' */
888
bebob->sync_input_plug = -1;
889
for (i = 0; i < plugs[0]; i++) {
890
avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, i);
891
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
892
if (err < 0) {
893
dev_err(&bebob->unit->device,
894
"fail to get type for MSU in plug %d: %d\n",
895
i, err);
896
goto end;
897
}
898
899
if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) {
900
bebob->sync_input_plug = i;
901
break;
902
}
903
}
904
end:
905
return err;
906
}
907
908
int snd_bebob_stream_discover(struct snd_bebob *bebob)
909
{
910
const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
911
u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
912
int err;
913
914
/* the number of plugs for isoc in/out, ext in/out */
915
err = avc_general_get_plug_info(bebob->unit, 0x1f, 0x07, 0x00, plugs);
916
if (err < 0) {
917
dev_err(&bebob->unit->device,
918
"fail to get info for isoc/external in/out plugs: %d\n",
919
err);
920
goto end;
921
}
922
923
/*
924
* This module supports at least one isoc input plug and one isoc
925
* output plug.
926
*/
927
if ((plugs[0] == 0) || (plugs[1] == 0)) {
928
err = -ENOSYS;
929
goto end;
930
}
931
932
err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_IN, 0,
933
bebob->rx_stream_formations);
934
if (err < 0)
935
goto end;
936
937
err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_OUT, 0,
938
bebob->tx_stream_formations);
939
if (err < 0)
940
goto end;
941
942
err = detect_midi_ports(bebob, bebob->tx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_IN,
943
plugs[2], &bebob->midi_input_ports);
944
if (err < 0)
945
goto end;
946
947
err = detect_midi_ports(bebob, bebob->rx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_OUT,
948
plugs[3], &bebob->midi_output_ports);
949
if (err < 0)
950
goto end;
951
952
/* for check source of clock later */
953
if (!clk_spec)
954
err = seek_msu_sync_input_plug(bebob);
955
end:
956
return err;
957
}
958
959
void snd_bebob_stream_lock_changed(struct snd_bebob *bebob)
960
{
961
bebob->dev_lock_changed = true;
962
wake_up(&bebob->hwdep_wait);
963
}
964
965
int snd_bebob_stream_lock_try(struct snd_bebob *bebob)
966
{
967
int err;
968
969
spin_lock_irq(&bebob->lock);
970
971
/* user land lock this */
972
if (bebob->dev_lock_count < 0) {
973
err = -EBUSY;
974
goto end;
975
}
976
977
/* this is the first time */
978
if (bebob->dev_lock_count++ == 0)
979
snd_bebob_stream_lock_changed(bebob);
980
err = 0;
981
end:
982
spin_unlock_irq(&bebob->lock);
983
return err;
984
}
985
986
void snd_bebob_stream_lock_release(struct snd_bebob *bebob)
987
{
988
spin_lock_irq(&bebob->lock);
989
990
if (WARN_ON(bebob->dev_lock_count <= 0))
991
goto end;
992
if (--bebob->dev_lock_count == 0)
993
snd_bebob_stream_lock_changed(bebob);
994
end:
995
spin_unlock_irq(&bebob->lock);
996
}
997
998