blob: 5ffedb0ade3f8e93713ff44fc07ab9ced3b21f4d [file] [log] [blame]
Thomas Gleixnerda607e12019-05-29 16:57:59 -07001// SPDX-License-Identifier: GPL-2.0-only
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +09002/*
3 * oxfw_stream.c - a part of driver for OXFW970/971 based devices
4 *
5 * Copyright (c) 2014 Takashi Sakamoto
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +09006 */
7
8#include "oxfw.h"
Takashi Sakamotof3699e22014-12-09 00:10:44 +09009#include <linux/delay.h>
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +090010
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +090011#define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
Takashi Sakamotof3699e22014-12-09 00:10:44 +090012#define CALLBACK_TIMEOUT 200
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +090013
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 */
19static 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 */
32static 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
Takashi Sakamotob0ac0002014-12-09 00:10:46 +090041static 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);
53end:
54 return err;
55}
56
Takashi Sakamotof3699e22014-12-09 00:10:44 +090057static 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;
Dan Carpenter5580ba72014-12-12 22:27:03 +030063 unsigned int len;
64 int i, err;
Takashi Sakamotof3699e22014-12-09 00:10:44 +090065
Takashi Sakamotob0ac0002014-12-09 00:10:46 +090066 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 }
Takashi Sakamotof3699e22014-12-09 00:10:44 +090073
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)
Takashi Sakamotob0ac0002014-12-09 00:10:46 +090088 return set_rate(oxfw, rate);
Takashi Sakamotof3699e22014-12-09 00:10:44 +090089
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
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900103static void stop_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900104{
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900105 amdtp_stream_pcm_abort(stream);
106 amdtp_stream_stop(stream);
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900107
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900108 if (stream == &oxfw->tx_stream)
109 cmp_connection_break(&oxfw->out_conn);
110 else
111 cmp_connection_break(&oxfw->in_conn);
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900112}
113
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900114static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream,
115 unsigned int rate, unsigned int pcm_channels)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900116{
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900117 u8 **formats;
118 struct cmp_connection *conn;
119 struct snd_oxfw_stream_formation formation;
120 unsigned int i, midi_ports;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900121 int err;
122
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900123 if (stream == &oxfw->rx_stream) {
124 formats = oxfw->rx_stream_formats;
125 conn = &oxfw->in_conn;
126 } else {
127 formats = oxfw->tx_stream_formats;
128 conn = &oxfw->out_conn;
129 }
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900130
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900131 /* Get stream format */
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900132 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
133 if (formats[i] == NULL)
134 break;
135
136 err = snd_oxfw_stream_parse_format(formats[i], &formation);
137 if (err < 0)
138 goto end;
139 if (rate != formation.rate)
140 continue;
141 if (pcm_channels == 0 || pcm_channels == formation.pcm)
142 break;
143 }
144 if (i == SND_OXFW_STREAM_FORMAT_ENTRIES) {
145 err = -EINVAL;
146 goto end;
147 }
148
149 pcm_channels = formation.pcm;
Takashi Sakamotobb71da42015-10-18 17:09:39 +0900150 midi_ports = formation.midi * 8;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900151
152 /* The stream should have one pcm channels at least */
153 if (pcm_channels == 0) {
154 err = -EINVAL;
155 goto end;
156 }
Takashi Sakamoto51c29fd2015-09-19 11:21:56 +0900157 err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports,
158 false);
Takashi Sakamoto547e6312015-09-19 11:21:49 +0900159 if (err < 0)
160 goto end;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900161
162 err = cmp_connection_establish(conn,
163 amdtp_stream_get_max_payload(stream));
164 if (err < 0)
165 goto end;
166
167 err = amdtp_stream_start(stream,
168 conn->resources.channel,
169 conn->speed);
170 if (err < 0) {
171 cmp_connection_break(conn);
172 goto end;
173 }
174
175 /* Wait first packet */
Takashi Sakamotof2b14c02015-02-27 09:39:32 +0900176 if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900177 stop_stream(oxfw, stream);
Takashi Sakamotof2b14c02015-02-27 09:39:32 +0900178 err = -ETIMEDOUT;
179 }
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900180end:
181 return err;
182}
183
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900184static int check_connection_used_by_others(struct snd_oxfw *oxfw,
185 struct amdtp_stream *stream)
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900186{
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900187 struct cmp_connection *conn;
188 bool used;
189 int err;
190
191 if (stream == &oxfw->tx_stream)
192 conn = &oxfw->out_conn;
193 else
194 conn = &oxfw->in_conn;
195
196 err = cmp_connection_check_used(conn, &used);
197 if ((err >= 0) && used && !amdtp_stream_running(stream)) {
198 dev_err(&oxfw->unit->device,
199 "Connection established by others: %cPCR[%d]\n",
200 (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
201 conn->pcr_index);
202 err = -EBUSY;
203 }
204
205 return err;
206}
207
208int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw,
209 struct amdtp_stream *stream)
210{
211 struct cmp_connection *conn;
212 enum cmp_direction c_dir;
213 enum amdtp_stream_direction s_dir;
214 int err;
215
216 if (stream == &oxfw->tx_stream) {
217 conn = &oxfw->out_conn;
218 c_dir = CMP_OUTPUT;
219 s_dir = AMDTP_IN_STREAM;
220 } else {
221 conn = &oxfw->in_conn;
222 c_dir = CMP_INPUT;
223 s_dir = AMDTP_OUT_STREAM;
224 }
225
226 err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
227 if (err < 0)
228 goto end;
229
Takashi Sakamoto59558152015-09-19 11:21:55 +0900230 err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900231 if (err < 0) {
232 amdtp_stream_destroy(stream);
233 cmp_connection_destroy(conn);
234 goto end;
235 }
236
Takashi Sakamotoa2064712015-05-22 23:00:50 +0900237 /*
238 * OXFW starts to transmit packets with non-zero dbc.
239 * OXFW postpone transferring packets till handling any asynchronous
240 * packets. As a result, next isochronous packet includes more data
241 * blocks than IEC 61883-6 defines.
242 */
Takashi Sakamoto13f3a462015-09-20 21:18:55 +0900243 if (stream == &oxfw->tx_stream) {
Takashi Sakamoto62f00e42016-05-09 23:15:56 +0900244 oxfw->tx_stream.flags |= CIP_JUMBO_PAYLOAD;
Takashi Sakamoto13f3a462015-09-20 21:18:55 +0900245 if (oxfw->wrong_dbs)
246 oxfw->tx_stream.flags |= CIP_WRONG_DBS;
247 }
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900248end:
249 return err;
250}
251
252int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw,
253 struct amdtp_stream *stream,
254 unsigned int rate, unsigned int pcm_channels)
255{
256 struct amdtp_stream *opposite;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900257 struct snd_oxfw_stream_formation formation;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900258 enum avc_general_plug_dir dir;
259 unsigned int substreams, opposite_substreams;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900260 int err = 0;
261
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900262 if (stream == &oxfw->tx_stream) {
263 substreams = oxfw->capture_substreams;
264 opposite = &oxfw->rx_stream;
265 opposite_substreams = oxfw->playback_substreams;
266 dir = AVC_GENERAL_PLUG_DIR_OUT;
267 } else {
268 substreams = oxfw->playback_substreams;
269 opposite_substreams = oxfw->capture_substreams;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900270
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900271 if (oxfw->has_output)
272 opposite = &oxfw->rx_stream;
273 else
274 opposite = NULL;
275
276 dir = AVC_GENERAL_PLUG_DIR_IN;
277 }
278
279 if (substreams == 0)
280 goto end;
281
282 /*
283 * Considering JACK/FFADO streaming:
284 * TODO: This can be removed hwdep functionality becomes popular.
285 */
286 err = check_connection_used_by_others(oxfw, stream);
287 if (err < 0)
288 goto end;
289
290 /* packet queueing error */
291 if (amdtp_streaming_error(stream))
292 stop_stream(oxfw, stream);
293
294 err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900295 if (err < 0)
296 goto end;
Takashi Sakamoto05588d32014-12-09 00:10:48 +0900297 if (rate == 0)
298 rate = formation.rate;
299 if (pcm_channels == 0)
300 pcm_channels = formation.pcm;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900301
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900302 if ((formation.rate != rate) || (formation.pcm != pcm_channels)) {
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900303 if (opposite != NULL) {
304 err = check_connection_used_by_others(oxfw, opposite);
305 if (err < 0)
306 goto end;
307 stop_stream(oxfw, opposite);
308 }
309 stop_stream(oxfw, stream);
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900310
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900311 err = set_stream_format(oxfw, stream, rate, pcm_channels);
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900312 if (err < 0) {
313 dev_err(&oxfw->unit->device,
314 "fail to set stream format: %d\n", err);
315 goto end;
316 }
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900317
318 /* Start opposite stream if needed. */
319 if (opposite && !amdtp_stream_running(opposite) &&
320 (opposite_substreams > 0)) {
321 err = start_stream(oxfw, opposite, rate, 0);
322 if (err < 0) {
323 dev_err(&oxfw->unit->device,
324 "fail to restart stream: %d\n", err);
325 goto end;
326 }
327 }
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900328 }
329
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900330 /* Start requested stream. */
331 if (!amdtp_stream_running(stream)) {
332 err = start_stream(oxfw, stream, rate, pcm_channels);
333 if (err < 0)
334 dev_err(&oxfw->unit->device,
335 "fail to start stream: %d\n", err);
336 }
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900337end:
338 return err;
339}
340
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900341void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw,
342 struct amdtp_stream *stream)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900343{
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900344 if (((stream == &oxfw->tx_stream) && (oxfw->capture_substreams > 0)) ||
345 ((stream == &oxfw->rx_stream) && (oxfw->playback_substreams > 0)))
346 return;
347
348 stop_stream(oxfw, stream);
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900349}
350
Takashi Sakamotod23c2cc2015-02-21 23:54:59 +0900351/*
352 * This function should be called before starting the stream or after stopping
353 * the streams.
354 */
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900355void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw,
356 struct amdtp_stream *stream)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900357{
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900358 struct cmp_connection *conn;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900359
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900360 if (stream == &oxfw->tx_stream)
361 conn = &oxfw->out_conn;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900362 else
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900363 conn = &oxfw->in_conn;
364
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900365 amdtp_stream_destroy(stream);
366 cmp_connection_destroy(conn);
367}
368
369void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw,
370 struct amdtp_stream *stream)
371{
372 struct cmp_connection *conn;
373
374 if (stream == &oxfw->tx_stream)
375 conn = &oxfw->out_conn;
376 else
377 conn = &oxfw->in_conn;
378
379 if (cmp_connection_update(conn) < 0)
380 stop_stream(oxfw, stream);
381 else
382 amdtp_stream_update(stream);
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900383}
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900384
Takashi Sakamoto3c961012014-12-09 00:10:43 +0900385int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
386 enum avc_general_plug_dir dir,
387 struct snd_oxfw_stream_formation *formation)
388{
389 u8 *format;
390 unsigned int len;
391 int err;
392
393 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
394 format = kmalloc(len, GFP_KERNEL);
395 if (format == NULL)
396 return -ENOMEM;
397
398 err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
399 if (err < 0)
400 goto end;
401 if (len < 3) {
402 err = -EIO;
403 goto end;
404 }
405
406 err = snd_oxfw_stream_parse_format(format, formation);
407end:
408 kfree(format);
409 return err;
410}
411
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900412/*
413 * See Table 6.16 - AM824 Stream Format
414 * Figure 6.19 - format_information field for AM824 Compound
415 * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
416 * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
417 */
418int snd_oxfw_stream_parse_format(u8 *format,
419 struct snd_oxfw_stream_formation *formation)
420{
421 unsigned int i, e, channels, type;
422
423 memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
424
425 /*
426 * this module can support a hierarchy combination that:
427 * Root: Audio and Music (0x90)
428 * Level 1: AM824 Compound (0x40)
429 */
430 if ((format[0] != 0x90) || (format[1] != 0x40))
431 return -ENOSYS;
432
433 /* check the sampling rate */
434 for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
435 if (format[2] == avc_stream_rate_table[i])
436 break;
437 }
438 if (i == ARRAY_SIZE(avc_stream_rate_table))
439 return -ENOSYS;
440
441 formation->rate = oxfw_rate_table[i];
442
443 for (e = 0; e < format[4]; e++) {
444 channels = format[5 + e * 2];
445 type = format[6 + e * 2];
446
447 switch (type) {
448 /* IEC 60958 Conformant, currently handled as MBLA */
449 case 0x00:
450 /* Multi Bit Linear Audio (Raw) */
451 case 0x06:
452 formation->pcm += channels;
453 break;
454 /* MIDI Conformant */
455 case 0x0d:
456 formation->midi = channels;
457 break;
458 /* IEC 61937-3 to 7 */
459 case 0x01:
460 case 0x02:
461 case 0x03:
462 case 0x04:
463 case 0x05:
464 /* Multi Bit Linear Audio */
465 case 0x07: /* DVD-Audio */
466 case 0x0c: /* High Precision */
467 /* One Bit Audio */
468 case 0x08: /* (Plain) Raw */
469 case 0x09: /* (Plain) SACD */
470 case 0x0a: /* (Encoded) Raw */
471 case 0x0b: /* (Encoded) SACD */
472 /* SMPTE Time-Code conformant */
473 case 0x0e:
474 /* Sample Count */
475 case 0x0f:
476 /* Anciliary Data */
477 case 0x10:
478 /* Synchronization Stream (Stereo Raw audio) */
479 case 0x40:
480 /* Don't care */
481 case 0xff:
482 default:
483 return -ENOSYS; /* not supported */
484 }
485 }
486
Takashi Sakamoto49c7b3f2015-09-19 11:22:01 +0900487 if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM ||
488 formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900489 return -ENOSYS;
490
491 return 0;
492}
493
494static int
495assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
496 unsigned int pid, u8 *buf, unsigned int *len,
497 u8 **formats)
498{
499 struct snd_oxfw_stream_formation formation;
500 unsigned int i, eid;
501 int err;
502
503 /* get format at current sampling rate */
504 err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
505 if (err < 0) {
506 dev_err(&oxfw->unit->device,
507 "fail to get current stream format for isoc %s plug %d:%d\n",
508 (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
509 pid, err);
510 goto end;
511 }
512
513 /* parse and set stream format */
514 eid = 0;
515 err = snd_oxfw_stream_parse_format(buf, &formation);
516 if (err < 0)
517 goto end;
518
Takashi Sakamotocd3b7112018-10-03 08:21:54 +0900519 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
520 GFP_KERNEL);
521 if (!formats[eid]) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900522 err = -ENOMEM;
523 goto end;
524 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900525
526 /* apply the format for each available sampling rate */
527 for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
528 if (formation.rate == oxfw_rate_table[i])
529 continue;
530
531 err = avc_general_inquiry_sig_fmt(oxfw->unit,
532 oxfw_rate_table[i],
533 dir, pid);
534 if (err < 0)
535 continue;
536
537 eid++;
Takashi Sakamotocd3b7112018-10-03 08:21:54 +0900538 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
539 GFP_KERNEL);
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900540 if (formats[eid] == NULL) {
541 err = -ENOMEM;
542 goto end;
543 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900544 formats[eid][2] = avc_stream_rate_table[i];
545 }
546
547 err = 0;
548 oxfw->assumed = true;
549end:
550 return err;
551}
552
553static int fill_stream_formats(struct snd_oxfw *oxfw,
554 enum avc_general_plug_dir dir,
555 unsigned short pid)
556{
557 u8 *buf, **formats;
558 unsigned int len, eid = 0;
559 struct snd_oxfw_stream_formation dummy;
560 int err;
561
562 buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
563 if (buf == NULL)
564 return -ENOMEM;
565
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900566 if (dir == AVC_GENERAL_PLUG_DIR_OUT)
567 formats = oxfw->tx_stream_formats;
568 else
569 formats = oxfw->rx_stream_formats;
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900570
571 /* get first entry */
572 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
573 err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
574 if (err == -ENOSYS) {
575 /* LIST subfunction is not implemented */
576 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
577 err = assume_stream_formats(oxfw, dir, pid, buf, &len,
578 formats);
579 goto end;
580 } else if (err < 0) {
581 dev_err(&oxfw->unit->device,
582 "fail to get stream format %d for isoc %s plug %d:%d\n",
583 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
584 pid, err);
585 goto end;
586 }
587
588 /* LIST subfunction is implemented */
589 while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
590 /* The format is too short. */
591 if (len < 3) {
592 err = -EIO;
593 break;
594 }
595
596 /* parse and set stream format */
597 err = snd_oxfw_stream_parse_format(buf, &dummy);
598 if (err < 0)
599 break;
600
Takashi Sakamotocd3b7112018-10-03 08:21:54 +0900601 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
602 GFP_KERNEL);
603 if (!formats[eid]) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900604 err = -ENOMEM;
605 break;
606 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900607
608 /* get next entry */
609 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
610 err = avc_stream_get_format_list(oxfw->unit, dir, 0,
611 buf, &len, ++eid);
612 /* No entries remained. */
613 if (err == -EINVAL) {
614 err = 0;
615 break;
616 } else if (err < 0) {
617 dev_err(&oxfw->unit->device,
618 "fail to get stream format %d for isoc %s plug %d:%d\n",
619 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
620 "out",
621 pid, err);
622 break;
623 }
624 }
625end:
626 kfree(buf);
627 return err;
628}
629
630int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
631{
632 u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
Takashi Sakamoto32056042015-10-18 17:09:38 +0900633 struct snd_oxfw_stream_formation formation;
634 u8 *format;
635 unsigned int i;
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900636 int err;
637
638 /* the number of plugs for isoc in/out, ext in/out */
639 err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
640 if (err < 0) {
641 dev_err(&oxfw->unit->device,
642 "fail to get info for isoc/external in/out plugs: %d\n",
643 err);
644 goto end;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900645 } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900646 err = -ENOSYS;
647 goto end;
648 }
649
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900650 /* use oPCR[0] if exists */
651 if (plugs[1] > 0) {
652 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
653 if (err < 0)
654 goto end;
Takashi Sakamoto32056042015-10-18 17:09:38 +0900655
656 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
657 format = oxfw->tx_stream_formats[i];
658 if (format == NULL)
659 continue;
660 err = snd_oxfw_stream_parse_format(format, &formation);
661 if (err < 0)
662 continue;
663
664 /* Add one MIDI port. */
665 if (formation.midi > 0)
666 oxfw->midi_input_ports = 1;
667 }
668
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900669 oxfw->has_output = true;
670 }
671
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900672 /* use iPCR[0] if exists */
Takashi Sakamoto32056042015-10-18 17:09:38 +0900673 if (plugs[0] > 0) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900674 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
Takashi Sakamoto32056042015-10-18 17:09:38 +0900675 if (err < 0)
676 goto end;
677
678 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
679 format = oxfw->rx_stream_formats[i];
680 if (format == NULL)
681 continue;
682 err = snd_oxfw_stream_parse_format(format, &formation);
683 if (err < 0)
684 continue;
685
686 /* Add one MIDI port. */
687 if (formation.midi > 0)
688 oxfw->midi_output_ports = 1;
689 }
690 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900691end:
692 return err;
693}
Takashi Sakamoto8985f4a2014-12-09 00:10:49 +0900694
695void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
696{
697 oxfw->dev_lock_changed = true;
698 wake_up(&oxfw->hwdep_wait);
699}
700
701int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
702{
703 int err;
704
705 spin_lock_irq(&oxfw->lock);
706
707 /* user land lock this */
708 if (oxfw->dev_lock_count < 0) {
709 err = -EBUSY;
710 goto end;
711 }
712
713 /* this is the first time */
714 if (oxfw->dev_lock_count++ == 0)
715 snd_oxfw_stream_lock_changed(oxfw);
716 err = 0;
717end:
718 spin_unlock_irq(&oxfw->lock);
719 return err;
720}
721
722void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
723{
724 spin_lock_irq(&oxfw->lock);
725
726 if (WARN_ON(oxfw->dev_lock_count <= 0))
727 goto end;
728 if (--oxfw->dev_lock_count == 0)
729 snd_oxfw_stream_lock_changed(oxfw);
730end:
731 spin_unlock_irq(&oxfw->lock);
732}