forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/firewire/motu/motu-stream.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * motu-stream.c - a part of driver for MOTU FireWire series
34 *
45 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include "motu.h"
....@@ -26,48 +25,47 @@
2625 #define RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000040
2726 #define TX_PACKET_TRANSMISSION_SPEED_MASK 0x0000000f
2827
29
-static int start_both_streams(struct snd_motu *motu, unsigned int rate)
28
+static int keep_resources(struct snd_motu *motu, unsigned int rate,
29
+ struct amdtp_stream *stream)
3030 {
31
+ struct fw_iso_resources *resources;
32
+ struct snd_motu_packet_format *packet_format;
3133 unsigned int midi_ports = 0;
34
+ int err;
35
+
36
+ if (stream == &motu->rx_stream) {
37
+ resources = &motu->rx_resources;
38
+ packet_format = &motu->rx_packet_formats;
39
+
40
+ if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
41
+ (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q))
42
+ midi_ports = 1;
43
+ } else {
44
+ resources = &motu->tx_resources;
45
+ packet_format = &motu->tx_packet_formats;
46
+
47
+ if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
48
+ (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q))
49
+ midi_ports = 1;
50
+ }
51
+
52
+ err = amdtp_motu_set_parameters(stream, rate, midi_ports,
53
+ packet_format);
54
+ if (err < 0)
55
+ return err;
56
+
57
+ return fw_iso_resources_allocate(resources,
58
+ amdtp_stream_get_max_payload(stream),
59
+ fw_parent_device(motu->unit)->max_speed);
60
+}
61
+
62
+static int begin_session(struct snd_motu *motu)
63
+{
3264 __be32 reg;
3365 u32 data;
3466 int err;
3567
36
- if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
37
- (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q))
38
- midi_ports = 1;
39
-
40
- /* Set packet formation to our packet streaming engine. */
41
- err = amdtp_motu_set_parameters(&motu->rx_stream, rate, midi_ports,
42
- &motu->rx_packet_formats);
43
- if (err < 0)
44
- return err;
45
-
46
- if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
47
- (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q))
48
- midi_ports = 1;
49
- else
50
- midi_ports = 0;
51
-
52
- err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports,
53
- &motu->tx_packet_formats);
54
- if (err < 0)
55
- return err;
56
-
57
- /* Get isochronous resources on the bus. */
58
- err = fw_iso_resources_allocate(&motu->rx_resources,
59
- amdtp_stream_get_max_payload(&motu->rx_stream),
60
- fw_parent_device(motu->unit)->max_speed);
61
- if (err < 0)
62
- return err;
63
-
64
- err = fw_iso_resources_allocate(&motu->tx_resources,
65
- amdtp_stream_get_max_payload(&motu->tx_stream),
66
- fw_parent_device(motu->unit)->max_speed);
67
- if (err < 0)
68
- return err;
69
-
70
- /* Configure the unit to start isochronous communication. */
68
+ // Configure the unit to start isochronous communication.
7169 err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
7270 sizeof(reg));
7371 if (err < 0)
....@@ -84,13 +82,13 @@
8482 sizeof(reg));
8583 }
8684
87
-static void stop_both_streams(struct snd_motu *motu)
85
+static void finish_session(struct snd_motu *motu)
8886 {
8987 __be32 reg;
9088 u32 data;
9189 int err;
9290
93
- err = motu->spec->protocol->switch_fetching_mode(motu, false);
91
+ err = snd_motu_protocol_switch_fetching_mode(motu, false);
9492 if (err < 0)
9593 return;
9694
....@@ -106,53 +104,13 @@
106104 reg = cpu_to_be32(data);
107105 snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg,
108106 sizeof(reg));
109
-
110
- fw_iso_resources_free(&motu->tx_resources);
111
- fw_iso_resources_free(&motu->rx_resources);
112
-}
113
-
114
-static int start_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream)
115
-{
116
- struct fw_iso_resources *resources;
117
- int err;
118
-
119
- if (stream == &motu->rx_stream)
120
- resources = &motu->rx_resources;
121
- else
122
- resources = &motu->tx_resources;
123
-
124
- err = amdtp_stream_start(stream, resources->channel,
125
- fw_parent_device(motu->unit)->max_speed);
126
- if (err < 0)
127
- return err;
128
-
129
- if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
130
- amdtp_stream_stop(stream);
131
- fw_iso_resources_free(resources);
132
- return -ETIMEDOUT;
133
- }
134
-
135
- return 0;
136
-}
137
-
138
-static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream)
139
-{
140
- struct fw_iso_resources *resources;
141
-
142
- if (stream == &motu->rx_stream)
143
- resources = &motu->rx_resources;
144
- else
145
- resources = &motu->tx_resources;
146
-
147
- amdtp_stream_stop(stream);
148
- fw_iso_resources_free(resources);
149107 }
150108
151109 int snd_motu_stream_cache_packet_formats(struct snd_motu *motu)
152110 {
153111 int err;
154112
155
- err = motu->spec->protocol->cache_packet_formats(motu);
113
+ err = snd_motu_protocol_cache_packet_formats(motu);
156114 if (err < 0)
157115 return err;
158116
....@@ -175,6 +133,59 @@
175133 return 0;
176134 }
177135
136
+int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
137
+ unsigned int frames_per_period,
138
+ unsigned int frames_per_buffer)
139
+{
140
+ unsigned int curr_rate;
141
+ int err;
142
+
143
+ err = snd_motu_protocol_get_clock_rate(motu, &curr_rate);
144
+ if (err < 0)
145
+ return err;
146
+ if (rate == 0)
147
+ rate = curr_rate;
148
+
149
+ if (motu->substreams_counter == 0 || curr_rate != rate) {
150
+ amdtp_domain_stop(&motu->domain);
151
+ finish_session(motu);
152
+
153
+ fw_iso_resources_free(&motu->tx_resources);
154
+ fw_iso_resources_free(&motu->rx_resources);
155
+
156
+ err = snd_motu_protocol_set_clock_rate(motu, rate);
157
+ if (err < 0) {
158
+ dev_err(&motu->unit->device,
159
+ "fail to set sampling rate: %d\n", err);
160
+ return err;
161
+ }
162
+
163
+ err = snd_motu_stream_cache_packet_formats(motu);
164
+ if (err < 0)
165
+ return err;
166
+
167
+ err = keep_resources(motu, rate, &motu->tx_stream);
168
+ if (err < 0)
169
+ return err;
170
+
171
+ err = keep_resources(motu, rate, &motu->rx_stream);
172
+ if (err < 0) {
173
+ fw_iso_resources_free(&motu->tx_resources);
174
+ return err;
175
+ }
176
+
177
+ err = amdtp_domain_set_events_per_period(&motu->domain,
178
+ frames_per_period, frames_per_buffer);
179
+ if (err < 0) {
180
+ fw_iso_resources_free(&motu->tx_resources);
181
+ fw_iso_resources_free(&motu->rx_resources);
182
+ return err;
183
+ }
184
+ }
185
+
186
+ return 0;
187
+}
188
+
178189 static int ensure_packet_formats(struct snd_motu *motu)
179190 {
180191 __be32 reg;
....@@ -190,9 +201,9 @@
190201 data &= ~(TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS |
191202 RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS|
192203 TX_PACKET_TRANSMISSION_SPEED_MASK);
193
- if (motu->tx_packet_formats.differed_part_pcm_chunks[0] == 0)
204
+ if (motu->spec->tx_fixed_pcm_chunks[0] == motu->tx_packet_formats.pcm_chunks[0])
194205 data |= TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS;
195
- if (motu->rx_packet_formats.differed_part_pcm_chunks[0] == 0)
206
+ if (motu->spec->rx_fixed_pcm_chunks[0] == motu->rx_packet_formats.pcm_chunks[0])
196207 data |= RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS;
197208 data |= fw_parent_device(motu->unit)->max_speed;
198209
....@@ -201,69 +212,67 @@
201212 sizeof(reg));
202213 }
203214
204
-int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate)
215
+int snd_motu_stream_start_duplex(struct snd_motu *motu)
205216 {
206
- const struct snd_motu_protocol *protocol = motu->spec->protocol;
207
- unsigned int curr_rate;
217
+ unsigned int generation = motu->rx_resources.generation;
208218 int err = 0;
209219
210
- if (motu->capture_substreams == 0 && motu->playback_substreams == 0)
220
+ if (motu->substreams_counter == 0)
211221 return 0;
212222
213
- /* Some packet queueing errors. */
214223 if (amdtp_streaming_error(&motu->rx_stream) ||
215224 amdtp_streaming_error(&motu->tx_stream)) {
216
- amdtp_stream_stop(&motu->rx_stream);
217
- amdtp_stream_stop(&motu->tx_stream);
218
- stop_both_streams(motu);
225
+ amdtp_domain_stop(&motu->domain);
226
+ finish_session(motu);
219227 }
220228
221
- err = snd_motu_stream_cache_packet_formats(motu);
222
- if (err < 0)
223
- return err;
229
+ if (generation != fw_parent_device(motu->unit)->card->generation) {
230
+ err = fw_iso_resources_update(&motu->rx_resources);
231
+ if (err < 0)
232
+ return err;
224233
225
- /* Stop stream if rate is different. */
226
- err = protocol->get_clock_rate(motu, &curr_rate);
227
- if (err < 0) {
228
- dev_err(&motu->unit->device,
229
- "fail to get sampling rate: %d\n", err);
230
- return err;
231
- }
232
- if (rate == 0)
233
- rate = curr_rate;
234
- if (rate != curr_rate) {
235
- amdtp_stream_stop(&motu->rx_stream);
236
- amdtp_stream_stop(&motu->tx_stream);
237
- stop_both_streams(motu);
234
+ err = fw_iso_resources_update(&motu->tx_resources);
235
+ if (err < 0)
236
+ return err;
238237 }
239238
240239 if (!amdtp_stream_running(&motu->rx_stream)) {
241
- err = protocol->set_clock_rate(motu, rate);
242
- if (err < 0) {
243
- dev_err(&motu->unit->device,
244
- "fail to set sampling rate: %d\n", err);
245
- return err;
246
- }
240
+ int spd = fw_parent_device(motu->unit)->max_speed;
247241
248242 err = ensure_packet_formats(motu);
249243 if (err < 0)
250244 return err;
251245
252
- err = start_both_streams(motu, rate);
246
+ err = begin_session(motu);
253247 if (err < 0) {
254248 dev_err(&motu->unit->device,
255249 "fail to start isochronous comm: %d\n", err);
256250 goto stop_streams;
257251 }
258252
259
- err = start_isoc_ctx(motu, &motu->rx_stream);
260
- if (err < 0) {
261
- dev_err(&motu->unit->device,
262
- "fail to start IT context: %d\n", err);
253
+ err = amdtp_domain_add_stream(&motu->domain, &motu->tx_stream,
254
+ motu->tx_resources.channel, spd);
255
+ if (err < 0)
256
+ goto stop_streams;
257
+
258
+ err = amdtp_domain_add_stream(&motu->domain, &motu->rx_stream,
259
+ motu->rx_resources.channel, spd);
260
+ if (err < 0)
261
+ goto stop_streams;
262
+
263
+ err = amdtp_domain_start(&motu->domain, 0);
264
+ if (err < 0)
265
+ goto stop_streams;
266
+
267
+ if (!amdtp_stream_wait_callback(&motu->tx_stream,
268
+ CALLBACK_TIMEOUT) ||
269
+ !amdtp_stream_wait_callback(&motu->rx_stream,
270
+ CALLBACK_TIMEOUT)) {
271
+ err = -ETIMEDOUT;
263272 goto stop_streams;
264273 }
265274
266
- err = protocol->switch_fetching_mode(motu, true);
275
+ err = snd_motu_protocol_switch_fetching_mode(motu, true);
267276 if (err < 0) {
268277 dev_err(&motu->unit->device,
269278 "fail to enable frame fetching: %d\n", err);
....@@ -271,109 +280,93 @@
271280 }
272281 }
273282
274
- if (!amdtp_stream_running(&motu->tx_stream) &&
275
- motu->capture_substreams > 0) {
276
- err = start_isoc_ctx(motu, &motu->tx_stream);
277
- if (err < 0) {
278
- dev_err(&motu->unit->device,
279
- "fail to start IR context: %d", err);
280
- amdtp_stream_stop(&motu->rx_stream);
281
- goto stop_streams;
282
- }
283
- }
284
-
285283 return 0;
286284
287285 stop_streams:
288
- stop_both_streams(motu);
286
+ amdtp_domain_stop(&motu->domain);
287
+ finish_session(motu);
289288 return err;
290289 }
291290
292291 void snd_motu_stream_stop_duplex(struct snd_motu *motu)
293292 {
294
- if (motu->capture_substreams == 0) {
295
- if (amdtp_stream_running(&motu->tx_stream))
296
- stop_isoc_ctx(motu, &motu->tx_stream);
293
+ if (motu->substreams_counter == 0) {
294
+ amdtp_domain_stop(&motu->domain);
295
+ finish_session(motu);
297296
298
- if (motu->playback_substreams == 0) {
299
- if (amdtp_stream_running(&motu->rx_stream))
300
- stop_isoc_ctx(motu, &motu->rx_stream);
301
- stop_both_streams(motu);
302
- }
297
+ fw_iso_resources_free(&motu->tx_resources);
298
+ fw_iso_resources_free(&motu->rx_resources);
303299 }
304300 }
305301
306
-static int init_stream(struct snd_motu *motu, enum amdtp_stream_direction dir)
302
+static int init_stream(struct snd_motu *motu, struct amdtp_stream *s)
307303 {
308
- int err;
309
- struct amdtp_stream *stream;
310304 struct fw_iso_resources *resources;
305
+ enum amdtp_stream_direction dir;
306
+ int err;
311307
312
- if (dir == AMDTP_IN_STREAM) {
313
- stream = &motu->tx_stream;
308
+ if (s == &motu->tx_stream) {
314309 resources = &motu->tx_resources;
310
+ dir = AMDTP_IN_STREAM;
315311 } else {
316
- stream = &motu->rx_stream;
317312 resources = &motu->rx_resources;
313
+ dir = AMDTP_OUT_STREAM;
318314 }
319315
320316 err = fw_iso_resources_init(resources, motu->unit);
321317 if (err < 0)
322318 return err;
323319
324
- err = amdtp_motu_init(stream, motu->unit, dir, motu->spec->protocol);
325
- if (err < 0) {
326
- amdtp_stream_destroy(stream);
320
+ err = amdtp_motu_init(s, motu->unit, dir, motu->spec);
321
+ if (err < 0)
327322 fw_iso_resources_destroy(resources);
328
- }
329323
330324 return err;
331325 }
332326
333
-static void destroy_stream(struct snd_motu *motu,
334
- enum amdtp_stream_direction dir)
327
+static void destroy_stream(struct snd_motu *motu, struct amdtp_stream *s)
335328 {
336
- struct amdtp_stream *stream;
337
- struct fw_iso_resources *resources;
329
+ amdtp_stream_destroy(s);
338330
339
- if (dir == AMDTP_IN_STREAM) {
340
- stream = &motu->tx_stream;
341
- resources = &motu->tx_resources;
342
- } else {
343
- stream = &motu->rx_stream;
344
- resources = &motu->rx_resources;
345
- }
346
-
347
- amdtp_stream_destroy(stream);
348
- fw_iso_resources_destroy(resources);
331
+ if (s == &motu->tx_stream)
332
+ fw_iso_resources_destroy(&motu->tx_resources);
333
+ else
334
+ fw_iso_resources_destroy(&motu->rx_resources);
349335 }
350336
351337 int snd_motu_stream_init_duplex(struct snd_motu *motu)
352338 {
353339 int err;
354340
355
- err = init_stream(motu, AMDTP_IN_STREAM);
341
+ err = init_stream(motu, &motu->tx_stream);
356342 if (err < 0)
357343 return err;
358344
359
- err = init_stream(motu, AMDTP_OUT_STREAM);
360
- if (err < 0)
361
- destroy_stream(motu, AMDTP_IN_STREAM);
345
+ err = init_stream(motu, &motu->rx_stream);
346
+ if (err < 0) {
347
+ destroy_stream(motu, &motu->tx_stream);
348
+ return err;
349
+ }
350
+
351
+ err = amdtp_domain_init(&motu->domain);
352
+ if (err < 0) {
353
+ destroy_stream(motu, &motu->tx_stream);
354
+ destroy_stream(motu, &motu->rx_stream);
355
+ }
362356
363357 return err;
364358 }
365359
366
-/*
367
- * This function should be called before starting streams or after stopping
368
- * streams.
369
- */
360
+// This function should be called before starting streams or after stopping
361
+// streams.
370362 void snd_motu_stream_destroy_duplex(struct snd_motu *motu)
371363 {
372
- destroy_stream(motu, AMDTP_IN_STREAM);
373
- destroy_stream(motu, AMDTP_OUT_STREAM);
364
+ amdtp_domain_destroy(&motu->domain);
374365
375
- motu->playback_substreams = 0;
376
- motu->capture_substreams = 0;
366
+ destroy_stream(motu, &motu->rx_stream);
367
+ destroy_stream(motu, &motu->tx_stream);
368
+
369
+ motu->substreams_counter = 0;
377370 }
378371
379372 static void motu_lock_changed(struct snd_motu *motu)