forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/firewire/fireworks/fireworks_pcm.c
....@@ -1,10 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * fireworks_pcm.c - a part of driver for Fireworks based devices
34 *
45 * Copyright (c) 2009-2010 Clemens Ladisch
56 * Copyright (c) 2013-2014 Takashi Sakamoto
6
- *
7
- * Licensed under the terms of the GNU General Public License, version 2.
87 */
98 #include "./fireworks.h"
109
....@@ -149,7 +148,7 @@
149148 }
150149
151150 /* limit rates */
152
- runtime->hw.rates = efw->supported_sampling_rate,
151
+ runtime->hw.rates = efw->supported_sampling_rate;
153152 snd_pcm_limit_hw_rates(runtime);
154153
155154 limit_channels(&runtime->hw, pcm_channels);
....@@ -174,13 +173,13 @@
174173 static int pcm_open(struct snd_pcm_substream *substream)
175174 {
176175 struct snd_efw *efw = substream->private_data;
177
- unsigned int sampling_rate;
176
+ struct amdtp_domain *d = &efw->domain;
178177 enum snd_efw_clock_source clock_source;
179178 int err;
180179
181180 err = snd_efw_stream_lock_try(efw);
182181 if (err < 0)
183
- goto end;
182
+ return err;
184183
185184 err = pcm_init_hw_params(efw, substream);
186185 if (err < 0)
....@@ -190,23 +189,49 @@
190189 if (err < 0)
191190 goto err_locked;
192191
193
- /*
194
- * When source of clock is not internal or any PCM streams are running,
195
- * available sampling rate is limited at current sampling rate.
196
- */
192
+ mutex_lock(&efw->mutex);
193
+
194
+ // When source of clock is not internal or any stream is reserved for
195
+ // transmission of PCM frames, the available sampling rate is limited
196
+ // at current one.
197197 if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
198
- amdtp_stream_pcm_running(&efw->tx_stream) ||
199
- amdtp_stream_pcm_running(&efw->rx_stream)) {
198
+ (efw->substreams_counter > 0 && d->events_per_period > 0)) {
199
+ unsigned int frames_per_period = d->events_per_period;
200
+ unsigned int frames_per_buffer = d->events_per_buffer;
201
+ unsigned int sampling_rate;
202
+
200203 err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
201
- if (err < 0)
204
+ if (err < 0) {
205
+ mutex_unlock(&efw->mutex);
202206 goto err_locked;
207
+ }
203208 substream->runtime->hw.rate_min = sampling_rate;
204209 substream->runtime->hw.rate_max = sampling_rate;
210
+
211
+ if (frames_per_period > 0) {
212
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
213
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
214
+ frames_per_period, frames_per_period);
215
+ if (err < 0) {
216
+ mutex_unlock(&efw->mutex);
217
+ goto err_locked;
218
+ }
219
+
220
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
221
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
222
+ frames_per_buffer, frames_per_buffer);
223
+ if (err < 0) {
224
+ mutex_unlock(&efw->mutex);
225
+ goto err_locked;
226
+ }
227
+ }
205228 }
206229
230
+ mutex_unlock(&efw->mutex);
231
+
207232 snd_pcm_set_sync(substream);
208
-end:
209
- return err;
233
+
234
+ return 0;
210235 err_locked:
211236 snd_efw_stream_lock_release(efw);
212237 return err;
....@@ -219,81 +244,50 @@
219244 return 0;
220245 }
221246
222
-static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
247
+static int pcm_hw_params(struct snd_pcm_substream *substream,
223248 struct snd_pcm_hw_params *hw_params)
224249 {
225250 struct snd_efw *efw = substream->private_data;
226
- int err;
227
-
228
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
229
- params_buffer_bytes(hw_params));
230
- if (err < 0)
231
- return err;
251
+ int err = 0;
232252
233253 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
254
+ unsigned int rate = params_rate(hw_params);
255
+ unsigned int frames_per_period = params_period_size(hw_params);
256
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
257
+
234258 mutex_lock(&efw->mutex);
235
- efw->capture_substreams++;
259
+ err = snd_efw_stream_reserve_duplex(efw, rate,
260
+ frames_per_period, frames_per_buffer);
261
+ if (err >= 0)
262
+ ++efw->substreams_counter;
236263 mutex_unlock(&efw->mutex);
237264 }
238265
239
- return 0;
240
-}
241
-static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
242
- struct snd_pcm_hw_params *hw_params)
243
-{
244
- struct snd_efw *efw = substream->private_data;
245
- int err;
246
-
247
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
248
- params_buffer_bytes(hw_params));
249
- if (err < 0)
250
- return err;
251
-
252
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
253
- mutex_lock(&efw->mutex);
254
- efw->playback_substreams++;
255
- mutex_unlock(&efw->mutex);
256
- }
257
-
258
- return 0;
266
+ return err;
259267 }
260268
261
-static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
269
+static int pcm_hw_free(struct snd_pcm_substream *substream)
262270 {
263271 struct snd_efw *efw = substream->private_data;
264272
265
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
266
- mutex_lock(&efw->mutex);
267
- efw->capture_substreams--;
268
- mutex_unlock(&efw->mutex);
269
- }
273
+ mutex_lock(&efw->mutex);
274
+
275
+ if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
276
+ --efw->substreams_counter;
270277
271278 snd_efw_stream_stop_duplex(efw);
272279
273
- return snd_pcm_lib_free_vmalloc_buffer(substream);
274
-}
275
-static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
276
-{
277
- struct snd_efw *efw = substream->private_data;
280
+ mutex_unlock(&efw->mutex);
278281
279
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
280
- mutex_lock(&efw->mutex);
281
- efw->playback_substreams--;
282
- mutex_unlock(&efw->mutex);
283
- }
284
-
285
- snd_efw_stream_stop_duplex(efw);
286
-
287
- return snd_pcm_lib_free_vmalloc_buffer(substream);
282
+ return 0;
288283 }
289284
290285 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
291286 {
292287 struct snd_efw *efw = substream->private_data;
293
- struct snd_pcm_runtime *runtime = substream->runtime;
294288 int err;
295289
296
- err = snd_efw_stream_start_duplex(efw, runtime->rate);
290
+ err = snd_efw_stream_start_duplex(efw);
297291 if (err >= 0)
298292 amdtp_stream_pcm_prepare(&efw->tx_stream);
299293
....@@ -302,10 +296,9 @@
302296 static int pcm_playback_prepare(struct snd_pcm_substream *substream)
303297 {
304298 struct snd_efw *efw = substream->private_data;
305
- struct snd_pcm_runtime *runtime = substream->runtime;
306299 int err;
307300
308
- err = snd_efw_stream_start_duplex(efw, runtime->rate);
301
+ err = snd_efw_stream_start_duplex(efw);
309302 if (err >= 0)
310303 amdtp_stream_pcm_prepare(&efw->rx_stream);
311304
....@@ -350,26 +343,28 @@
350343 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
351344 {
352345 struct snd_efw *efw = sbstrm->private_data;
353
- return amdtp_stream_pcm_pointer(&efw->tx_stream);
346
+
347
+ return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->tx_stream);
354348 }
355349 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
356350 {
357351 struct snd_efw *efw = sbstrm->private_data;
358
- return amdtp_stream_pcm_pointer(&efw->rx_stream);
352
+
353
+ return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->rx_stream);
359354 }
360355
361356 static int pcm_capture_ack(struct snd_pcm_substream *substream)
362357 {
363358 struct snd_efw *efw = substream->private_data;
364359
365
- return amdtp_stream_pcm_ack(&efw->tx_stream);
360
+ return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->tx_stream);
366361 }
367362
368363 static int pcm_playback_ack(struct snd_pcm_substream *substream)
369364 {
370365 struct snd_efw *efw = substream->private_data;
371366
372
- return amdtp_stream_pcm_ack(&efw->rx_stream);
367
+ return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->rx_stream);
373368 }
374369
375370 int snd_efw_create_pcm_devices(struct snd_efw *efw)
....@@ -377,26 +372,22 @@
377372 static const struct snd_pcm_ops capture_ops = {
378373 .open = pcm_open,
379374 .close = pcm_close,
380
- .ioctl = snd_pcm_lib_ioctl,
381
- .hw_params = pcm_capture_hw_params,
382
- .hw_free = pcm_capture_hw_free,
375
+ .hw_params = pcm_hw_params,
376
+ .hw_free = pcm_hw_free,
383377 .prepare = pcm_capture_prepare,
384378 .trigger = pcm_capture_trigger,
385379 .pointer = pcm_capture_pointer,
386380 .ack = pcm_capture_ack,
387
- .page = snd_pcm_lib_get_vmalloc_page,
388381 };
389382 static const struct snd_pcm_ops playback_ops = {
390383 .open = pcm_open,
391384 .close = pcm_close,
392
- .ioctl = snd_pcm_lib_ioctl,
393
- .hw_params = pcm_playback_hw_params,
394
- .hw_free = pcm_playback_hw_free,
385
+ .hw_params = pcm_hw_params,
386
+ .hw_free = pcm_hw_free,
395387 .prepare = pcm_playback_prepare,
396388 .trigger = pcm_playback_trigger,
397389 .pointer = pcm_playback_pointer,
398390 .ack = pcm_playback_ack,
399
- .page = snd_pcm_lib_get_vmalloc_page,
400391 };
401392 struct snd_pcm *pcm;
402393 int err;
....@@ -409,6 +400,7 @@
409400 snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname);
410401 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
411402 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
403
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
412404 end:
413405 return err;
414406 }