From 244b2c5ca8b14627e4a17755e5922221e121c771 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:15:07 +0000
Subject: [PATCH] change system file
---
kernel/sound/firewire/fireworks/fireworks_pcm.c | 148 +++++++++++++++++++++++--------------------------
1 files changed, 70 insertions(+), 78 deletions(-)
diff --git a/kernel/sound/firewire/fireworks/fireworks_pcm.c b/kernel/sound/firewire/fireworks/fireworks_pcm.c
index aed566d..a0d5db1 100644
--- a/kernel/sound/firewire/fireworks/fireworks_pcm.c
+++ b/kernel/sound/firewire/fireworks/fireworks_pcm.c
@@ -1,10 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* fireworks_pcm.c - a part of driver for Fireworks based devices
*
* Copyright (c) 2009-2010 Clemens Ladisch
* Copyright (c) 2013-2014 Takashi Sakamoto
- *
- * Licensed under the terms of the GNU General Public License, version 2.
*/
#include "./fireworks.h"
@@ -149,7 +148,7 @@
}
/* limit rates */
- runtime->hw.rates = efw->supported_sampling_rate,
+ runtime->hw.rates = efw->supported_sampling_rate;
snd_pcm_limit_hw_rates(runtime);
limit_channels(&runtime->hw, pcm_channels);
@@ -174,13 +173,13 @@
static int pcm_open(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- unsigned int sampling_rate;
+ struct amdtp_domain *d = &efw->domain;
enum snd_efw_clock_source clock_source;
int err;
err = snd_efw_stream_lock_try(efw);
if (err < 0)
- goto end;
+ return err;
err = pcm_init_hw_params(efw, substream);
if (err < 0)
@@ -190,23 +189,49 @@
if (err < 0)
goto err_locked;
- /*
- * When source of clock is not internal or any PCM streams are running,
- * available sampling rate is limited at current sampling rate.
- */
+ mutex_lock(&efw->mutex);
+
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
- amdtp_stream_pcm_running(&efw->tx_stream) ||
- amdtp_stream_pcm_running(&efw->rx_stream)) {
+ (efw->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int frames_per_buffer = d->events_per_buffer;
+ unsigned int sampling_rate;
+
err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
- if (err < 0)
+ if (err < 0) {
+ mutex_unlock(&efw->mutex);
goto err_locked;
+ }
substream->runtime->hw.rate_min = sampling_rate;
substream->runtime->hw.rate_max = sampling_rate;
+
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0) {
+ mutex_unlock(&efw->mutex);
+ goto err_locked;
+ }
+
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ frames_per_buffer, frames_per_buffer);
+ if (err < 0) {
+ mutex_unlock(&efw->mutex);
+ goto err_locked;
+ }
+ }
}
+ mutex_unlock(&efw->mutex);
+
snd_pcm_set_sync(substream);
-end:
- return err;
+
+ return 0;
err_locked:
snd_efw_stream_lock_release(efw);
return err;
@@ -219,81 +244,50 @@
return 0;
}
-static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
+static int pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_efw *efw = substream->private_data;
- int err;
-
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
+ int err = 0;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ unsigned int rate = params_rate(hw_params);
+ unsigned int frames_per_period = params_period_size(hw_params);
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
+
mutex_lock(&efw->mutex);
- efw->capture_substreams++;
+ err = snd_efw_stream_reserve_duplex(efw, rate,
+ frames_per_period, frames_per_buffer);
+ if (err >= 0)
+ ++efw->substreams_counter;
mutex_unlock(&efw->mutex);
}
- return 0;
-}
-static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_efw *efw = substream->private_data;
- int err;
-
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
-
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
- mutex_lock(&efw->mutex);
- efw->playback_substreams++;
- mutex_unlock(&efw->mutex);
- }
-
- return 0;
+ return err;
}
-static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
+static int pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
- mutex_lock(&efw->mutex);
- efw->capture_substreams--;
- mutex_unlock(&efw->mutex);
- }
+ mutex_lock(&efw->mutex);
+
+ if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
+ --efw->substreams_counter;
snd_efw_stream_stop_duplex(efw);
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_efw *efw = substream->private_data;
+ mutex_unlock(&efw->mutex);
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
- mutex_lock(&efw->mutex);
- efw->playback_substreams--;
- mutex_unlock(&efw->mutex);
- }
-
- snd_efw_stream_stop_duplex(efw);
-
- return snd_pcm_lib_free_vmalloc_buffer(substream);
+ return 0;
}
static int pcm_capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- err = snd_efw_stream_start_duplex(efw, runtime->rate);
+ err = snd_efw_stream_start_duplex(efw);
if (err >= 0)
amdtp_stream_pcm_prepare(&efw->tx_stream);
@@ -302,10 +296,9 @@
static int pcm_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- err = snd_efw_stream_start_duplex(efw, runtime->rate);
+ err = snd_efw_stream_start_duplex(efw);
if (err >= 0)
amdtp_stream_pcm_prepare(&efw->rx_stream);
@@ -350,26 +343,28 @@
static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
{
struct snd_efw *efw = sbstrm->private_data;
- return amdtp_stream_pcm_pointer(&efw->tx_stream);
+
+ return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->tx_stream);
}
static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
{
struct snd_efw *efw = sbstrm->private_data;
- return amdtp_stream_pcm_pointer(&efw->rx_stream);
+
+ return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->rx_stream);
}
static int pcm_capture_ack(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- return amdtp_stream_pcm_ack(&efw->tx_stream);
+ return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->tx_stream);
}
static int pcm_playback_ack(struct snd_pcm_substream *substream)
{
struct snd_efw *efw = substream->private_data;
- return amdtp_stream_pcm_ack(&efw->rx_stream);
+ return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->rx_stream);
}
int snd_efw_create_pcm_devices(struct snd_efw *efw)
@@ -377,26 +372,22 @@
static const struct snd_pcm_ops capture_ops = {
.open = pcm_open,
.close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_capture_hw_params,
- .hw_free = pcm_capture_hw_free,
+ .hw_params = pcm_hw_params,
+ .hw_free = pcm_hw_free,
.prepare = pcm_capture_prepare,
.trigger = pcm_capture_trigger,
.pointer = pcm_capture_pointer,
.ack = pcm_capture_ack,
- .page = snd_pcm_lib_get_vmalloc_page,
};
static const struct snd_pcm_ops playback_ops = {
.open = pcm_open,
.close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_playback_hw_params,
- .hw_free = pcm_playback_hw_free,
+ .hw_params = pcm_hw_params,
+ .hw_free = pcm_hw_free,
.prepare = pcm_playback_prepare,
.trigger = pcm_playback_trigger,
.pointer = pcm_playback_pointer,
.ack = pcm_playback_ack,
- .page = snd_pcm_lib_get_vmalloc_page,
};
struct snd_pcm *pcm;
int err;
@@ -409,6 +400,7 @@
snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
end:
return err;
}
--
Gitblit v1.6.2