blob: 7d2e88c5b73d3fb7a026dab610b579359ca7b82a [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 Sakamoto521b2e12019-06-12 17:44:15 +0900103static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900104{
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900105 struct cmp_connection *conn;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900106 int err;
107
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900108 if (stream == &oxfw->rx_stream)
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900109 conn = &oxfw->in_conn;
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900110 else
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900111 conn = &oxfw->out_conn;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900112
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900113 err = cmp_connection_establish(conn);
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900114 if (err < 0)
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900115 return err;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900116
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900117 err = amdtp_domain_add_stream(&oxfw->domain, stream,
118 conn->resources.channel, conn->speed);
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900119 if (err < 0) {
120 cmp_connection_break(conn);
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900121 return err;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900122 }
123
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900124 return 0;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900125}
126
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900127static int check_connection_used_by_others(struct snd_oxfw *oxfw,
128 struct amdtp_stream *stream)
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900129{
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900130 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
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900151static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900152{
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)
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900170 return err;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900171
Takashi Sakamoto59558152015-09-19 11:21:55 +0900172 err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900173 if (err < 0) {
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900174 cmp_connection_destroy(conn);
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900175 return err;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900176 }
177
Takashi Sakamotoa2064712015-05-22 23:00:50 +0900178 /*
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 */
Takashi Sakamoto13f3a462015-09-20 21:18:55 +0900184 if (stream == &oxfw->tx_stream) {
Takashi Sakamoto62f00e42016-05-09 23:15:56 +0900185 oxfw->tx_stream.flags |= CIP_JUMBO_PAYLOAD;
Takashi Sakamoto13f3a462015-09-20 21:18:55 +0900186 if (oxfw->wrong_dbs)
187 oxfw->tx_stream.flags |= CIP_WRONG_DBS;
188 }
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900189
190 return 0;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900191}
192
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900193static 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;
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900198 struct cmp_connection *conn;
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900199 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;
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900205 conn = &oxfw->in_conn;
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900206 } else {
207 dir = AVC_GENERAL_PLUG_DIR_OUT;
208 formats = oxfw->tx_stream_formats;
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900209 conn = &oxfw->out_conn;
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900210 }
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
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900237 err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900238 formation.midi * 8, false);
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900239 if (err < 0)
240 return err;
241
242 return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900243}
244
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900245int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
246 struct amdtp_stream *stream,
Takashi Sakamoto1d6a7222019-10-07 20:05:19 +0900247 unsigned int rate, unsigned int pcm_channels,
248 unsigned int frames_per_period)
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900249{
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900250 struct snd_oxfw_stream_formation formation;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900251 enum avc_general_plug_dir dir;
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900252 int err;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900253
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900254 // Considering JACK/FFADO streaming:
255 // TODO: This can be removed hwdep functionality becomes popular.
256 err = check_connection_used_by_others(oxfw, &oxfw->rx_stream);
257 if (err < 0)
258 return err;
259 if (oxfw->has_output) {
260 err = check_connection_used_by_others(oxfw, &oxfw->tx_stream);
261 if (err < 0)
262 return err;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900263 }
264
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900265 if (stream == &oxfw->tx_stream)
266 dir = AVC_GENERAL_PLUG_DIR_OUT;
267 else
268 dir = AVC_GENERAL_PLUG_DIR_IN;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900269
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900270 err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900271 if (err < 0)
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900272 return err;
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900273 if (rate == 0) {
Takashi Sakamoto05588d32014-12-09 00:10:48 +0900274 rate = formation.rate;
Takashi Sakamoto05588d32014-12-09 00:10:48 +0900275 pcm_channels = formation.pcm;
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900276 }
277 if (formation.rate != rate || formation.pcm != pcm_channels) {
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900278 amdtp_domain_stop(&oxfw->domain);
279
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900280 cmp_connection_break(&oxfw->in_conn);
Takashi Sakamoto3f2ce832019-06-18 22:26:22 +0900281 cmp_connection_release(&oxfw->in_conn);
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900282
283 if (oxfw->has_output) {
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900284 cmp_connection_break(&oxfw->out_conn);
Takashi Sakamoto3f2ce832019-06-18 22:26:22 +0900285 cmp_connection_release(&oxfw->out_conn);
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900286 }
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900287 }
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900288
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900289 if (oxfw->substreams_count == 0 ||
290 formation.rate != rate || formation.pcm != pcm_channels) {
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900291 err = set_stream_format(oxfw, stream, rate, pcm_channels);
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900292 if (err < 0) {
293 dev_err(&oxfw->unit->device,
294 "fail to set stream format: %d\n", err);
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900295 return err;
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900296 }
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900297
298 err = keep_resources(oxfw, &oxfw->rx_stream);
299 if (err < 0)
300 return err;
301
302 if (oxfw->has_output) {
303 err = keep_resources(oxfw, &oxfw->tx_stream);
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900304 if (err < 0) {
305 cmp_connection_release(&oxfw->in_conn);
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900306 return err;
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900307 }
Takashi Sakamoto0356ce32019-06-12 17:44:22 +0900308 }
Takashi Sakamoto1d6a7222019-10-07 20:05:19 +0900309
310 err = amdtp_domain_set_events_per_period(&oxfw->domain,
311 frames_per_period);
312 if (err < 0) {
313 cmp_connection_release(&oxfw->in_conn);
314 if (oxfw->has_output)
315 cmp_connection_release(&oxfw->out_conn);
316 return err;
317 }
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900318 }
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900319
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900320 return 0;
321}
322
323int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
324{
325 int err;
326
327 if (oxfw->substreams_count == 0)
328 return -EIO;
329
330 if (amdtp_streaming_error(&oxfw->rx_stream) ||
331 amdtp_streaming_error(&oxfw->tx_stream)) {
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900332 amdtp_domain_stop(&oxfw->domain);
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900333
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900334 cmp_connection_break(&oxfw->in_conn);
335 if (oxfw->has_output)
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900336 cmp_connection_break(&oxfw->out_conn);
Takashi Sakamoto4f380d02019-06-12 17:44:21 +0900337 }
338
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900339 if (!amdtp_stream_running(&oxfw->rx_stream)) {
340 err = start_stream(oxfw, &oxfw->rx_stream);
341 if (err < 0) {
342 dev_err(&oxfw->unit->device,
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900343 "fail to prepare rx stream: %d\n", err);
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900344 goto error;
345 }
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900346
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900347 if (oxfw->has_output &&
348 !amdtp_stream_running(&oxfw->tx_stream)) {
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900349 err = start_stream(oxfw, &oxfw->tx_stream);
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900350 if (err < 0) {
351 dev_err(&oxfw->unit->device,
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900352 "fail to prepare tx stream: %d\n", err);
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900353 goto error;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900354 }
355 }
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900356
357 err = amdtp_domain_start(&oxfw->domain);
358 if (err < 0)
359 goto error;
360
361 // Wait first packet.
362 if (!amdtp_stream_wait_callback(&oxfw->rx_stream,
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900363 CALLBACK_TIMEOUT)) {
364 err = -ETIMEDOUT;
365 goto error;
366 }
367
Takashi Sakamoto4c098da2019-08-26 22:54:15 +0900368 if (oxfw->has_output) {
369 if (!amdtp_stream_wait_callback(&oxfw->tx_stream,
370 CALLBACK_TIMEOUT)) {
371 err = -ETIMEDOUT;
372 goto error;
373 }
374 }
Takashi Sakamotof3699e22014-12-09 00:10:44 +0900375 }
376
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900377 return 0;
378error:
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900379 amdtp_domain_stop(&oxfw->domain);
380
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900381 cmp_connection_break(&oxfw->in_conn);
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900382 if (oxfw->has_output)
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900383 cmp_connection_break(&oxfw->out_conn);
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900384
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900385 return err;
386}
387
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900388void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900389{
Takashi Sakamoto4a0a0472019-06-12 17:44:20 +0900390 if (oxfw->substreams_count == 0) {
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900391 amdtp_domain_stop(&oxfw->domain);
392
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900393 cmp_connection_break(&oxfw->in_conn);
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900394 cmp_connection_release(&oxfw->in_conn);
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900395
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900396 if (oxfw->has_output) {
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900397 cmp_connection_break(&oxfw->out_conn);
Takashi Sakamoto7bc93822019-06-15 18:11:01 +0900398 cmp_connection_release(&oxfw->out_conn);
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900399 }
Takashi Sakamoto20358d42019-06-12 17:44:16 +0900400 }
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900401}
402
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900403static void destroy_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900404{
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900405 struct cmp_connection *conn;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900406
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900407 if (stream == &oxfw->tx_stream)
408 conn = &oxfw->out_conn;
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900409 else
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900410 conn = &oxfw->in_conn;
411
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900412 amdtp_stream_destroy(stream);
413 cmp_connection_destroy(conn);
414}
415
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900416int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw)
417{
418 int err;
419
420 err = init_stream(oxfw, &oxfw->rx_stream);
421 if (err < 0)
422 return err;
423
424 if (oxfw->has_output) {
425 err = init_stream(oxfw, &oxfw->tx_stream);
426 if (err < 0) {
427 destroy_stream(oxfw, &oxfw->rx_stream);
428 return err;
429 }
430 }
431
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900432 err = amdtp_domain_init(&oxfw->domain);
433 if (err < 0) {
434 destroy_stream(oxfw, &oxfw->rx_stream);
435 if (oxfw->has_output)
436 destroy_stream(oxfw, &oxfw->tx_stream);
437 }
438
439 return err;
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900440}
441
442// This function should be called before starting the stream or after stopping
443// the streams.
444void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw)
445{
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900446 amdtp_domain_destroy(&oxfw->domain);
447
Takashi Sakamoto779f0db2019-06-12 17:44:19 +0900448 destroy_stream(oxfw, &oxfw->rx_stream);
449
450 if (oxfw->has_output)
451 destroy_stream(oxfw, &oxfw->tx_stream);
452}
453
454void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw)
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900455{
Takashi Sakamotoac5d7782019-08-04 15:21:32 +0900456 amdtp_domain_stop(&oxfw->domain);
457
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900458 cmp_connection_break(&oxfw->in_conn);
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900459
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900460 amdtp_stream_pcm_abort(&oxfw->rx_stream);
461
462 if (oxfw->has_output) {
Takashi Sakamotoe34244d2019-06-12 17:44:18 +0900463 cmp_connection_break(&oxfw->out_conn);
464
465 amdtp_stream_pcm_abort(&oxfw->tx_stream);
466 }
Takashi Sakamotoe2786ca2014-11-29 00:59:27 +0900467}
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900468
Takashi Sakamoto3c961012014-12-09 00:10:43 +0900469int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
470 enum avc_general_plug_dir dir,
471 struct snd_oxfw_stream_formation *formation)
472{
473 u8 *format;
474 unsigned int len;
475 int err;
476
477 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
478 format = kmalloc(len, GFP_KERNEL);
479 if (format == NULL)
480 return -ENOMEM;
481
482 err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
483 if (err < 0)
484 goto end;
485 if (len < 3) {
486 err = -EIO;
487 goto end;
488 }
489
490 err = snd_oxfw_stream_parse_format(format, formation);
491end:
492 kfree(format);
493 return err;
494}
495
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900496/*
497 * See Table 6.16 - AM824 Stream Format
498 * Figure 6.19 - format_information field for AM824 Compound
499 * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
500 * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
501 */
502int snd_oxfw_stream_parse_format(u8 *format,
503 struct snd_oxfw_stream_formation *formation)
504{
505 unsigned int i, e, channels, type;
506
507 memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
508
509 /*
510 * this module can support a hierarchy combination that:
511 * Root: Audio and Music (0x90)
512 * Level 1: AM824 Compound (0x40)
513 */
514 if ((format[0] != 0x90) || (format[1] != 0x40))
515 return -ENOSYS;
516
517 /* check the sampling rate */
518 for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
519 if (format[2] == avc_stream_rate_table[i])
520 break;
521 }
522 if (i == ARRAY_SIZE(avc_stream_rate_table))
523 return -ENOSYS;
524
525 formation->rate = oxfw_rate_table[i];
526
527 for (e = 0; e < format[4]; e++) {
528 channels = format[5 + e * 2];
529 type = format[6 + e * 2];
530
531 switch (type) {
532 /* IEC 60958 Conformant, currently handled as MBLA */
533 case 0x00:
534 /* Multi Bit Linear Audio (Raw) */
535 case 0x06:
536 formation->pcm += channels;
537 break;
538 /* MIDI Conformant */
539 case 0x0d:
540 formation->midi = channels;
541 break;
542 /* IEC 61937-3 to 7 */
543 case 0x01:
544 case 0x02:
545 case 0x03:
546 case 0x04:
547 case 0x05:
548 /* Multi Bit Linear Audio */
549 case 0x07: /* DVD-Audio */
550 case 0x0c: /* High Precision */
551 /* One Bit Audio */
552 case 0x08: /* (Plain) Raw */
553 case 0x09: /* (Plain) SACD */
554 case 0x0a: /* (Encoded) Raw */
555 case 0x0b: /* (Encoded) SACD */
556 /* SMPTE Time-Code conformant */
557 case 0x0e:
558 /* Sample Count */
559 case 0x0f:
560 /* Anciliary Data */
561 case 0x10:
562 /* Synchronization Stream (Stereo Raw audio) */
563 case 0x40:
564 /* Don't care */
565 case 0xff:
566 default:
567 return -ENOSYS; /* not supported */
568 }
569 }
570
Takashi Sakamoto49c7b3f2015-09-19 11:22:01 +0900571 if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM ||
572 formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900573 return -ENOSYS;
574
575 return 0;
576}
577
578static int
579assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
580 unsigned int pid, u8 *buf, unsigned int *len,
581 u8 **formats)
582{
583 struct snd_oxfw_stream_formation formation;
584 unsigned int i, eid;
585 int err;
586
587 /* get format at current sampling rate */
588 err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
589 if (err < 0) {
590 dev_err(&oxfw->unit->device,
591 "fail to get current stream format for isoc %s plug %d:%d\n",
592 (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
593 pid, err);
594 goto end;
595 }
596
597 /* parse and set stream format */
598 eid = 0;
599 err = snd_oxfw_stream_parse_format(buf, &formation);
600 if (err < 0)
601 goto end;
602
Takashi Sakamotocd3b7112018-10-03 08:21:54 +0900603 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
604 GFP_KERNEL);
605 if (!formats[eid]) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900606 err = -ENOMEM;
607 goto end;
608 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900609
610 /* apply the format for each available sampling rate */
611 for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
612 if (formation.rate == oxfw_rate_table[i])
613 continue;
614
615 err = avc_general_inquiry_sig_fmt(oxfw->unit,
616 oxfw_rate_table[i],
617 dir, pid);
618 if (err < 0)
619 continue;
620
621 eid++;
Takashi Sakamotocd3b7112018-10-03 08:21:54 +0900622 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
623 GFP_KERNEL);
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900624 if (formats[eid] == NULL) {
625 err = -ENOMEM;
626 goto end;
627 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900628 formats[eid][2] = avc_stream_rate_table[i];
629 }
630
631 err = 0;
632 oxfw->assumed = true;
633end:
634 return err;
635}
636
637static int fill_stream_formats(struct snd_oxfw *oxfw,
638 enum avc_general_plug_dir dir,
639 unsigned short pid)
640{
641 u8 *buf, **formats;
642 unsigned int len, eid = 0;
643 struct snd_oxfw_stream_formation dummy;
644 int err;
645
646 buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
647 if (buf == NULL)
648 return -ENOMEM;
649
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900650 if (dir == AVC_GENERAL_PLUG_DIR_OUT)
651 formats = oxfw->tx_stream_formats;
652 else
653 formats = oxfw->rx_stream_formats;
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900654
655 /* get first entry */
656 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
657 err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
658 if (err == -ENOSYS) {
659 /* LIST subfunction is not implemented */
660 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
661 err = assume_stream_formats(oxfw, dir, pid, buf, &len,
662 formats);
663 goto end;
664 } else if (err < 0) {
665 dev_err(&oxfw->unit->device,
666 "fail to get stream format %d for isoc %s plug %d:%d\n",
667 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
668 pid, err);
669 goto end;
670 }
671
672 /* LIST subfunction is implemented */
673 while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
674 /* The format is too short. */
675 if (len < 3) {
676 err = -EIO;
677 break;
678 }
679
680 /* parse and set stream format */
681 err = snd_oxfw_stream_parse_format(buf, &dummy);
682 if (err < 0)
683 break;
684
Takashi Sakamotocd3b7112018-10-03 08:21:54 +0900685 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
686 GFP_KERNEL);
687 if (!formats[eid]) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900688 err = -ENOMEM;
689 break;
690 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900691
692 /* get next entry */
693 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
694 err = avc_stream_get_format_list(oxfw->unit, dir, 0,
695 buf, &len, ++eid);
696 /* No entries remained. */
697 if (err == -EINVAL) {
698 err = 0;
699 break;
700 } else if (err < 0) {
701 dev_err(&oxfw->unit->device,
702 "fail to get stream format %d for isoc %s plug %d:%d\n",
703 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
704 "out",
705 pid, err);
706 break;
707 }
708 }
709end:
710 kfree(buf);
711 return err;
712}
713
714int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
715{
716 u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
Takashi Sakamoto32056042015-10-18 17:09:38 +0900717 struct snd_oxfw_stream_formation formation;
718 u8 *format;
719 unsigned int i;
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900720 int err;
721
722 /* the number of plugs for isoc in/out, ext in/out */
723 err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
724 if (err < 0) {
725 dev_err(&oxfw->unit->device,
726 "fail to get info for isoc/external in/out plugs: %d\n",
727 err);
728 goto end;
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900729 } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900730 err = -ENOSYS;
731 goto end;
732 }
733
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900734 /* use oPCR[0] if exists */
735 if (plugs[1] > 0) {
736 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
737 if (err < 0)
738 goto end;
Takashi Sakamoto32056042015-10-18 17:09:38 +0900739
740 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
741 format = oxfw->tx_stream_formats[i];
742 if (format == NULL)
743 continue;
744 err = snd_oxfw_stream_parse_format(format, &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
Takashi Sakamotob0ac0002014-12-09 00:10:46 +0900753 oxfw->has_output = true;
754 }
755
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900756 /* use iPCR[0] if exists */
Takashi Sakamoto32056042015-10-18 17:09:38 +0900757 if (plugs[0] > 0) {
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900758 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
Takashi Sakamoto32056042015-10-18 17:09:38 +0900759 if (err < 0)
760 goto end;
761
762 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
763 format = oxfw->rx_stream_formats[i];
764 if (format == NULL)
765 continue;
766 err = snd_oxfw_stream_parse_format(format, &formation);
767 if (err < 0)
768 continue;
769
770 /* Add one MIDI port. */
771 if (formation.midi > 0)
772 oxfw->midi_output_ports = 1;
773 }
774 }
Takashi Sakamoto5cd1d3f2014-12-09 00:10:42 +0900775end:
776 return err;
777}
Takashi Sakamoto8985f4a2014-12-09 00:10:49 +0900778
779void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
780{
781 oxfw->dev_lock_changed = true;
782 wake_up(&oxfw->hwdep_wait);
783}
784
785int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
786{
787 int err;
788
789 spin_lock_irq(&oxfw->lock);
790
791 /* user land lock this */
792 if (oxfw->dev_lock_count < 0) {
793 err = -EBUSY;
794 goto end;
795 }
796
797 /* this is the first time */
798 if (oxfw->dev_lock_count++ == 0)
799 snd_oxfw_stream_lock_changed(oxfw);
800 err = 0;
801end:
802 spin_unlock_irq(&oxfw->lock);
803 return err;
804}
805
806void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
807{
808 spin_lock_irq(&oxfw->lock);
809
810 if (WARN_ON(oxfw->dev_lock_count <= 0))
811 goto end;
812 if (--oxfw->dev_lock_count == 0)
813 snd_oxfw_stream_lock_changed(oxfw);
814end:
815 spin_unlock_irq(&oxfw->lock);
816}