forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/firewire/oxfw/oxfw-pcm.c
....@@ -1,8 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * oxfw_pcm.c - a part of driver for OXFW970/971 based devices
34 *
45 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5
- * Licensed under the terms of the GNU General Public License, version 2.
66 */
77
88 #include "oxfw.h"
....@@ -170,30 +170,56 @@
170170 static int pcm_open(struct snd_pcm_substream *substream)
171171 {
172172 struct snd_oxfw *oxfw = substream->private_data;
173
+ struct amdtp_domain *d = &oxfw->domain;
173174 int err;
174175
175176 err = snd_oxfw_stream_lock_try(oxfw);
176177 if (err < 0)
177
- goto end;
178
+ return err;
178179
179180 err = init_hw_params(oxfw, substream);
180181 if (err < 0)
181182 goto err_locked;
182183
183
- /*
184
- * When any PCM streams are already running, the available sampling
185
- * rate is limited at current value.
186
- */
187
- if (amdtp_stream_pcm_running(&oxfw->tx_stream) ||
188
- amdtp_stream_pcm_running(&oxfw->rx_stream)) {
184
+ mutex_lock(&oxfw->mutex);
185
+
186
+ // When source of clock is not internal or any stream is reserved for
187
+ // transmission of PCM frames, the available sampling rate is limited
188
+ // at current one.
189
+ if (oxfw->substreams_count > 0 && d->events_per_period > 0) {
190
+ unsigned int frames_per_period = d->events_per_period;
191
+ unsigned int frames_per_buffer = d->events_per_buffer;
192
+
189193 err = limit_to_current_params(substream);
190
- if (err < 0)
191
- goto end;
194
+ if (err < 0) {
195
+ mutex_unlock(&oxfw->mutex);
196
+ goto err_locked;
197
+ }
198
+
199
+ if (frames_per_period > 0) {
200
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
201
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
202
+ frames_per_period, frames_per_period);
203
+ if (err < 0) {
204
+ mutex_unlock(&oxfw->mutex);
205
+ goto err_locked;
206
+ }
207
+
208
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
209
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
210
+ frames_per_buffer, frames_per_buffer);
211
+ if (err < 0) {
212
+ mutex_unlock(&oxfw->mutex);
213
+ goto err_locked;
214
+ }
215
+ }
192216 }
193217
218
+ mutex_unlock(&oxfw->mutex);
219
+
194220 snd_pcm_set_sync(substream);
195
-end:
196
- return err;
221
+
222
+ return 0;
197223 err_locked:
198224 snd_oxfw_stream_lock_release(oxfw);
199225 return err;
....@@ -211,39 +237,47 @@
211237 struct snd_pcm_hw_params *hw_params)
212238 {
213239 struct snd_oxfw *oxfw = substream->private_data;
214
- int err;
215
-
216
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
217
- params_buffer_bytes(hw_params));
218
- if (err < 0)
219
- return err;
240
+ int err = 0;
220241
221242 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
243
+ unsigned int rate = params_rate(hw_params);
244
+ unsigned int channels = params_channels(hw_params);
245
+ unsigned int frames_per_period = params_period_size(hw_params);
246
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
247
+
222248 mutex_lock(&oxfw->mutex);
223
- oxfw->capture_substreams++;
249
+ err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
250
+ rate, channels, frames_per_period,
251
+ frames_per_buffer);
252
+ if (err >= 0)
253
+ ++oxfw->substreams_count;
224254 mutex_unlock(&oxfw->mutex);
225255 }
226256
227
- return 0;
257
+ return err;
228258 }
229259 static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
230260 struct snd_pcm_hw_params *hw_params)
231261 {
232262 struct snd_oxfw *oxfw = substream->private_data;
233
- int err;
234
-
235
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
236
- params_buffer_bytes(hw_params));
237
- if (err < 0)
238
- return err;
263
+ int err = 0;
239264
240265 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
266
+ unsigned int rate = params_rate(hw_params);
267
+ unsigned int channels = params_channels(hw_params);
268
+ unsigned int frames_per_period = params_period_size(hw_params);
269
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
270
+
241271 mutex_lock(&oxfw->mutex);
242
- oxfw->playback_substreams++;
272
+ err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream,
273
+ rate, channels, frames_per_period,
274
+ frames_per_buffer);
275
+ if (err >= 0)
276
+ ++oxfw->substreams_count;
243277 mutex_unlock(&oxfw->mutex);
244278 }
245279
246
- return 0;
280
+ return err;
247281 }
248282
249283 static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
....@@ -253,13 +287,13 @@
253287 mutex_lock(&oxfw->mutex);
254288
255289 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
256
- oxfw->capture_substreams--;
290
+ --oxfw->substreams_count;
257291
258
- snd_oxfw_stream_stop_simplex(oxfw, &oxfw->tx_stream);
292
+ snd_oxfw_stream_stop_duplex(oxfw);
259293
260294 mutex_unlock(&oxfw->mutex);
261295
262
- return snd_pcm_lib_free_vmalloc_buffer(substream);
296
+ return 0;
263297 }
264298 static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
265299 {
....@@ -268,24 +302,22 @@
268302 mutex_lock(&oxfw->mutex);
269303
270304 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
271
- oxfw->playback_substreams--;
305
+ --oxfw->substreams_count;
272306
273
- snd_oxfw_stream_stop_simplex(oxfw, &oxfw->rx_stream);
307
+ snd_oxfw_stream_stop_duplex(oxfw);
274308
275309 mutex_unlock(&oxfw->mutex);
276310
277
- return snd_pcm_lib_free_vmalloc_buffer(substream);
311
+ return 0;
278312 }
279313
280314 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
281315 {
282316 struct snd_oxfw *oxfw = substream->private_data;
283
- struct snd_pcm_runtime *runtime = substream->runtime;
284317 int err;
285318
286319 mutex_lock(&oxfw->mutex);
287
- err = snd_oxfw_stream_start_simplex(oxfw, &oxfw->tx_stream,
288
- runtime->rate, runtime->channels);
320
+ err = snd_oxfw_stream_start_duplex(oxfw);
289321 mutex_unlock(&oxfw->mutex);
290322 if (err < 0)
291323 goto end;
....@@ -297,12 +329,10 @@
297329 static int pcm_playback_prepare(struct snd_pcm_substream *substream)
298330 {
299331 struct snd_oxfw *oxfw = substream->private_data;
300
- struct snd_pcm_runtime *runtime = substream->runtime;
301332 int err;
302333
303334 mutex_lock(&oxfw->mutex);
304
- err = snd_oxfw_stream_start_simplex(oxfw, &oxfw->rx_stream,
305
- runtime->rate, runtime->channels);
335
+ err = snd_oxfw_stream_start_duplex(oxfw);
306336 mutex_unlock(&oxfw->mutex);
307337 if (err < 0)
308338 goto end;
....@@ -353,27 +383,27 @@
353383 {
354384 struct snd_oxfw *oxfw = sbstm->private_data;
355385
356
- return amdtp_stream_pcm_pointer(&oxfw->tx_stream);
386
+ return amdtp_domain_stream_pcm_pointer(&oxfw->domain, &oxfw->tx_stream);
357387 }
358388 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstm)
359389 {
360390 struct snd_oxfw *oxfw = sbstm->private_data;
361391
362
- return amdtp_stream_pcm_pointer(&oxfw->rx_stream);
392
+ return amdtp_domain_stream_pcm_pointer(&oxfw->domain, &oxfw->rx_stream);
363393 }
364394
365395 static int pcm_capture_ack(struct snd_pcm_substream *substream)
366396 {
367397 struct snd_oxfw *oxfw = substream->private_data;
368398
369
- return amdtp_stream_pcm_ack(&oxfw->tx_stream);
399
+ return amdtp_domain_stream_pcm_ack(&oxfw->domain, &oxfw->tx_stream);
370400 }
371401
372402 static int pcm_playback_ack(struct snd_pcm_substream *substream)
373403 {
374404 struct snd_oxfw *oxfw = substream->private_data;
375405
376
- return amdtp_stream_pcm_ack(&oxfw->rx_stream);
406
+ return amdtp_domain_stream_pcm_ack(&oxfw->domain, &oxfw->rx_stream);
377407 }
378408
379409 int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
....@@ -381,26 +411,22 @@
381411 static const struct snd_pcm_ops capture_ops = {
382412 .open = pcm_open,
383413 .close = pcm_close,
384
- .ioctl = snd_pcm_lib_ioctl,
385414 .hw_params = pcm_capture_hw_params,
386415 .hw_free = pcm_capture_hw_free,
387416 .prepare = pcm_capture_prepare,
388417 .trigger = pcm_capture_trigger,
389418 .pointer = pcm_capture_pointer,
390419 .ack = pcm_capture_ack,
391
- .page = snd_pcm_lib_get_vmalloc_page,
392420 };
393421 static const struct snd_pcm_ops playback_ops = {
394422 .open = pcm_open,
395423 .close = pcm_close,
396
- .ioctl = snd_pcm_lib_ioctl,
397424 .hw_params = pcm_playback_hw_params,
398425 .hw_free = pcm_playback_hw_free,
399426 .prepare = pcm_playback_prepare,
400427 .trigger = pcm_playback_trigger,
401428 .pointer = pcm_playback_pointer,
402429 .ack = pcm_playback_ack,
403
- .page = snd_pcm_lib_get_vmalloc_page,
404430 };
405431 struct snd_pcm *pcm;
406432 unsigned int cap = 0;
....@@ -418,6 +444,7 @@
418444 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
419445 if (cap > 0)
420446 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
447
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
421448
422449 return 0;
423450 }