forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/firewire/fireface/ff-stream.c
....@@ -1,76 +1,33 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ff-stream.c - a part of driver for RME Fireface series
34 *
45 * Copyright (c) 2015-2017 Takashi Sakamoto
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include "ff.h"
109
1110 #define CALLBACK_TIMEOUT_MS 200
1211
13
-static int get_rate_mode(unsigned int rate, unsigned int *mode)
12
+int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
13
+ enum snd_ff_stream_mode *mode)
1414 {
15
- int i;
15
+ static const enum snd_ff_stream_mode modes[] = {
16
+ [CIP_SFC_32000] = SND_FF_STREAM_MODE_LOW,
17
+ [CIP_SFC_44100] = SND_FF_STREAM_MODE_LOW,
18
+ [CIP_SFC_48000] = SND_FF_STREAM_MODE_LOW,
19
+ [CIP_SFC_88200] = SND_FF_STREAM_MODE_MID,
20
+ [CIP_SFC_96000] = SND_FF_STREAM_MODE_MID,
21
+ [CIP_SFC_176400] = SND_FF_STREAM_MODE_HIGH,
22
+ [CIP_SFC_192000] = SND_FF_STREAM_MODE_HIGH,
23
+ };
1624
17
- for (i = 0; i < CIP_SFC_COUNT; i++) {
18
- if (amdtp_rate_table[i] == rate)
19
- break;
20
- }
21
-
22
- if (i == CIP_SFC_COUNT)
25
+ if (sfc >= CIP_SFC_COUNT)
2326 return -EINVAL;
2427
25
- *mode = ((int)i - 1) / 2;
28
+ *mode = modes[sfc];
2629
2730 return 0;
28
-}
29
-
30
-/*
31
- * Fireface 400 manages isochronous channel number in 3 bit field. Therefore,
32
- * we can allocate between 0 and 7 channel.
33
- */
34
-static int keep_resources(struct snd_ff *ff, unsigned int rate)
35
-{
36
- int mode;
37
- int err;
38
-
39
- err = get_rate_mode(rate, &mode);
40
- if (err < 0)
41
- return err;
42
-
43
- /* Keep resources for in-stream. */
44
- err = amdtp_ff_set_parameters(&ff->tx_stream, rate,
45
- ff->spec->pcm_capture_channels[mode]);
46
- if (err < 0)
47
- return err;
48
- ff->tx_resources.channels_mask = 0x00000000000000ffuLL;
49
- err = fw_iso_resources_allocate(&ff->tx_resources,
50
- amdtp_stream_get_max_payload(&ff->tx_stream),
51
- fw_parent_device(ff->unit)->max_speed);
52
- if (err < 0)
53
- return err;
54
-
55
- /* Keep resources for out-stream. */
56
- err = amdtp_ff_set_parameters(&ff->rx_stream, rate,
57
- ff->spec->pcm_playback_channels[mode]);
58
- if (err < 0)
59
- return err;
60
- ff->rx_resources.channels_mask = 0x00000000000000ffuLL;
61
- err = fw_iso_resources_allocate(&ff->rx_resources,
62
- amdtp_stream_get_max_payload(&ff->rx_stream),
63
- fw_parent_device(ff->unit)->max_speed);
64
- if (err < 0)
65
- fw_iso_resources_free(&ff->tx_resources);
66
-
67
- return err;
68
-}
69
-
70
-static void release_resources(struct snd_ff *ff)
71
-{
72
- fw_iso_resources_free(&ff->tx_resources);
73
- fw_iso_resources_free(&ff->rx_resources);
7431 }
7532
7633 static inline void finish_session(struct snd_ff *ff)
....@@ -79,54 +36,61 @@
7936 ff->spec->protocol->switch_fetching_mode(ff, false);
8037 }
8138
82
-static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)
39
+static int init_stream(struct snd_ff *ff, struct amdtp_stream *s)
8340 {
84
- int err;
8541 struct fw_iso_resources *resources;
86
- struct amdtp_stream *stream;
42
+ enum amdtp_stream_direction dir;
43
+ int err;
8744
88
- if (dir == AMDTP_IN_STREAM) {
45
+ if (s == &ff->tx_stream) {
8946 resources = &ff->tx_resources;
90
- stream = &ff->tx_stream;
47
+ dir = AMDTP_IN_STREAM;
9148 } else {
9249 resources = &ff->rx_resources;
93
- stream = &ff->rx_stream;
50
+ dir = AMDTP_OUT_STREAM;
9451 }
9552
9653 err = fw_iso_resources_init(resources, ff->unit);
9754 if (err < 0)
9855 return err;
9956
100
- err = amdtp_ff_init(stream, ff->unit, dir);
57
+ err = amdtp_ff_init(s, ff->unit, dir);
10158 if (err < 0)
10259 fw_iso_resources_destroy(resources);
10360
10461 return err;
10562 }
10663
107
-static void destroy_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)
64
+static void destroy_stream(struct snd_ff *ff, struct amdtp_stream *s)
10865 {
109
- if (dir == AMDTP_IN_STREAM) {
110
- amdtp_stream_destroy(&ff->tx_stream);
66
+ amdtp_stream_destroy(s);
67
+
68
+ if (s == &ff->tx_stream)
11169 fw_iso_resources_destroy(&ff->tx_resources);
112
- } else {
113
- amdtp_stream_destroy(&ff->rx_stream);
70
+ else
11471 fw_iso_resources_destroy(&ff->rx_resources);
115
- }
11672 }
11773
11874 int snd_ff_stream_init_duplex(struct snd_ff *ff)
11975 {
12076 int err;
12177
122
- err = init_stream(ff, AMDTP_OUT_STREAM);
78
+ err = init_stream(ff, &ff->rx_stream);
12379 if (err < 0)
124
- goto end;
80
+ return err;
12581
126
- err = init_stream(ff, AMDTP_IN_STREAM);
127
- if (err < 0)
128
- destroy_stream(ff, AMDTP_OUT_STREAM);
129
-end:
82
+ err = init_stream(ff, &ff->tx_stream);
83
+ if (err < 0) {
84
+ destroy_stream(ff, &ff->rx_stream);
85
+ return err;
86
+ }
87
+
88
+ err = amdtp_domain_init(&ff->domain);
89
+ if (err < 0) {
90
+ destroy_stream(ff, &ff->rx_stream);
91
+ destroy_stream(ff, &ff->tx_stream);
92
+ }
93
+
13094 return err;
13195 }
13296
....@@ -136,31 +100,82 @@
136100 */
137101 void snd_ff_stream_destroy_duplex(struct snd_ff *ff)
138102 {
139
- destroy_stream(ff, AMDTP_IN_STREAM);
140
- destroy_stream(ff, AMDTP_OUT_STREAM);
103
+ amdtp_domain_destroy(&ff->domain);
104
+
105
+ destroy_stream(ff, &ff->rx_stream);
106
+ destroy_stream(ff, &ff->tx_stream);
141107 }
142108
143
-int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
109
+int snd_ff_stream_reserve_duplex(struct snd_ff *ff, unsigned int rate,
110
+ unsigned int frames_per_period,
111
+ unsigned int frames_per_buffer)
144112 {
145113 unsigned int curr_rate;
146114 enum snd_ff_clock_src src;
147115 int err;
148116
149
- if (ff->substreams_counter == 0)
150
- return 0;
151
-
152117 err = ff->spec->protocol->get_clock(ff, &curr_rate, &src);
153118 if (err < 0)
154119 return err;
155
- if (curr_rate != rate ||
156
- amdtp_streaming_error(&ff->tx_stream) ||
157
- amdtp_streaming_error(&ff->rx_stream)) {
120
+
121
+ if (ff->substreams_counter == 0 || curr_rate != rate) {
122
+ enum snd_ff_stream_mode mode;
123
+ int i;
124
+
125
+ amdtp_domain_stop(&ff->domain);
158126 finish_session(ff);
159127
160
- amdtp_stream_stop(&ff->tx_stream);
161
- amdtp_stream_stop(&ff->rx_stream);
128
+ fw_iso_resources_free(&ff->tx_resources);
129
+ fw_iso_resources_free(&ff->rx_resources);
162130
163
- release_resources(ff);
131
+ for (i = 0; i < CIP_SFC_COUNT; ++i) {
132
+ if (amdtp_rate_table[i] == rate)
133
+ break;
134
+ }
135
+ if (i >= CIP_SFC_COUNT)
136
+ return -EINVAL;
137
+
138
+ err = snd_ff_stream_get_multiplier_mode(i, &mode);
139
+ if (err < 0)
140
+ return err;
141
+
142
+ err = amdtp_ff_set_parameters(&ff->tx_stream, rate,
143
+ ff->spec->pcm_capture_channels[mode]);
144
+ if (err < 0)
145
+ return err;
146
+
147
+ err = amdtp_ff_set_parameters(&ff->rx_stream, rate,
148
+ ff->spec->pcm_playback_channels[mode]);
149
+ if (err < 0)
150
+ return err;
151
+
152
+ err = ff->spec->protocol->allocate_resources(ff, rate);
153
+ if (err < 0)
154
+ return err;
155
+
156
+ err = amdtp_domain_set_events_per_period(&ff->domain,
157
+ frames_per_period, frames_per_buffer);
158
+ if (err < 0) {
159
+ fw_iso_resources_free(&ff->tx_resources);
160
+ fw_iso_resources_free(&ff->rx_resources);
161
+ return err;
162
+ }
163
+ }
164
+
165
+ return 0;
166
+}
167
+
168
+int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
169
+{
170
+ int err;
171
+
172
+ if (ff->substreams_counter == 0)
173
+ return 0;
174
+
175
+ if (amdtp_streaming_error(&ff->tx_stream) ||
176
+ amdtp_streaming_error(&ff->rx_stream)) {
177
+ amdtp_domain_stop(&ff->domain);
178
+ finish_session(ff);
164179 }
165180
166181 /*
....@@ -168,21 +183,29 @@
168183 * packets. Then, the device transfers packets.
169184 */
170185 if (!amdtp_stream_running(&ff->rx_stream)) {
171
- err = keep_resources(ff, rate);
172
- if (err < 0)
173
- goto error;
186
+ int spd = fw_parent_device(ff->unit)->max_speed;
174187
175188 err = ff->spec->protocol->begin_session(ff, rate);
176189 if (err < 0)
177190 goto error;
178191
179
- err = amdtp_stream_start(&ff->rx_stream,
180
- ff->rx_resources.channel,
181
- fw_parent_device(ff->unit)->max_speed);
192
+ err = amdtp_domain_add_stream(&ff->domain, &ff->rx_stream,
193
+ ff->rx_resources.channel, spd);
194
+ if (err < 0)
195
+ goto error;
196
+
197
+ err = amdtp_domain_add_stream(&ff->domain, &ff->tx_stream,
198
+ ff->tx_resources.channel, spd);
199
+ if (err < 0)
200
+ goto error;
201
+
202
+ err = amdtp_domain_start(&ff->domain, 0);
182203 if (err < 0)
183204 goto error;
184205
185206 if (!amdtp_stream_wait_callback(&ff->rx_stream,
207
+ CALLBACK_TIMEOUT_MS) ||
208
+ !amdtp_stream_wait_callback(&ff->tx_stream,
186209 CALLBACK_TIMEOUT_MS)) {
187210 err = -ETIMEDOUT;
188211 goto error;
....@@ -193,53 +216,32 @@
193216 goto error;
194217 }
195218
196
- if (!amdtp_stream_running(&ff->tx_stream)) {
197
- err = amdtp_stream_start(&ff->tx_stream,
198
- ff->tx_resources.channel,
199
- fw_parent_device(ff->unit)->max_speed);
200
- if (err < 0)
201
- goto error;
202
-
203
- if (!amdtp_stream_wait_callback(&ff->tx_stream,
204
- CALLBACK_TIMEOUT_MS)) {
205
- err = -ETIMEDOUT;
206
- goto error;
207
- }
208
- }
209
-
210219 return 0;
211220 error:
212
- amdtp_stream_stop(&ff->tx_stream);
213
- amdtp_stream_stop(&ff->rx_stream);
214
-
221
+ amdtp_domain_stop(&ff->domain);
215222 finish_session(ff);
216
- release_resources(ff);
217223
218224 return err;
219225 }
220226
221227 void snd_ff_stream_stop_duplex(struct snd_ff *ff)
222228 {
223
- if (ff->substreams_counter > 0)
224
- return;
229
+ if (ff->substreams_counter == 0) {
230
+ amdtp_domain_stop(&ff->domain);
231
+ finish_session(ff);
225232
226
- amdtp_stream_stop(&ff->tx_stream);
227
- amdtp_stream_stop(&ff->rx_stream);
228
- finish_session(ff);
229
- release_resources(ff);
233
+ fw_iso_resources_free(&ff->tx_resources);
234
+ fw_iso_resources_free(&ff->rx_resources);
235
+ }
230236 }
231237
232238 void snd_ff_stream_update_duplex(struct snd_ff *ff)
233239 {
234
- /* The device discontinue to transfer packets. */
240
+ amdtp_domain_stop(&ff->domain);
241
+
242
+ // The device discontinue to transfer packets.
235243 amdtp_stream_pcm_abort(&ff->tx_stream);
236
- amdtp_stream_stop(&ff->tx_stream);
237
-
238244 amdtp_stream_pcm_abort(&ff->rx_stream);
239
- amdtp_stream_stop(&ff->rx_stream);
240
-
241
- fw_iso_resources_update(&ff->tx_resources);
242
- fw_iso_resources_update(&ff->rx_resources);
243245 }
244246
245247 void snd_ff_stream_lock_changed(struct snd_ff *ff)