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