a6e97a37f1295a9993a58f691cd998cd5af599a0
[sfrench/cifs-2.6.git] / sound / firewire / oxfw / oxfw-stream.c
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        200
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;
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         if (stream == &oxfw->tx_stream) {
165                 conn = &oxfw->out_conn;
166                 c_dir = CMP_OUTPUT;
167                 s_dir = AMDTP_IN_STREAM;
168
169                 if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD)
170                         flags |= CIP_JUMBO_PAYLOAD;
171                 if (oxfw->quirks & SND_OXFW_QUIRK_WRONG_DBS)
172                         flags |= CIP_WRONG_DBS;
173         } else {
174                 conn = &oxfw->in_conn;
175                 c_dir = CMP_INPUT;
176                 s_dir = AMDTP_OUT_STREAM;
177         }
178
179         err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
180         if (err < 0)
181                 return err;
182
183         err = amdtp_am824_init(stream, oxfw->unit, s_dir, flags);
184         if (err < 0) {
185                 cmp_connection_destroy(conn);
186                 return err;
187         }
188
189         return 0;
190 }
191
192 static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
193 {
194         enum avc_general_plug_dir dir;
195         u8 **formats;
196         struct snd_oxfw_stream_formation formation;
197         struct cmp_connection *conn;
198         int i;
199         int err;
200
201         if (stream == &oxfw->rx_stream) {
202                 dir = AVC_GENERAL_PLUG_DIR_IN;
203                 formats = oxfw->rx_stream_formats;
204                 conn = &oxfw->in_conn;
205         } else {
206                 dir = AVC_GENERAL_PLUG_DIR_OUT;
207                 formats = oxfw->tx_stream_formats;
208                 conn = &oxfw->out_conn;
209         }
210
211         err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
212         if (err < 0)
213                 return err;
214
215         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
216                 struct snd_oxfw_stream_formation fmt;
217
218                 if (formats[i] == NULL)
219                         break;
220
221                 err = snd_oxfw_stream_parse_format(formats[i], &fmt);
222                 if (err < 0)
223                         return err;
224
225                 if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
226                     fmt.midi == formation.midi)
227                         break;
228         }
229         if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
230                 return -EINVAL;
231
232         // The stream should have one pcm channels at least.
233         if (formation.pcm == 0)
234                 return -EINVAL;
235
236         err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
237                                          formation.midi * 8, false);
238         if (err < 0)
239                 return err;
240
241         return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
242 }
243
244 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
245                                    struct amdtp_stream *stream,
246                                    unsigned int rate, unsigned int pcm_channels,
247                                    unsigned int frames_per_period,
248                                    unsigned int frames_per_buffer)
249 {
250         struct snd_oxfw_stream_formation formation;
251         enum avc_general_plug_dir dir;
252         int err;
253
254         // Considering JACK/FFADO streaming:
255         // TODO: This can be removed hwdep functionality becomes popular.
256         err = check_connection_used_by_others(oxfw, &oxfw->rx_stream);
257         if (err < 0)
258                 return err;
259         if (oxfw->has_output) {
260                 err = check_connection_used_by_others(oxfw, &oxfw->tx_stream);
261                 if (err < 0)
262                         return err;
263         }
264
265         if (stream == &oxfw->tx_stream)
266                 dir = AVC_GENERAL_PLUG_DIR_OUT;
267         else
268                 dir = AVC_GENERAL_PLUG_DIR_IN;
269
270         err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
271         if (err < 0)
272                 return err;
273         if (rate == 0) {
274                 rate = formation.rate;
275                 pcm_channels = formation.pcm;
276         }
277         if (formation.rate != rate || formation.pcm != pcm_channels) {
278                 amdtp_domain_stop(&oxfw->domain);
279
280                 cmp_connection_break(&oxfw->in_conn);
281                 cmp_connection_release(&oxfw->in_conn);
282
283                 if (oxfw->has_output) {
284                         cmp_connection_break(&oxfw->out_conn);
285                         cmp_connection_release(&oxfw->out_conn);
286                 }
287         }
288
289         if (oxfw->substreams_count == 0 ||
290             formation.rate != rate || formation.pcm != pcm_channels) {
291                 err = set_stream_format(oxfw, stream, rate, pcm_channels);
292                 if (err < 0) {
293                         dev_err(&oxfw->unit->device,
294                                 "fail to set stream format: %d\n", err);
295                         return err;
296                 }
297
298                 err = keep_resources(oxfw, &oxfw->rx_stream);
299                 if (err < 0)
300                         return err;
301
302                 if (oxfw->has_output) {
303                         err = keep_resources(oxfw, &oxfw->tx_stream);
304                         if (err < 0) {
305                                 cmp_connection_release(&oxfw->in_conn);
306                                 return err;
307                         }
308                 }
309
310                 err = amdtp_domain_set_events_per_period(&oxfw->domain,
311                                         frames_per_period, frames_per_buffer);
312                 if (err < 0) {
313                         cmp_connection_release(&oxfw->in_conn);
314                         if (oxfw->has_output)
315                                 cmp_connection_release(&oxfw->out_conn);
316                         return err;
317                 }
318         }
319
320         return 0;
321 }
322
323 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
324 {
325         int err;
326
327         if (oxfw->substreams_count == 0)
328                 return -EIO;
329
330         if (amdtp_streaming_error(&oxfw->rx_stream) ||
331             amdtp_streaming_error(&oxfw->tx_stream)) {
332                 amdtp_domain_stop(&oxfw->domain);
333
334                 cmp_connection_break(&oxfw->in_conn);
335                 if (oxfw->has_output)
336                         cmp_connection_break(&oxfw->out_conn);
337         }
338
339         if (!amdtp_stream_running(&oxfw->rx_stream)) {
340                 err = start_stream(oxfw, &oxfw->rx_stream);
341                 if (err < 0) {
342                         dev_err(&oxfw->unit->device,
343                                 "fail to prepare rx stream: %d\n", err);
344                         goto error;
345                 }
346
347                 if (oxfw->has_output &&
348                     !amdtp_stream_running(&oxfw->tx_stream)) {
349                         err = start_stream(oxfw, &oxfw->tx_stream);
350                         if (err < 0) {
351                                 dev_err(&oxfw->unit->device,
352                                         "fail to prepare tx stream: %d\n", err);
353                                 goto error;
354                         }
355                 }
356
357                 err = amdtp_domain_start(&oxfw->domain, 0, false);
358                 if (err < 0)
359                         goto error;
360
361                 if (!amdtp_domain_wait_ready(&oxfw->domain, READY_TIMEOUT_MS)) {
362                         err = -ETIMEDOUT;
363                         goto error;
364                 }
365         }
366
367         return 0;
368 error:
369         amdtp_domain_stop(&oxfw->domain);
370
371         cmp_connection_break(&oxfw->in_conn);
372         if (oxfw->has_output)
373                 cmp_connection_break(&oxfw->out_conn);
374
375         return err;
376 }
377
378 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw)
379 {
380         if (oxfw->substreams_count == 0) {
381                 amdtp_domain_stop(&oxfw->domain);
382
383                 cmp_connection_break(&oxfw->in_conn);
384                 cmp_connection_release(&oxfw->in_conn);
385
386                 if (oxfw->has_output) {
387                         cmp_connection_break(&oxfw->out_conn);
388                         cmp_connection_release(&oxfw->out_conn);
389                 }
390         }
391 }
392
393 static void destroy_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
394 {
395         struct cmp_connection *conn;
396
397         if (stream == &oxfw->tx_stream)
398                 conn = &oxfw->out_conn;
399         else
400                 conn = &oxfw->in_conn;
401
402         amdtp_stream_destroy(stream);
403         cmp_connection_destroy(conn);
404 }
405
406 int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw)
407 {
408         int err;
409
410         err = init_stream(oxfw, &oxfw->rx_stream);
411         if (err < 0)
412                 return err;
413
414         if (oxfw->has_output) {
415                 err = init_stream(oxfw, &oxfw->tx_stream);
416                 if (err < 0) {
417                         destroy_stream(oxfw, &oxfw->rx_stream);
418                         return err;
419                 }
420         }
421
422         err = amdtp_domain_init(&oxfw->domain);
423         if (err < 0) {
424                 destroy_stream(oxfw, &oxfw->rx_stream);
425                 if (oxfw->has_output)
426                         destroy_stream(oxfw, &oxfw->tx_stream);
427         }
428
429         return err;
430 }
431
432 // This function should be called before starting the stream or after stopping
433 // the streams.
434 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw)
435 {
436         amdtp_domain_destroy(&oxfw->domain);
437
438         destroy_stream(oxfw, &oxfw->rx_stream);
439
440         if (oxfw->has_output)
441                 destroy_stream(oxfw, &oxfw->tx_stream);
442 }
443
444 void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw)
445 {
446         amdtp_domain_stop(&oxfw->domain);
447
448         cmp_connection_break(&oxfw->in_conn);
449
450         amdtp_stream_pcm_abort(&oxfw->rx_stream);
451
452         if (oxfw->has_output) {
453                 cmp_connection_break(&oxfw->out_conn);
454
455                 amdtp_stream_pcm_abort(&oxfw->tx_stream);
456         }
457 }
458
459 int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
460                                 enum avc_general_plug_dir dir,
461                                 struct snd_oxfw_stream_formation *formation)
462 {
463         u8 *format;
464         unsigned int len;
465         int err;
466
467         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
468         format = kmalloc(len, GFP_KERNEL);
469         if (format == NULL)
470                 return -ENOMEM;
471
472         err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
473         if (err < 0)
474                 goto end;
475         if (len < 3) {
476                 err = -EIO;
477                 goto end;
478         }
479
480         err = snd_oxfw_stream_parse_format(format, formation);
481 end:
482         kfree(format);
483         return err;
484 }
485
486 /*
487  * See Table 6.16 - AM824 Stream Format
488  *     Figure 6.19 - format_information field for AM824 Compound
489  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
490  * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
491  */
492 int snd_oxfw_stream_parse_format(u8 *format,
493                                  struct snd_oxfw_stream_formation *formation)
494 {
495         unsigned int i, e, channels, type;
496
497         memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
498
499         /*
500          * this module can support a hierarchy combination that:
501          *  Root:       Audio and Music (0x90)
502          *  Level 1:    AM824 Compound  (0x40)
503          */
504         if ((format[0] != 0x90) || (format[1] != 0x40))
505                 return -ENXIO;
506
507         /* check the sampling rate */
508         for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
509                 if (format[2] == avc_stream_rate_table[i])
510                         break;
511         }
512         if (i == ARRAY_SIZE(avc_stream_rate_table))
513                 return -ENXIO;
514
515         formation->rate = oxfw_rate_table[i];
516
517         for (e = 0; e < format[4]; e++) {
518                 channels = format[5 + e * 2];
519                 type = format[6 + e * 2];
520
521                 switch (type) {
522                 /* IEC 60958 Conformant, currently handled as MBLA */
523                 case 0x00:
524                 /* Multi Bit Linear Audio (Raw) */
525                 case 0x06:
526                         formation->pcm += channels;
527                         break;
528                 /* MIDI Conformant */
529                 case 0x0d:
530                         formation->midi = channels;
531                         break;
532                 /* IEC 61937-3 to 7 */
533                 case 0x01:
534                 case 0x02:
535                 case 0x03:
536                 case 0x04:
537                 case 0x05:
538                 /* Multi Bit Linear Audio */
539                 case 0x07:      /* DVD-Audio */
540                 case 0x0c:      /* High Precision */
541                 /* One Bit Audio */
542                 case 0x08:      /* (Plain) Raw */
543                 case 0x09:      /* (Plain) SACD */
544                 case 0x0a:      /* (Encoded) Raw */
545                 case 0x0b:      /* (Encoded) SACD */
546                 /* SMPTE Time-Code conformant */
547                 case 0x0e:
548                 /* Sample Count */
549                 case 0x0f:
550                 /* Anciliary Data */
551                 case 0x10:
552                 /* Synchronization Stream (Stereo Raw audio) */
553                 case 0x40:
554                 /* Don't care */
555                 case 0xff:
556                 default:
557                         return -ENXIO;  /* not supported */
558                 }
559         }
560
561         if (formation->pcm  > AM824_MAX_CHANNELS_FOR_PCM ||
562             formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
563                 return -ENXIO;
564
565         return 0;
566 }
567
568 static int
569 assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
570                       unsigned int pid, u8 *buf, unsigned int *len,
571                       u8 **formats)
572 {
573         struct snd_oxfw_stream_formation formation;
574         unsigned int i, eid;
575         int err;
576
577         /* get format at current sampling rate */
578         err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
579         if (err < 0) {
580                 dev_err(&oxfw->unit->device,
581                 "fail to get current stream format for isoc %s plug %d:%d\n",
582                         (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
583                         pid, err);
584                 goto end;
585         }
586
587         /* parse and set stream format */
588         eid = 0;
589         err = snd_oxfw_stream_parse_format(buf, &formation);
590         if (err < 0)
591                 goto end;
592
593         formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
594                                     GFP_KERNEL);
595         if (!formats[eid]) {
596                 err = -ENOMEM;
597                 goto end;
598         }
599
600         /* apply the format for each available sampling rate */
601         for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
602                 if (formation.rate == oxfw_rate_table[i])
603                         continue;
604
605                 err = avc_general_inquiry_sig_fmt(oxfw->unit,
606                                                   oxfw_rate_table[i],
607                                                   dir, pid);
608                 if (err < 0)
609                         continue;
610
611                 eid++;
612                 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
613                                             GFP_KERNEL);
614                 if (formats[eid] == NULL) {
615                         err = -ENOMEM;
616                         goto end;
617                 }
618                 formats[eid][2] = avc_stream_rate_table[i];
619         }
620
621         err = 0;
622         oxfw->assumed = true;
623 end:
624         return err;
625 }
626
627 static int fill_stream_formats(struct snd_oxfw *oxfw,
628                                enum avc_general_plug_dir dir,
629                                unsigned short pid)
630 {
631         u8 *buf, **formats;
632         unsigned int len, eid = 0;
633         struct snd_oxfw_stream_formation dummy;
634         int err;
635
636         buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
637         if (buf == NULL)
638                 return -ENOMEM;
639
640         if (dir == AVC_GENERAL_PLUG_DIR_OUT)
641                 formats = oxfw->tx_stream_formats;
642         else
643                 formats = oxfw->rx_stream_formats;
644
645         /* get first entry */
646         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
647         err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
648         if (err == -ENXIO) {
649                 /* LIST subfunction is not implemented */
650                 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
651                 err = assume_stream_formats(oxfw, dir, pid, buf, &len,
652                                             formats);
653                 goto end;
654         } else if (err < 0) {
655                 dev_err(&oxfw->unit->device,
656                         "fail to get stream format %d for isoc %s plug %d:%d\n",
657                         eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
658                         pid, err);
659                 goto end;
660         }
661
662         /* LIST subfunction is implemented */
663         while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
664                 /* The format is too short. */
665                 if (len < 3) {
666                         err = -EIO;
667                         break;
668                 }
669
670                 /* parse and set stream format */
671                 err = snd_oxfw_stream_parse_format(buf, &dummy);
672                 if (err < 0)
673                         break;
674
675                 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
676                                             GFP_KERNEL);
677                 if (!formats[eid]) {
678                         err = -ENOMEM;
679                         break;
680                 }
681
682                 /* get next entry */
683                 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
684                 err = avc_stream_get_format_list(oxfw->unit, dir, 0,
685                                                  buf, &len, ++eid);
686                 /* No entries remained. */
687                 if (err == -EINVAL) {
688                         err = 0;
689                         break;
690                 } else if (err < 0) {
691                         dev_err(&oxfw->unit->device,
692                         "fail to get stream format %d for isoc %s plug %d:%d\n",
693                                 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
694                                                                         "out",
695                                 pid, err);
696                         break;
697                 }
698         }
699 end:
700         kfree(buf);
701         return err;
702 }
703
704 int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
705 {
706         u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
707         struct snd_oxfw_stream_formation formation;
708         u8 *format;
709         unsigned int i;
710         int err;
711
712         /* the number of plugs for isoc in/out, ext in/out  */
713         err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
714         if (err < 0) {
715                 dev_err(&oxfw->unit->device,
716                 "fail to get info for isoc/external in/out plugs: %d\n",
717                         err);
718                 goto end;
719         } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
720                 err = -ENXIO;
721                 goto end;
722         }
723
724         /* use oPCR[0] if exists */
725         if (plugs[1] > 0) {
726                 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
727                 if (err < 0) {
728                         if (err != -ENXIO)
729                                 return err;
730
731                         // The oPCR is not available for isoc communication.
732                         err = 0;
733                 } else {
734                         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
735                                 format = oxfw->tx_stream_formats[i];
736                                 if (format == NULL)
737                                         continue;
738                                 err = snd_oxfw_stream_parse_format(format,
739                                                                    &formation);
740                                 if (err < 0)
741                                         continue;
742
743                                 /* Add one MIDI port. */
744                                 if (formation.midi > 0)
745                                         oxfw->midi_input_ports = 1;
746                         }
747
748                         oxfw->has_output = true;
749                 }
750         }
751
752         /* use iPCR[0] if exists */
753         if (plugs[0] > 0) {
754                 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
755                 if (err < 0) {
756                         if (err != -ENXIO)
757                                 return err;
758
759                         // The iPCR is not available for isoc communication.
760                         err = 0;
761                 } else {
762                         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
763                                 format = oxfw->rx_stream_formats[i];
764                                 if (format == NULL)
765                                         continue;
766                                 err = snd_oxfw_stream_parse_format(format,
767                                                                    &formation);
768                                 if (err < 0)
769                                         continue;
770
771                                 /* Add one MIDI port. */
772                                 if (formation.midi > 0)
773                                         oxfw->midi_output_ports = 1;
774                         }
775
776                         oxfw->has_input = true;
777                 }
778         }
779 end:
780         return err;
781 }
782
783 void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
784 {
785         oxfw->dev_lock_changed = true;
786         wake_up(&oxfw->hwdep_wait);
787 }
788
789 int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
790 {
791         int err;
792
793         spin_lock_irq(&oxfw->lock);
794
795         /* user land lock this */
796         if (oxfw->dev_lock_count < 0) {
797                 err = -EBUSY;
798                 goto end;
799         }
800
801         /* this is the first time */
802         if (oxfw->dev_lock_count++ == 0)
803                 snd_oxfw_stream_lock_changed(oxfw);
804         err = 0;
805 end:
806         spin_unlock_irq(&oxfw->lock);
807         return err;
808 }
809
810 void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
811 {
812         spin_lock_irq(&oxfw->lock);
813
814         if (WARN_ON(oxfw->dev_lock_count <= 0))
815                 goto end;
816         if (--oxfw->dev_lock_count == 0)
817                 snd_oxfw_stream_lock_changed(oxfw);
818 end:
819         spin_unlock_irq(&oxfw->lock);
820 }