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