forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/firewire/fireface/ff-pcm.c
....@@ -1,17 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ff-pcm.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"
10
-
11
-static inline unsigned int get_multiplier_mode_with_index(unsigned int index)
12
-{
13
- return ((int)index - 1) / 2;
14
-}
159
1610 static int hw_rule_rate(struct snd_pcm_hw_params *params,
1711 struct snd_pcm_hw_rule *rule)
....@@ -24,10 +18,16 @@
2418 struct snd_interval t = {
2519 .min = UINT_MAX, .max = 0, .integer = 1
2620 };
27
- unsigned int i, mode;
21
+ unsigned int i;
2822
2923 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
30
- mode = get_multiplier_mode_with_index(i);
24
+ enum snd_ff_stream_mode mode;
25
+ int err;
26
+
27
+ err = snd_ff_stream_get_multiplier_mode(i, &mode);
28
+ if (err < 0)
29
+ continue;
30
+
3131 if (!snd_interval_test(c, pcm_channels[mode]))
3232 continue;
3333
....@@ -49,10 +49,16 @@
4949 struct snd_interval t = {
5050 .min = UINT_MAX, .max = 0, .integer = 1
5151 };
52
- unsigned int i, mode;
52
+ unsigned int i;
5353
5454 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
55
- mode = get_multiplier_mode_with_index(i);
55
+ enum snd_ff_stream_mode mode;
56
+ int err;
57
+
58
+ err = snd_ff_stream_get_multiplier_mode(i, &mode);
59
+ if (err < 0)
60
+ continue;
61
+
5662 if (!snd_interval_test(r, amdtp_rate_table[i]))
5763 continue;
5864
....@@ -66,7 +72,6 @@
6672 static void limit_channels_and_rates(struct snd_pcm_hardware *hw,
6773 const unsigned int *pcm_channels)
6874 {
69
- unsigned int mode;
7075 unsigned int rate, channels;
7176 int i;
7277
....@@ -76,7 +81,12 @@
7681 hw->rate_max = 0;
7782
7883 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
79
- mode = get_multiplier_mode_with_index(i);
84
+ enum snd_ff_stream_mode mode;
85
+ int err;
86
+
87
+ err = snd_ff_stream_get_multiplier_mode(i, &mode);
88
+ if (err < 0)
89
+ continue;
8090
8191 channels = pcm_channels[mode];
8292 if (pcm_channels[mode] == 0)
....@@ -129,6 +139,7 @@
129139 static int pcm_open(struct snd_pcm_substream *substream)
130140 {
131141 struct snd_ff *ff = substream->private_data;
142
+ struct amdtp_domain *d = &ff->domain;
132143 unsigned int rate;
133144 enum snd_ff_clock_src src;
134145 int i, err;
....@@ -145,16 +156,21 @@
145156 if (err < 0)
146157 goto release_lock;
147158
159
+ mutex_lock(&ff->mutex);
160
+
161
+ // When source of clock is not internal or any stream is reserved for
162
+ // transmission of PCM frames, the available sampling rate is limited
163
+ // at current one.
148164 if (src != SND_FF_CLOCK_SRC_INTERNAL) {
149165 for (i = 0; i < CIP_SFC_COUNT; ++i) {
150166 if (amdtp_rate_table[i] == rate)
151167 break;
152168 }
153
- /*
154
- * The unit is configured at sampling frequency which packet
155
- * streaming engine can't support.
156
- */
169
+
170
+ // The unit is configured at sampling frequency which packet
171
+ // streaming engine can't support.
157172 if (i >= CIP_SFC_COUNT) {
173
+ mutex_unlock(&ff->mutex);
158174 err = -EIO;
159175 goto release_lock;
160176 }
....@@ -162,13 +178,33 @@
162178 substream->runtime->hw.rate_min = rate;
163179 substream->runtime->hw.rate_max = rate;
164180 } else {
165
- if (amdtp_stream_pcm_running(&ff->rx_stream) ||
166
- amdtp_stream_pcm_running(&ff->tx_stream)) {
181
+ if (ff->substreams_counter > 0) {
182
+ unsigned int frames_per_period = d->events_per_period;
183
+ unsigned int frames_per_buffer = d->events_per_buffer;
184
+
167185 rate = amdtp_rate_table[ff->rx_stream.sfc];
168186 substream->runtime->hw.rate_min = rate;
169187 substream->runtime->hw.rate_max = rate;
188
+
189
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
190
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
191
+ frames_per_period, frames_per_period);
192
+ if (err < 0) {
193
+ mutex_unlock(&ff->mutex);
194
+ goto release_lock;
195
+ }
196
+
197
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
198
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
199
+ frames_per_buffer, frames_per_buffer);
200
+ if (err < 0) {
201
+ mutex_unlock(&ff->mutex);
202
+ goto release_lock;
203
+ }
170204 }
171205 }
206
+
207
+ mutex_unlock(&ff->mutex);
172208
173209 snd_pcm_set_sync(substream);
174210
....@@ -188,76 +224,42 @@
188224 return 0;
189225 }
190226
191
-static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
192
- struct snd_pcm_hw_params *hw_params)
227
+static int pcm_hw_params(struct snd_pcm_substream *substream,
228
+ struct snd_pcm_hw_params *hw_params)
193229 {
194230 struct snd_ff *ff = substream->private_data;
195
- int err;
196
-
197
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
198
- params_buffer_bytes(hw_params));
199
- if (err < 0)
200
- return err;
231
+ int err = 0;
201232
202233 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
234
+ unsigned int rate = params_rate(hw_params);
235
+ unsigned int frames_per_period = params_period_size(hw_params);
236
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
237
+
203238 mutex_lock(&ff->mutex);
204
- ff->substreams_counter++;
239
+ err = snd_ff_stream_reserve_duplex(ff, rate, frames_per_period,
240
+ frames_per_buffer);
241
+ if (err >= 0)
242
+ ++ff->substreams_counter;
205243 mutex_unlock(&ff->mutex);
206244 }
207245
208
- return 0;
246
+ return err;
209247 }
210248
211
-static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
212
- struct snd_pcm_hw_params *hw_params)
213
-{
214
- struct snd_ff *ff = substream->private_data;
215
- int err;
216
-
217
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
218
- params_buffer_bytes(hw_params));
219
- if (err < 0)
220
- return err;
221
-
222
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
223
- mutex_lock(&ff->mutex);
224
- ff->substreams_counter++;
225
- mutex_unlock(&ff->mutex);
226
- }
227
-
228
- return 0;
229
-}
230
-
231
-static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
249
+static int pcm_hw_free(struct snd_pcm_substream *substream)
232250 {
233251 struct snd_ff *ff = substream->private_data;
234252
235253 mutex_lock(&ff->mutex);
236254
237255 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
238
- ff->substreams_counter--;
256
+ --ff->substreams_counter;
239257
240258 snd_ff_stream_stop_duplex(ff);
241259
242260 mutex_unlock(&ff->mutex);
243261
244
- return snd_pcm_lib_free_vmalloc_buffer(substream);
245
-}
246
-
247
-static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
248
-{
249
- struct snd_ff *ff = substream->private_data;
250
-
251
- mutex_lock(&ff->mutex);
252
-
253
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
254
- ff->substreams_counter--;
255
-
256
- snd_ff_stream_stop_duplex(ff);
257
-
258
- mutex_unlock(&ff->mutex);
259
-
260
- return snd_pcm_lib_free_vmalloc_buffer(substream);
262
+ return 0;
261263 }
262264
263265 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
....@@ -334,28 +336,28 @@
334336 {
335337 struct snd_ff *ff = sbstrm->private_data;
336338
337
- return amdtp_stream_pcm_pointer(&ff->tx_stream);
339
+ return amdtp_domain_stream_pcm_pointer(&ff->domain, &ff->tx_stream);
338340 }
339341
340342 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
341343 {
342344 struct snd_ff *ff = sbstrm->private_data;
343345
344
- return amdtp_stream_pcm_pointer(&ff->rx_stream);
346
+ return amdtp_domain_stream_pcm_pointer(&ff->domain, &ff->rx_stream);
345347 }
346348
347349 static int pcm_capture_ack(struct snd_pcm_substream *substream)
348350 {
349351 struct snd_ff *ff = substream->private_data;
350352
351
- return amdtp_stream_pcm_ack(&ff->tx_stream);
353
+ return amdtp_domain_stream_pcm_ack(&ff->domain, &ff->tx_stream);
352354 }
353355
354356 static int pcm_playback_ack(struct snd_pcm_substream *substream)
355357 {
356358 struct snd_ff *ff = substream->private_data;
357359
358
- return amdtp_stream_pcm_ack(&ff->rx_stream);
360
+ return amdtp_domain_stream_pcm_ack(&ff->domain, &ff->rx_stream);
359361 }
360362
361363 int snd_ff_create_pcm_devices(struct snd_ff *ff)
....@@ -363,26 +365,22 @@
363365 static const struct snd_pcm_ops pcm_capture_ops = {
364366 .open = pcm_open,
365367 .close = pcm_close,
366
- .ioctl = snd_pcm_lib_ioctl,
367
- .hw_params = pcm_capture_hw_params,
368
- .hw_free = pcm_capture_hw_free,
368
+ .hw_params = pcm_hw_params,
369
+ .hw_free = pcm_hw_free,
369370 .prepare = pcm_capture_prepare,
370371 .trigger = pcm_capture_trigger,
371372 .pointer = pcm_capture_pointer,
372373 .ack = pcm_capture_ack,
373
- .page = snd_pcm_lib_get_vmalloc_page,
374374 };
375375 static const struct snd_pcm_ops pcm_playback_ops = {
376376 .open = pcm_open,
377377 .close = pcm_close,
378
- .ioctl = snd_pcm_lib_ioctl,
379
- .hw_params = pcm_playback_hw_params,
380
- .hw_free = pcm_playback_hw_free,
378
+ .hw_params = pcm_hw_params,
379
+ .hw_free = pcm_hw_free,
381380 .prepare = pcm_playback_prepare,
382381 .trigger = pcm_playback_trigger,
383382 .pointer = pcm_playback_pointer,
384383 .ack = pcm_playback_ack,
385
- .page = snd_pcm_lib_get_vmalloc_page,
386384 };
387385 struct snd_pcm *pcm;
388386 int err;
....@@ -396,6 +394,7 @@
396394 "%s PCM", ff->card->shortname);
397395 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
398396 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
397
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
399398
400399 return 0;
401400 }