Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/firewire/oxfw/oxfw-stream.c
26451 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* oxfw_stream.c - a part of driver for OXFW970/971 based devices
4
*
5
* Copyright (c) 2014 Takashi Sakamoto
6
*/
7
8
#include "oxfw.h"
9
#include <linux/delay.h>
10
11
#define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
12
#define READY_TIMEOUT_MS 600
13
14
/*
15
* According to datasheet of Oxford Semiconductor:
16
* OXFW970: 32.0/44.1/48.0/96.0 Khz, 8 audio channels I/O
17
* OXFW971: 32.0/44.1/48.0/88.2/96.0/192.0 kHz, 16 audio channels I/O, MIDI I/O
18
*/
19
static const unsigned int oxfw_rate_table[] = {
20
[0] = 32000,
21
[1] = 44100,
22
[2] = 48000,
23
[3] = 88200,
24
[4] = 96000,
25
[5] = 192000,
26
};
27
28
/*
29
* See Table 5.7 – Sampling frequency for Multi-bit Audio
30
* in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
31
*/
32
static const unsigned int avc_stream_rate_table[] = {
33
[0] = 0x02,
34
[1] = 0x03,
35
[2] = 0x04,
36
[3] = 0x0a,
37
[4] = 0x05,
38
[5] = 0x07,
39
};
40
41
static int set_rate(struct snd_oxfw *oxfw, unsigned int rate)
42
{
43
int err;
44
45
err = avc_general_set_sig_fmt(oxfw->unit, rate,
46
AVC_GENERAL_PLUG_DIR_IN, 0);
47
if (err < 0)
48
goto end;
49
50
if (oxfw->has_output)
51
err = avc_general_set_sig_fmt(oxfw->unit, rate,
52
AVC_GENERAL_PLUG_DIR_OUT, 0);
53
end:
54
return err;
55
}
56
57
static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
58
unsigned int rate, unsigned int pcm_channels)
59
{
60
u8 **formats;
61
struct snd_oxfw_stream_formation formation;
62
enum avc_general_plug_dir dir;
63
unsigned int len;
64
int i, err;
65
66
if (s == &oxfw->tx_stream) {
67
formats = oxfw->tx_stream_formats;
68
dir = AVC_GENERAL_PLUG_DIR_OUT;
69
} else {
70
formats = oxfw->rx_stream_formats;
71
dir = AVC_GENERAL_PLUG_DIR_IN;
72
}
73
74
/* Seek stream format for requirements. */
75
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
76
err = snd_oxfw_stream_parse_format(formats[i], &formation);
77
if (err < 0)
78
return err;
79
80
if ((formation.rate == rate) && (formation.pcm == pcm_channels))
81
break;
82
}
83
if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
84
return -EINVAL;
85
86
/* If assumed, just change rate. */
87
if (oxfw->assumed)
88
return set_rate(oxfw, rate);
89
90
/* Calculate format length. */
91
len = 5 + formats[i][4] * 2;
92
93
err = avc_stream_set_format(oxfw->unit, dir, 0, formats[i], len);
94
if (err < 0)
95
return err;
96
97
/* Some requests just after changing format causes freezing. */
98
msleep(100);
99
100
return 0;
101
}
102
103
static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
104
{
105
struct cmp_connection *conn;
106
int err;
107
108
if (stream == &oxfw->rx_stream)
109
conn = &oxfw->in_conn;
110
else
111
conn = &oxfw->out_conn;
112
113
err = cmp_connection_establish(conn);
114
if (err < 0)
115
return err;
116
117
err = amdtp_domain_add_stream(&oxfw->domain, stream,
118
conn->resources.channel, conn->speed);
119
if (err < 0) {
120
cmp_connection_break(conn);
121
return err;
122
}
123
124
return 0;
125
}
126
127
static int check_connection_used_by_others(struct snd_oxfw *oxfw,
128
struct amdtp_stream *stream)
129
{
130
struct cmp_connection *conn;
131
bool used;
132
int err;
133
134
if (stream == &oxfw->tx_stream)
135
conn = &oxfw->out_conn;
136
else
137
conn = &oxfw->in_conn;
138
139
err = cmp_connection_check_used(conn, &used);
140
if ((err >= 0) && used && !amdtp_stream_running(stream)) {
141
dev_err(&oxfw->unit->device,
142
"Connection established by others: %cPCR[%d]\n",
143
(conn->direction == CMP_OUTPUT) ? 'o' : 'i',
144
conn->pcr_index);
145
err = -EBUSY;
146
}
147
148
return err;
149
}
150
151
static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
152
{
153
struct cmp_connection *conn;
154
enum cmp_direction c_dir;
155
enum amdtp_stream_direction s_dir;
156
unsigned int flags = 0;
157
int err;
158
159
if (!(oxfw->quirks & SND_OXFW_QUIRK_BLOCKING_TRANSMISSION))
160
flags |= CIP_NONBLOCKING;
161
else
162
flags |= CIP_BLOCKING;
163
164
// OXFW 970/971 has no function to generate playback timing according to the sequence
165
// of value in syt field, thus the packet should include NO_INFO value in the field.
166
// However, some models just ignore data blocks in packet with NO_INFO for audio data
167
// processing.
168
if (!(oxfw->quirks & SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET))
169
flags |= CIP_UNAWARE_SYT;
170
171
if (stream == &oxfw->tx_stream) {
172
conn = &oxfw->out_conn;
173
c_dir = CMP_OUTPUT;
174
s_dir = AMDTP_IN_STREAM;
175
176
if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD)
177
flags |= CIP_JUMBO_PAYLOAD;
178
if (oxfw->quirks & SND_OXFW_QUIRK_WRONG_DBS)
179
flags |= CIP_WRONG_DBS;
180
if (oxfw->quirks & SND_OXFW_QUIRK_DBC_IS_TOTAL_PAYLOAD_QUADLETS)
181
flags |= CIP_DBC_IS_END_EVENT | CIP_DBC_IS_PAYLOAD_QUADLETS;
182
} else {
183
conn = &oxfw->in_conn;
184
c_dir = CMP_INPUT;
185
s_dir = AMDTP_OUT_STREAM;
186
}
187
188
err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
189
if (err < 0)
190
return err;
191
192
err = amdtp_am824_init(stream, oxfw->unit, s_dir, flags);
193
if (err < 0) {
194
cmp_connection_destroy(conn);
195
return err;
196
}
197
198
return 0;
199
}
200
201
static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
202
{
203
enum avc_general_plug_dir dir;
204
u8 **formats;
205
struct snd_oxfw_stream_formation formation;
206
struct cmp_connection *conn;
207
int i;
208
int err;
209
210
if (stream == &oxfw->rx_stream) {
211
dir = AVC_GENERAL_PLUG_DIR_IN;
212
formats = oxfw->rx_stream_formats;
213
conn = &oxfw->in_conn;
214
} else {
215
dir = AVC_GENERAL_PLUG_DIR_OUT;
216
formats = oxfw->tx_stream_formats;
217
conn = &oxfw->out_conn;
218
}
219
220
err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
221
if (err < 0)
222
return err;
223
224
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
225
struct snd_oxfw_stream_formation fmt;
226
227
if (formats[i] == NULL)
228
break;
229
230
err = snd_oxfw_stream_parse_format(formats[i], &fmt);
231
if (err < 0)
232
return err;
233
234
if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
235
fmt.midi == formation.midi)
236
break;
237
}
238
if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
239
return -EINVAL;
240
241
// The stream should have one pcm channels at least.
242
if (formation.pcm == 0)
243
return -EINVAL;
244
245
err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
246
formation.midi * 8, false);
247
if (err < 0)
248
return err;
249
250
return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
251
}
252
253
int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
254
struct amdtp_stream *stream,
255
unsigned int rate, unsigned int pcm_channels,
256
unsigned int frames_per_period,
257
unsigned int frames_per_buffer)
258
{
259
struct snd_oxfw_stream_formation formation;
260
enum avc_general_plug_dir dir;
261
int err;
262
263
// Considering JACK/FFADO streaming:
264
// TODO: This can be removed hwdep functionality becomes popular.
265
err = check_connection_used_by_others(oxfw, &oxfw->rx_stream);
266
if (err < 0)
267
return err;
268
if (oxfw->has_output) {
269
err = check_connection_used_by_others(oxfw, &oxfw->tx_stream);
270
if (err < 0)
271
return err;
272
}
273
274
if (stream == &oxfw->tx_stream)
275
dir = AVC_GENERAL_PLUG_DIR_OUT;
276
else
277
dir = AVC_GENERAL_PLUG_DIR_IN;
278
279
err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
280
if (err < 0)
281
return err;
282
if (rate == 0) {
283
rate = formation.rate;
284
pcm_channels = formation.pcm;
285
}
286
if (formation.rate != rate || formation.pcm != pcm_channels) {
287
amdtp_domain_stop(&oxfw->domain);
288
289
cmp_connection_break(&oxfw->in_conn);
290
cmp_connection_release(&oxfw->in_conn);
291
292
if (oxfw->has_output) {
293
cmp_connection_break(&oxfw->out_conn);
294
cmp_connection_release(&oxfw->out_conn);
295
}
296
}
297
298
if (oxfw->substreams_count == 0 ||
299
formation.rate != rate || formation.pcm != pcm_channels) {
300
err = set_stream_format(oxfw, stream, rate, pcm_channels);
301
if (err < 0) {
302
dev_err(&oxfw->unit->device,
303
"fail to set stream format: %d\n", err);
304
return err;
305
}
306
307
err = keep_resources(oxfw, &oxfw->rx_stream);
308
if (err < 0)
309
return err;
310
311
if (oxfw->has_output) {
312
err = keep_resources(oxfw, &oxfw->tx_stream);
313
if (err < 0) {
314
cmp_connection_release(&oxfw->in_conn);
315
return err;
316
}
317
}
318
319
err = amdtp_domain_set_events_per_period(&oxfw->domain,
320
frames_per_period, frames_per_buffer);
321
if (err < 0) {
322
cmp_connection_release(&oxfw->in_conn);
323
if (oxfw->has_output)
324
cmp_connection_release(&oxfw->out_conn);
325
return err;
326
}
327
}
328
329
return 0;
330
}
331
332
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
333
{
334
int err;
335
336
if (oxfw->substreams_count == 0)
337
return -EIO;
338
339
if (amdtp_streaming_error(&oxfw->rx_stream) ||
340
amdtp_streaming_error(&oxfw->tx_stream)) {
341
amdtp_domain_stop(&oxfw->domain);
342
343
cmp_connection_break(&oxfw->in_conn);
344
if (oxfw->has_output)
345
cmp_connection_break(&oxfw->out_conn);
346
}
347
348
if (!amdtp_stream_running(&oxfw->rx_stream)) {
349
unsigned int tx_init_skip_cycles = 0;
350
bool replay_seq = false;
351
352
err = start_stream(oxfw, &oxfw->rx_stream);
353
if (err < 0) {
354
dev_err(&oxfw->unit->device,
355
"fail to prepare rx stream: %d\n", err);
356
goto error;
357
}
358
359
if (oxfw->has_output &&
360
!amdtp_stream_running(&oxfw->tx_stream)) {
361
err = start_stream(oxfw, &oxfw->tx_stream);
362
if (err < 0) {
363
dev_err(&oxfw->unit->device,
364
"fail to prepare tx stream: %d\n", err);
365
goto error;
366
}
367
368
if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD) {
369
// Just after changing sampling transfer frequency, many cycles are
370
// skipped for packet transmission.
371
tx_init_skip_cycles = 400;
372
} else if (oxfw->quirks & SND_OXFW_QUIRK_VOLUNTARY_RECOVERY) {
373
// It takes a bit time for target device to adjust event frequency
374
// according to nominal event frequency in isochronous packets from
375
// ALSA oxfw driver.
376
tx_init_skip_cycles = 4000;
377
} else {
378
replay_seq = true;
379
}
380
}
381
382
// NOTE: The device ignores presentation time expressed by the value of syt field
383
// of CIP header in received packets. The sequence of the number of data blocks per
384
// packet is important for media clock recovery.
385
err = amdtp_domain_start(&oxfw->domain, tx_init_skip_cycles, replay_seq, false);
386
if (err < 0)
387
goto error;
388
389
if (!amdtp_domain_wait_ready(&oxfw->domain, READY_TIMEOUT_MS)) {
390
err = -ETIMEDOUT;
391
goto error;
392
}
393
}
394
395
return 0;
396
error:
397
amdtp_domain_stop(&oxfw->domain);
398
399
cmp_connection_break(&oxfw->in_conn);
400
if (oxfw->has_output)
401
cmp_connection_break(&oxfw->out_conn);
402
403
return err;
404
}
405
406
void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw)
407
{
408
if (oxfw->substreams_count == 0) {
409
amdtp_domain_stop(&oxfw->domain);
410
411
cmp_connection_break(&oxfw->in_conn);
412
cmp_connection_release(&oxfw->in_conn);
413
414
if (oxfw->has_output) {
415
cmp_connection_break(&oxfw->out_conn);
416
cmp_connection_release(&oxfw->out_conn);
417
}
418
}
419
}
420
421
static void destroy_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
422
{
423
struct cmp_connection *conn;
424
425
if (stream == &oxfw->tx_stream)
426
conn = &oxfw->out_conn;
427
else
428
conn = &oxfw->in_conn;
429
430
amdtp_stream_destroy(stream);
431
cmp_connection_destroy(conn);
432
}
433
434
int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw)
435
{
436
int err;
437
438
err = init_stream(oxfw, &oxfw->rx_stream);
439
if (err < 0)
440
return err;
441
442
if (oxfw->has_output) {
443
err = init_stream(oxfw, &oxfw->tx_stream);
444
if (err < 0) {
445
destroy_stream(oxfw, &oxfw->rx_stream);
446
return err;
447
}
448
}
449
450
err = amdtp_domain_init(&oxfw->domain);
451
if (err < 0) {
452
destroy_stream(oxfw, &oxfw->rx_stream);
453
if (oxfw->has_output)
454
destroy_stream(oxfw, &oxfw->tx_stream);
455
}
456
457
return err;
458
}
459
460
// This function should be called before starting the stream or after stopping
461
// the streams.
462
void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw)
463
{
464
amdtp_domain_destroy(&oxfw->domain);
465
466
destroy_stream(oxfw, &oxfw->rx_stream);
467
468
if (oxfw->has_output)
469
destroy_stream(oxfw, &oxfw->tx_stream);
470
}
471
472
void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw)
473
{
474
amdtp_domain_stop(&oxfw->domain);
475
476
cmp_connection_break(&oxfw->in_conn);
477
478
amdtp_stream_pcm_abort(&oxfw->rx_stream);
479
480
if (oxfw->has_output) {
481
cmp_connection_break(&oxfw->out_conn);
482
483
amdtp_stream_pcm_abort(&oxfw->tx_stream);
484
}
485
}
486
487
int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
488
enum avc_general_plug_dir dir,
489
struct snd_oxfw_stream_formation *formation)
490
{
491
int err;
492
493
if (!(oxfw->quirks & SND_OXFW_QUIRK_STREAM_FORMAT_INFO_UNSUPPORTED)) {
494
u8 *format;
495
unsigned int len;
496
497
len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
498
format = kmalloc(len, GFP_KERNEL);
499
if (format == NULL)
500
return -ENOMEM;
501
502
err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
503
if (err >= 0) {
504
if (len < 3)
505
err = -EIO;
506
else
507
err = snd_oxfw_stream_parse_format(format, formation);
508
}
509
510
kfree(format);
511
} else {
512
// Miglia Harmony Audio does not support Extended Stream Format Information
513
// command. Use the duplicated hard-coded format, instead.
514
unsigned int rate;
515
u8 *const *formats;
516
int i;
517
518
err = avc_general_get_sig_fmt(oxfw->unit, &rate, dir, 0);
519
if (err < 0)
520
return err;
521
522
if (dir == AVC_GENERAL_PLUG_DIR_IN)
523
formats = oxfw->rx_stream_formats;
524
else
525
formats = oxfw->tx_stream_formats;
526
527
for (i = 0; (i < SND_OXFW_STREAM_FORMAT_ENTRIES); ++i) {
528
if (!formats[i])
529
continue;
530
531
err = snd_oxfw_stream_parse_format(formats[i], formation);
532
if (err < 0)
533
continue;
534
535
if (formation->rate == rate)
536
break;
537
}
538
if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
539
return -EIO;
540
}
541
542
return err;
543
}
544
545
/*
546
* See Table 6.16 - AM824 Stream Format
547
* Figure 6.19 - format_information field for AM824 Compound
548
* in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
549
* Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
550
*/
551
int snd_oxfw_stream_parse_format(const u8 *format,
552
struct snd_oxfw_stream_formation *formation)
553
{
554
unsigned int i, e, channels, type;
555
556
memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
557
558
/*
559
* this module can support a hierarchy combination that:
560
* Root: Audio and Music (0x90)
561
* Level 1: AM824 Compound (0x40)
562
*/
563
if ((format[0] != 0x90) || (format[1] != 0x40))
564
return -ENXIO;
565
566
/* check the sampling rate */
567
for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
568
if (format[2] == avc_stream_rate_table[i])
569
break;
570
}
571
if (i == ARRAY_SIZE(avc_stream_rate_table))
572
return -ENXIO;
573
574
formation->rate = oxfw_rate_table[i];
575
576
for (e = 0; e < format[4]; e++) {
577
channels = format[5 + e * 2];
578
type = format[6 + e * 2];
579
580
switch (type) {
581
/* IEC 60958 Conformant, currently handled as MBLA */
582
case 0x00:
583
/* Multi Bit Linear Audio (Raw) */
584
case 0x06:
585
formation->pcm += channels;
586
break;
587
/* MIDI Conformant */
588
case 0x0d:
589
formation->midi = channels;
590
break;
591
/* IEC 61937-3 to 7 */
592
case 0x01:
593
case 0x02:
594
case 0x03:
595
case 0x04:
596
case 0x05:
597
/* Multi Bit Linear Audio */
598
case 0x07: /* DVD-Audio */
599
case 0x0c: /* High Precision */
600
/* One Bit Audio */
601
case 0x08: /* (Plain) Raw */
602
case 0x09: /* (Plain) SACD */
603
case 0x0a: /* (Encoded) Raw */
604
case 0x0b: /* (Encoded) SACD */
605
/* SMPTE Time-Code conformant */
606
case 0x0e:
607
/* Sample Count */
608
case 0x0f:
609
/* Anciliary Data */
610
case 0x10:
611
/* Synchronization Stream (Stereo Raw audio) */
612
case 0x40:
613
/* Don't care */
614
case 0xff:
615
default:
616
return -ENXIO; /* not supported */
617
}
618
}
619
620
if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM ||
621
formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
622
return -ENXIO;
623
624
return 0;
625
}
626
627
static int
628
assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
629
unsigned int pid, u8 *buf, unsigned int *len,
630
u8 **formats)
631
{
632
struct snd_oxfw_stream_formation formation;
633
unsigned int i, eid;
634
int err;
635
636
// get format at current sampling rate.
637
if (!(oxfw->quirks & SND_OXFW_QUIRK_STREAM_FORMAT_INFO_UNSUPPORTED)) {
638
err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
639
if (err < 0) {
640
dev_err(&oxfw->unit->device,
641
"fail to get current stream format for isoc %s plug %d:%d\n",
642
(dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
643
pid, err);
644
goto end;
645
}
646
} else {
647
// Miglia Harmony Audio does not support Extended Stream Format Information
648
// command. Use the hard-coded format, instead.
649
buf[0] = 0x90;
650
buf[1] = 0x40;
651
buf[2] = avc_stream_rate_table[0];
652
buf[3] = 0x00;
653
buf[4] = 0x01;
654
655
if (dir == AVC_GENERAL_PLUG_DIR_IN)
656
buf[5] = 0x08;
657
else
658
buf[5] = 0x02;
659
660
buf[6] = 0x06;
661
662
*len = 7;
663
}
664
665
/* parse and set stream format */
666
eid = 0;
667
err = snd_oxfw_stream_parse_format(buf, &formation);
668
if (err < 0)
669
goto end;
670
671
formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
672
GFP_KERNEL);
673
if (!formats[eid]) {
674
err = -ENOMEM;
675
goto end;
676
}
677
678
/* apply the format for each available sampling rate */
679
for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
680
if (formation.rate == oxfw_rate_table[i])
681
continue;
682
683
err = avc_general_inquiry_sig_fmt(oxfw->unit,
684
oxfw_rate_table[i],
685
dir, pid);
686
if (err < 0)
687
continue;
688
689
eid++;
690
formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
691
GFP_KERNEL);
692
if (formats[eid] == NULL) {
693
err = -ENOMEM;
694
goto end;
695
}
696
formats[eid][2] = avc_stream_rate_table[i];
697
}
698
699
err = 0;
700
oxfw->assumed = true;
701
end:
702
return err;
703
}
704
705
static int fill_stream_formats(struct snd_oxfw *oxfw,
706
enum avc_general_plug_dir dir,
707
unsigned short pid)
708
{
709
u8 *buf, **formats;
710
unsigned int len, eid = 0;
711
struct snd_oxfw_stream_formation dummy;
712
int err;
713
714
buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
715
if (buf == NULL)
716
return -ENOMEM;
717
718
if (dir == AVC_GENERAL_PLUG_DIR_OUT)
719
formats = oxfw->tx_stream_formats;
720
else
721
formats = oxfw->rx_stream_formats;
722
723
/* get first entry */
724
len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
725
err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
726
if (err == -ENXIO) {
727
/* LIST subfunction is not implemented */
728
len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
729
err = assume_stream_formats(oxfw, dir, pid, buf, &len,
730
formats);
731
goto end;
732
} else if (err < 0) {
733
dev_err(&oxfw->unit->device,
734
"fail to get stream format %d for isoc %s plug %d:%d\n",
735
eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
736
pid, err);
737
goto end;
738
}
739
740
/* LIST subfunction is implemented */
741
while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
742
/* The format is too short. */
743
if (len < 3) {
744
err = -EIO;
745
break;
746
}
747
748
/* parse and set stream format */
749
err = snd_oxfw_stream_parse_format(buf, &dummy);
750
if (err < 0)
751
break;
752
753
formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
754
GFP_KERNEL);
755
if (!formats[eid]) {
756
err = -ENOMEM;
757
break;
758
}
759
760
/* get next entry */
761
len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
762
err = avc_stream_get_format_list(oxfw->unit, dir, 0,
763
buf, &len, ++eid);
764
/* No entries remained. */
765
if (err == -EINVAL) {
766
err = 0;
767
break;
768
} else if (err < 0) {
769
dev_err(&oxfw->unit->device,
770
"fail to get stream format %d for isoc %s plug %d:%d\n",
771
eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
772
"out",
773
pid, err);
774
break;
775
}
776
}
777
end:
778
kfree(buf);
779
return err;
780
}
781
782
int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
783
{
784
u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
785
struct snd_oxfw_stream_formation formation;
786
u8 *format;
787
unsigned int i;
788
int err;
789
790
/* the number of plugs for isoc in/out, ext in/out */
791
err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
792
if (err < 0) {
793
dev_err(&oxfw->unit->device,
794
"fail to get info for isoc/external in/out plugs: %d\n",
795
err);
796
goto end;
797
} else if ((plugs[0] == 0) && (plugs[1] == 0)) {
798
err = -ENXIO;
799
goto end;
800
}
801
802
/* use oPCR[0] if exists */
803
if (plugs[1] > 0) {
804
err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
805
if (err < 0) {
806
if (err != -ENXIO)
807
return err;
808
809
// The oPCR is not available for isoc communication.
810
err = 0;
811
} else {
812
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
813
format = oxfw->tx_stream_formats[i];
814
if (format == NULL)
815
continue;
816
err = snd_oxfw_stream_parse_format(format,
817
&formation);
818
if (err < 0)
819
continue;
820
821
/* Add one MIDI port. */
822
if (formation.midi > 0)
823
oxfw->midi_input_ports = 1;
824
}
825
826
oxfw->has_output = true;
827
}
828
}
829
830
/* use iPCR[0] if exists */
831
if (plugs[0] > 0) {
832
err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
833
if (err < 0) {
834
if (err != -ENXIO)
835
return err;
836
837
// The iPCR is not available for isoc communication.
838
err = 0;
839
} else {
840
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
841
format = oxfw->rx_stream_formats[i];
842
if (format == NULL)
843
continue;
844
err = snd_oxfw_stream_parse_format(format,
845
&formation);
846
if (err < 0)
847
continue;
848
849
/* Add one MIDI port. */
850
if (formation.midi > 0)
851
oxfw->midi_output_ports = 1;
852
}
853
854
oxfw->has_input = true;
855
}
856
}
857
end:
858
return err;
859
}
860
861
void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
862
{
863
oxfw->dev_lock_changed = true;
864
wake_up(&oxfw->hwdep_wait);
865
}
866
867
int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
868
{
869
int err;
870
871
spin_lock_irq(&oxfw->lock);
872
873
/* user land lock this */
874
if (oxfw->dev_lock_count < 0) {
875
err = -EBUSY;
876
goto end;
877
}
878
879
/* this is the first time */
880
if (oxfw->dev_lock_count++ == 0)
881
snd_oxfw_stream_lock_changed(oxfw);
882
err = 0;
883
end:
884
spin_unlock_irq(&oxfw->lock);
885
return err;
886
}
887
888
void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
889
{
890
spin_lock_irq(&oxfw->lock);
891
892
if (WARN_ON(oxfw->dev_lock_count <= 0))
893
goto end;
894
if (--oxfw->dev_lock_count == 0)
895
snd_oxfw_stream_lock_changed(oxfw);
896
end:
897
spin_unlock_irq(&oxfw->lock);
898
}
899
900