Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * oxfw_stream.c - a part of driver for OXFW970/971 based devices
0004  *
0005  * Copyright (c) 2014 Takashi Sakamoto
0006  */
0007 
0008 #include "oxfw.h"
0009 #include <linux/delay.h>
0010 
0011 #define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
0012 #define READY_TIMEOUT_MS    600
0013 
0014 /*
0015  * According to datasheet of Oxford Semiconductor:
0016  *  OXFW970: 32.0/44.1/48.0/96.0 Khz, 8 audio channels I/O
0017  *  OXFW971: 32.0/44.1/48.0/88.2/96.0/192.0 kHz, 16 audio channels I/O, MIDI I/O
0018  */
0019 static const unsigned int oxfw_rate_table[] = {
0020     [0] = 32000,
0021     [1] = 44100,
0022     [2] = 48000,
0023     [3] = 88200,
0024     [4] = 96000,
0025     [5] = 192000,
0026 };
0027 
0028 /*
0029  * See Table 5.7 – Sampling frequency for Multi-bit Audio
0030  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
0031  */
0032 static const unsigned int avc_stream_rate_table[] = {
0033     [0] = 0x02,
0034     [1] = 0x03,
0035     [2] = 0x04,
0036     [3] = 0x0a,
0037     [4] = 0x05,
0038     [5] = 0x07,
0039 };
0040 
0041 static int set_rate(struct snd_oxfw *oxfw, unsigned int rate)
0042 {
0043     int err;
0044 
0045     err = avc_general_set_sig_fmt(oxfw->unit, rate,
0046                       AVC_GENERAL_PLUG_DIR_IN, 0);
0047     if (err < 0)
0048         goto end;
0049 
0050     if (oxfw->has_output)
0051         err = avc_general_set_sig_fmt(oxfw->unit, rate,
0052                           AVC_GENERAL_PLUG_DIR_OUT, 0);
0053 end:
0054     return err;
0055 }
0056 
0057 static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
0058                  unsigned int rate, unsigned int pcm_channels)
0059 {
0060     u8 **formats;
0061     struct snd_oxfw_stream_formation formation;
0062     enum avc_general_plug_dir dir;
0063     unsigned int len;
0064     int i, err;
0065 
0066     if (s == &oxfw->tx_stream) {
0067         formats = oxfw->tx_stream_formats;
0068         dir = AVC_GENERAL_PLUG_DIR_OUT;
0069     } else {
0070         formats = oxfw->rx_stream_formats;
0071         dir = AVC_GENERAL_PLUG_DIR_IN;
0072     }
0073 
0074     /* Seek stream format for requirements. */
0075     for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
0076         err = snd_oxfw_stream_parse_format(formats[i], &formation);
0077         if (err < 0)
0078             return err;
0079 
0080         if ((formation.rate == rate) && (formation.pcm == pcm_channels))
0081             break;
0082     }
0083     if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
0084         return -EINVAL;
0085 
0086     /* If assumed, just change rate. */
0087     if (oxfw->assumed)
0088         return set_rate(oxfw, rate);
0089 
0090     /* Calculate format length. */
0091     len = 5 + formats[i][4] * 2;
0092 
0093     err = avc_stream_set_format(oxfw->unit, dir, 0, formats[i], len);
0094     if (err < 0)
0095         return err;
0096 
0097     /* Some requests just after changing format causes freezing. */
0098     msleep(100);
0099 
0100     return 0;
0101 }
0102 
0103 static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
0104 {
0105     struct cmp_connection *conn;
0106     int err;
0107 
0108     if (stream == &oxfw->rx_stream)
0109         conn = &oxfw->in_conn;
0110     else
0111         conn = &oxfw->out_conn;
0112 
0113     err = cmp_connection_establish(conn);
0114     if (err < 0)
0115         return err;
0116 
0117     err = amdtp_domain_add_stream(&oxfw->domain, stream,
0118                       conn->resources.channel, conn->speed);
0119     if (err < 0) {
0120         cmp_connection_break(conn);
0121         return err;
0122     }
0123 
0124     return 0;
0125 }
0126 
0127 static int check_connection_used_by_others(struct snd_oxfw *oxfw,
0128                        struct amdtp_stream *stream)
0129 {
0130     struct cmp_connection *conn;
0131     bool used;
0132     int err;
0133 
0134     if (stream == &oxfw->tx_stream)
0135         conn = &oxfw->out_conn;
0136     else
0137         conn = &oxfw->in_conn;
0138 
0139     err = cmp_connection_check_used(conn, &used);
0140     if ((err >= 0) && used && !amdtp_stream_running(stream)) {
0141         dev_err(&oxfw->unit->device,
0142             "Connection established by others: %cPCR[%d]\n",
0143             (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
0144             conn->pcr_index);
0145         err = -EBUSY;
0146     }
0147 
0148     return err;
0149 }
0150 
0151 static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
0152 {
0153     struct cmp_connection *conn;
0154     enum cmp_direction c_dir;
0155     enum amdtp_stream_direction s_dir;
0156     unsigned int flags = 0;
0157     int err;
0158 
0159     if (!(oxfw->quirks & SND_OXFW_QUIRK_BLOCKING_TRANSMISSION))
0160         flags |= CIP_NONBLOCKING;
0161     else
0162         flags |= CIP_BLOCKING;
0163 
0164     // OXFW 970/971 has no function to generate playback timing according to the sequence
0165     // of value in syt field, thus the packet should include NO_INFO value in the field.
0166     // However, some models just ignore data blocks in packet with NO_INFO for audio data
0167     // processing.
0168     if (!(oxfw->quirks & SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET))
0169         flags |= CIP_UNAWARE_SYT;
0170 
0171     if (stream == &oxfw->tx_stream) {
0172         conn = &oxfw->out_conn;
0173         c_dir = CMP_OUTPUT;
0174         s_dir = AMDTP_IN_STREAM;
0175 
0176         if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD)
0177             flags |= CIP_JUMBO_PAYLOAD;
0178         if (oxfw->quirks & SND_OXFW_QUIRK_WRONG_DBS)
0179             flags |= CIP_WRONG_DBS;
0180     } else {
0181         conn = &oxfw->in_conn;
0182         c_dir = CMP_INPUT;
0183         s_dir = AMDTP_OUT_STREAM;
0184     }
0185 
0186     err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
0187     if (err < 0)
0188         return err;
0189 
0190     err = amdtp_am824_init(stream, oxfw->unit, s_dir, flags);
0191     if (err < 0) {
0192         cmp_connection_destroy(conn);
0193         return err;
0194     }
0195 
0196     return 0;
0197 }
0198 
0199 static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
0200 {
0201     enum avc_general_plug_dir dir;
0202     u8 **formats;
0203     struct snd_oxfw_stream_formation formation;
0204     struct cmp_connection *conn;
0205     int i;
0206     int err;
0207 
0208     if (stream == &oxfw->rx_stream) {
0209         dir = AVC_GENERAL_PLUG_DIR_IN;
0210         formats = oxfw->rx_stream_formats;
0211         conn = &oxfw->in_conn;
0212     } else {
0213         dir = AVC_GENERAL_PLUG_DIR_OUT;
0214         formats = oxfw->tx_stream_formats;
0215         conn = &oxfw->out_conn;
0216     }
0217 
0218     err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
0219     if (err < 0)
0220         return err;
0221 
0222     for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
0223         struct snd_oxfw_stream_formation fmt;
0224 
0225         if (formats[i] == NULL)
0226             break;
0227 
0228         err = snd_oxfw_stream_parse_format(formats[i], &fmt);
0229         if (err < 0)
0230             return err;
0231 
0232         if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
0233             fmt.midi == formation.midi)
0234             break;
0235     }
0236     if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
0237         return -EINVAL;
0238 
0239     // The stream should have one pcm channels at least.
0240     if (formation.pcm == 0)
0241         return -EINVAL;
0242 
0243     err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
0244                      formation.midi * 8, false);
0245     if (err < 0)
0246         return err;
0247 
0248     return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
0249 }
0250 
0251 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
0252                    struct amdtp_stream *stream,
0253                    unsigned int rate, unsigned int pcm_channels,
0254                    unsigned int frames_per_period,
0255                    unsigned int frames_per_buffer)
0256 {
0257     struct snd_oxfw_stream_formation formation;
0258     enum avc_general_plug_dir dir;
0259     int err;
0260 
0261     // Considering JACK/FFADO streaming:
0262     // TODO: This can be removed hwdep functionality becomes popular.
0263     err = check_connection_used_by_others(oxfw, &oxfw->rx_stream);
0264     if (err < 0)
0265         return err;
0266     if (oxfw->has_output) {
0267         err = check_connection_used_by_others(oxfw, &oxfw->tx_stream);
0268         if (err < 0)
0269             return err;
0270     }
0271 
0272     if (stream == &oxfw->tx_stream)
0273         dir = AVC_GENERAL_PLUG_DIR_OUT;
0274     else
0275         dir = AVC_GENERAL_PLUG_DIR_IN;
0276 
0277     err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
0278     if (err < 0)
0279         return err;
0280     if (rate == 0) {
0281         rate = formation.rate;
0282         pcm_channels = formation.pcm;
0283     }
0284     if (formation.rate != rate || formation.pcm != pcm_channels) {
0285         amdtp_domain_stop(&oxfw->domain);
0286 
0287         cmp_connection_break(&oxfw->in_conn);
0288         cmp_connection_release(&oxfw->in_conn);
0289 
0290         if (oxfw->has_output) {
0291             cmp_connection_break(&oxfw->out_conn);
0292             cmp_connection_release(&oxfw->out_conn);
0293         }
0294     }
0295 
0296     if (oxfw->substreams_count == 0 ||
0297         formation.rate != rate || formation.pcm != pcm_channels) {
0298         err = set_stream_format(oxfw, stream, rate, pcm_channels);
0299         if (err < 0) {
0300             dev_err(&oxfw->unit->device,
0301                 "fail to set stream format: %d\n", err);
0302             return err;
0303         }
0304 
0305         err = keep_resources(oxfw, &oxfw->rx_stream);
0306         if (err < 0)
0307             return err;
0308 
0309         if (oxfw->has_output) {
0310             err = keep_resources(oxfw, &oxfw->tx_stream);
0311             if (err < 0) {
0312                 cmp_connection_release(&oxfw->in_conn);
0313                 return err;
0314             }
0315         }
0316 
0317         err = amdtp_domain_set_events_per_period(&oxfw->domain,
0318                     frames_per_period, frames_per_buffer);
0319         if (err < 0) {
0320             cmp_connection_release(&oxfw->in_conn);
0321             if (oxfw->has_output)
0322                 cmp_connection_release(&oxfw->out_conn);
0323             return err;
0324         }
0325     }
0326 
0327     return 0;
0328 }
0329 
0330 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
0331 {
0332     int err;
0333 
0334     if (oxfw->substreams_count == 0)
0335         return -EIO;
0336 
0337     if (amdtp_streaming_error(&oxfw->rx_stream) ||
0338         amdtp_streaming_error(&oxfw->tx_stream)) {
0339         amdtp_domain_stop(&oxfw->domain);
0340 
0341         cmp_connection_break(&oxfw->in_conn);
0342         if (oxfw->has_output)
0343             cmp_connection_break(&oxfw->out_conn);
0344     }
0345 
0346     if (!amdtp_stream_running(&oxfw->rx_stream)) {
0347         unsigned int tx_init_skip_cycles = 0;
0348         bool replay_seq = false;
0349 
0350         err = start_stream(oxfw, &oxfw->rx_stream);
0351         if (err < 0) {
0352             dev_err(&oxfw->unit->device,
0353                 "fail to prepare rx stream: %d\n", err);
0354             goto error;
0355         }
0356 
0357         if (oxfw->has_output &&
0358             !amdtp_stream_running(&oxfw->tx_stream)) {
0359             err = start_stream(oxfw, &oxfw->tx_stream);
0360             if (err < 0) {
0361                 dev_err(&oxfw->unit->device,
0362                     "fail to prepare tx stream: %d\n", err);
0363                 goto error;
0364             }
0365 
0366             if (oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD) {
0367                 // Just after changing sampling transfer frequency, many cycles are
0368                 // skipped for packet transmission.
0369                 tx_init_skip_cycles = 400;
0370             } else if (oxfw->quirks & SND_OXFW_QUIRK_VOLUNTARY_RECOVERY) {
0371                 // It takes a bit time for target device to adjust event frequency
0372                 // according to nominal event frequency in isochronous packets from
0373                 // ALSA oxfw driver.
0374                 tx_init_skip_cycles = 4000;
0375             } else {
0376                 replay_seq = true;
0377             }
0378         }
0379 
0380         // NOTE: The device ignores presentation time expressed by the value of syt field
0381         // of CIP header in received packets. The sequence of the number of data blocks per
0382         // packet is important for media clock recovery.
0383         err = amdtp_domain_start(&oxfw->domain, tx_init_skip_cycles, replay_seq, false);
0384         if (err < 0)
0385             goto error;
0386 
0387         if (!amdtp_domain_wait_ready(&oxfw->domain, READY_TIMEOUT_MS)) {
0388             err = -ETIMEDOUT;
0389             goto error;
0390         }
0391     }
0392 
0393     return 0;
0394 error:
0395     amdtp_domain_stop(&oxfw->domain);
0396 
0397     cmp_connection_break(&oxfw->in_conn);
0398     if (oxfw->has_output)
0399         cmp_connection_break(&oxfw->out_conn);
0400 
0401     return err;
0402 }
0403 
0404 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw)
0405 {
0406     if (oxfw->substreams_count == 0) {
0407         amdtp_domain_stop(&oxfw->domain);
0408 
0409         cmp_connection_break(&oxfw->in_conn);
0410         cmp_connection_release(&oxfw->in_conn);
0411 
0412         if (oxfw->has_output) {
0413             cmp_connection_break(&oxfw->out_conn);
0414             cmp_connection_release(&oxfw->out_conn);
0415         }
0416     }
0417 }
0418 
0419 static void destroy_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
0420 {
0421     struct cmp_connection *conn;
0422 
0423     if (stream == &oxfw->tx_stream)
0424         conn = &oxfw->out_conn;
0425     else
0426         conn = &oxfw->in_conn;
0427 
0428     amdtp_stream_destroy(stream);
0429     cmp_connection_destroy(conn);
0430 }
0431 
0432 int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw)
0433 {
0434     int err;
0435 
0436     err = init_stream(oxfw, &oxfw->rx_stream);
0437     if (err < 0)
0438         return err;
0439 
0440     if (oxfw->has_output) {
0441         err = init_stream(oxfw, &oxfw->tx_stream);
0442         if (err < 0) {
0443             destroy_stream(oxfw, &oxfw->rx_stream);
0444             return err;
0445         }
0446     }
0447 
0448     err = amdtp_domain_init(&oxfw->domain);
0449     if (err < 0) {
0450         destroy_stream(oxfw, &oxfw->rx_stream);
0451         if (oxfw->has_output)
0452             destroy_stream(oxfw, &oxfw->tx_stream);
0453     }
0454 
0455     return err;
0456 }
0457 
0458 // This function should be called before starting the stream or after stopping
0459 // the streams.
0460 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw)
0461 {
0462     amdtp_domain_destroy(&oxfw->domain);
0463 
0464     destroy_stream(oxfw, &oxfw->rx_stream);
0465 
0466     if (oxfw->has_output)
0467         destroy_stream(oxfw, &oxfw->tx_stream);
0468 }
0469 
0470 void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw)
0471 {
0472     amdtp_domain_stop(&oxfw->domain);
0473 
0474     cmp_connection_break(&oxfw->in_conn);
0475 
0476     amdtp_stream_pcm_abort(&oxfw->rx_stream);
0477 
0478     if (oxfw->has_output) {
0479         cmp_connection_break(&oxfw->out_conn);
0480 
0481         amdtp_stream_pcm_abort(&oxfw->tx_stream);
0482     }
0483 }
0484 
0485 int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
0486                 enum avc_general_plug_dir dir,
0487                 struct snd_oxfw_stream_formation *formation)
0488 {
0489     u8 *format;
0490     unsigned int len;
0491     int err;
0492 
0493     len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
0494     format = kmalloc(len, GFP_KERNEL);
0495     if (format == NULL)
0496         return -ENOMEM;
0497 
0498     err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
0499     if (err < 0)
0500         goto end;
0501     if (len < 3) {
0502         err = -EIO;
0503         goto end;
0504     }
0505 
0506     err = snd_oxfw_stream_parse_format(format, formation);
0507 end:
0508     kfree(format);
0509     return err;
0510 }
0511 
0512 /*
0513  * See Table 6.16 - AM824 Stream Format
0514  *     Figure 6.19 - format_information field for AM824 Compound
0515  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
0516  * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
0517  */
0518 int snd_oxfw_stream_parse_format(u8 *format,
0519                  struct snd_oxfw_stream_formation *formation)
0520 {
0521     unsigned int i, e, channels, type;
0522 
0523     memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
0524 
0525     /*
0526      * this module can support a hierarchy combination that:
0527      *  Root:   Audio and Music (0x90)
0528      *  Level 1:    AM824 Compound  (0x40)
0529      */
0530     if ((format[0] != 0x90) || (format[1] != 0x40))
0531         return -ENXIO;
0532 
0533     /* check the sampling rate */
0534     for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
0535         if (format[2] == avc_stream_rate_table[i])
0536             break;
0537     }
0538     if (i == ARRAY_SIZE(avc_stream_rate_table))
0539         return -ENXIO;
0540 
0541     formation->rate = oxfw_rate_table[i];
0542 
0543     for (e = 0; e < format[4]; e++) {
0544         channels = format[5 + e * 2];
0545         type = format[6 + e * 2];
0546 
0547         switch (type) {
0548         /* IEC 60958 Conformant, currently handled as MBLA */
0549         case 0x00:
0550         /* Multi Bit Linear Audio (Raw) */
0551         case 0x06:
0552             formation->pcm += channels;
0553             break;
0554         /* MIDI Conformant */
0555         case 0x0d:
0556             formation->midi = channels;
0557             break;
0558         /* IEC 61937-3 to 7 */
0559         case 0x01:
0560         case 0x02:
0561         case 0x03:
0562         case 0x04:
0563         case 0x05:
0564         /* Multi Bit Linear Audio */
0565         case 0x07:  /* DVD-Audio */
0566         case 0x0c:  /* High Precision */
0567         /* One Bit Audio */
0568         case 0x08:  /* (Plain) Raw */
0569         case 0x09:  /* (Plain) SACD */
0570         case 0x0a:  /* (Encoded) Raw */
0571         case 0x0b:  /* (Encoded) SACD */
0572         /* SMPTE Time-Code conformant */
0573         case 0x0e:
0574         /* Sample Count */
0575         case 0x0f:
0576         /* Anciliary Data */
0577         case 0x10:
0578         /* Synchronization Stream (Stereo Raw audio) */
0579         case 0x40:
0580         /* Don't care */
0581         case 0xff:
0582         default:
0583             return -ENXIO;  /* not supported */
0584         }
0585     }
0586 
0587     if (formation->pcm  > AM824_MAX_CHANNELS_FOR_PCM ||
0588         formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
0589         return -ENXIO;
0590 
0591     return 0;
0592 }
0593 
0594 static int
0595 assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
0596               unsigned int pid, u8 *buf, unsigned int *len,
0597               u8 **formats)
0598 {
0599     struct snd_oxfw_stream_formation formation;
0600     unsigned int i, eid;
0601     int err;
0602 
0603     /* get format at current sampling rate */
0604     err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
0605     if (err < 0) {
0606         dev_err(&oxfw->unit->device,
0607         "fail to get current stream format for isoc %s plug %d:%d\n",
0608             (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
0609             pid, err);
0610         goto end;
0611     }
0612 
0613     /* parse and set stream format */
0614     eid = 0;
0615     err = snd_oxfw_stream_parse_format(buf, &formation);
0616     if (err < 0)
0617         goto end;
0618 
0619     formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
0620                     GFP_KERNEL);
0621     if (!formats[eid]) {
0622         err = -ENOMEM;
0623         goto end;
0624     }
0625 
0626     /* apply the format for each available sampling rate */
0627     for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
0628         if (formation.rate == oxfw_rate_table[i])
0629             continue;
0630 
0631         err = avc_general_inquiry_sig_fmt(oxfw->unit,
0632                           oxfw_rate_table[i],
0633                           dir, pid);
0634         if (err < 0)
0635             continue;
0636 
0637         eid++;
0638         formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
0639                         GFP_KERNEL);
0640         if (formats[eid] == NULL) {
0641             err = -ENOMEM;
0642             goto end;
0643         }
0644         formats[eid][2] = avc_stream_rate_table[i];
0645     }
0646 
0647     err = 0;
0648     oxfw->assumed = true;
0649 end:
0650     return err;
0651 }
0652 
0653 static int fill_stream_formats(struct snd_oxfw *oxfw,
0654                    enum avc_general_plug_dir dir,
0655                    unsigned short pid)
0656 {
0657     u8 *buf, **formats;
0658     unsigned int len, eid = 0;
0659     struct snd_oxfw_stream_formation dummy;
0660     int err;
0661 
0662     buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
0663     if (buf == NULL)
0664         return -ENOMEM;
0665 
0666     if (dir == AVC_GENERAL_PLUG_DIR_OUT)
0667         formats = oxfw->tx_stream_formats;
0668     else
0669         formats = oxfw->rx_stream_formats;
0670 
0671     /* get first entry */
0672     len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
0673     err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
0674     if (err == -ENXIO) {
0675         /* LIST subfunction is not implemented */
0676         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
0677         err = assume_stream_formats(oxfw, dir, pid, buf, &len,
0678                         formats);
0679         goto end;
0680     } else if (err < 0) {
0681         dev_err(&oxfw->unit->device,
0682             "fail to get stream format %d for isoc %s plug %d:%d\n",
0683             eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
0684             pid, err);
0685         goto end;
0686     }
0687 
0688     /* LIST subfunction is implemented */
0689     while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
0690         /* The format is too short. */
0691         if (len < 3) {
0692             err = -EIO;
0693             break;
0694         }
0695 
0696         /* parse and set stream format */
0697         err = snd_oxfw_stream_parse_format(buf, &dummy);
0698         if (err < 0)
0699             break;
0700 
0701         formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
0702                         GFP_KERNEL);
0703         if (!formats[eid]) {
0704             err = -ENOMEM;
0705             break;
0706         }
0707 
0708         /* get next entry */
0709         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
0710         err = avc_stream_get_format_list(oxfw->unit, dir, 0,
0711                          buf, &len, ++eid);
0712         /* No entries remained. */
0713         if (err == -EINVAL) {
0714             err = 0;
0715             break;
0716         } else if (err < 0) {
0717             dev_err(&oxfw->unit->device,
0718             "fail to get stream format %d for isoc %s plug %d:%d\n",
0719                 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
0720                                     "out",
0721                 pid, err);
0722             break;
0723         }
0724     }
0725 end:
0726     kfree(buf);
0727     return err;
0728 }
0729 
0730 int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
0731 {
0732     u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
0733     struct snd_oxfw_stream_formation formation;
0734     u8 *format;
0735     unsigned int i;
0736     int err;
0737 
0738     /* the number of plugs for isoc in/out, ext in/out  */
0739     err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
0740     if (err < 0) {
0741         dev_err(&oxfw->unit->device,
0742         "fail to get info for isoc/external in/out plugs: %d\n",
0743             err);
0744         goto end;
0745     } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
0746         err = -ENXIO;
0747         goto end;
0748     }
0749 
0750     /* use oPCR[0] if exists */
0751     if (plugs[1] > 0) {
0752         err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
0753         if (err < 0) {
0754             if (err != -ENXIO)
0755                 return err;
0756 
0757             // The oPCR is not available for isoc communication.
0758             err = 0;
0759         } else {
0760             for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
0761                 format = oxfw->tx_stream_formats[i];
0762                 if (format == NULL)
0763                     continue;
0764                 err = snd_oxfw_stream_parse_format(format,
0765                                    &formation);
0766                 if (err < 0)
0767                     continue;
0768 
0769                 /* Add one MIDI port. */
0770                 if (formation.midi > 0)
0771                     oxfw->midi_input_ports = 1;
0772             }
0773 
0774             oxfw->has_output = true;
0775         }
0776     }
0777 
0778     /* use iPCR[0] if exists */
0779     if (plugs[0] > 0) {
0780         err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
0781         if (err < 0) {
0782             if (err != -ENXIO)
0783                 return err;
0784 
0785             // The iPCR is not available for isoc communication.
0786             err = 0;
0787         } else {
0788             for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
0789                 format = oxfw->rx_stream_formats[i];
0790                 if (format == NULL)
0791                     continue;
0792                 err = snd_oxfw_stream_parse_format(format,
0793                                    &formation);
0794                 if (err < 0)
0795                     continue;
0796 
0797                 /* Add one MIDI port. */
0798                 if (formation.midi > 0)
0799                     oxfw->midi_output_ports = 1;
0800             }
0801 
0802             oxfw->has_input = true;
0803         }
0804     }
0805 end:
0806     return err;
0807 }
0808 
0809 void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
0810 {
0811     oxfw->dev_lock_changed = true;
0812     wake_up(&oxfw->hwdep_wait);
0813 }
0814 
0815 int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
0816 {
0817     int err;
0818 
0819     spin_lock_irq(&oxfw->lock);
0820 
0821     /* user land lock this */
0822     if (oxfw->dev_lock_count < 0) {
0823         err = -EBUSY;
0824         goto end;
0825     }
0826 
0827     /* this is the first time */
0828     if (oxfw->dev_lock_count++ == 0)
0829         snd_oxfw_stream_lock_changed(oxfw);
0830     err = 0;
0831 end:
0832     spin_unlock_irq(&oxfw->lock);
0833     return err;
0834 }
0835 
0836 void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
0837 {
0838     spin_lock_irq(&oxfw->lock);
0839 
0840     if (WARN_ON(oxfw->dev_lock_count <= 0))
0841         goto end;
0842     if (--oxfw->dev_lock_count == 0)
0843         snd_oxfw_stream_lock_changed(oxfw);
0844 end:
0845     spin_unlock_irq(&oxfw->lock);
0846 }