forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/firewire/tascam/tascam-pcm.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * tascam-pcm.c - a part of driver for TASCAM FireWire series
34 *
45 * Copyright (c) 2015 Takashi Sakamoto
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include "tascam.h"
....@@ -44,13 +43,13 @@
4443 static int pcm_open(struct snd_pcm_substream *substream)
4544 {
4645 struct snd_tscm *tscm = substream->private_data;
46
+ struct amdtp_domain *d = &tscm->domain;
4747 enum snd_tscm_clock clock;
48
- unsigned int rate;
4948 int err;
5049
5150 err = snd_tscm_stream_lock_try(tscm);
5251 if (err < 0)
53
- goto end;
52
+ return err;
5453
5554 err = pcm_init_hw_params(tscm, substream);
5655 if (err < 0)
....@@ -60,19 +59,46 @@
6059 if (err < 0)
6160 goto err_locked;
6261
63
- if (clock != SND_TSCM_CLOCK_INTERNAL ||
64
- amdtp_stream_pcm_running(&tscm->rx_stream) ||
65
- amdtp_stream_pcm_running(&tscm->tx_stream)) {
62
+ mutex_lock(&tscm->mutex);
63
+
64
+ // When source of clock is not internal or any stream is reserved for
65
+ // transmission of PCM frames, the available sampling rate is limited
66
+ // at current one.
67
+ if (clock != SND_TSCM_CLOCK_INTERNAL || tscm->substreams_counter > 0) {
68
+ unsigned int frames_per_period = d->events_per_period;
69
+ unsigned int frames_per_buffer = d->events_per_buffer;
70
+ unsigned int rate;
71
+
6672 err = snd_tscm_stream_get_rate(tscm, &rate);
67
- if (err < 0)
73
+ if (err < 0) {
74
+ mutex_unlock(&tscm->mutex);
6875 goto err_locked;
76
+ }
6977 substream->runtime->hw.rate_min = rate;
7078 substream->runtime->hw.rate_max = rate;
79
+
80
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
81
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
82
+ frames_per_period, frames_per_period);
83
+ if (err < 0) {
84
+ mutex_unlock(&tscm->mutex);
85
+ goto err_locked;
86
+ }
87
+
88
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
89
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
90
+ frames_per_buffer, frames_per_buffer);
91
+ if (err < 0) {
92
+ mutex_unlock(&tscm->mutex);
93
+ goto err_locked;
94
+ }
7195 }
7296
97
+ mutex_unlock(&tscm->mutex);
98
+
7399 snd_pcm_set_sync(substream);
74
-end:
75
- return err;
100
+
101
+ return 0;
76102 err_locked:
77103 snd_tscm_stream_lock_release(tscm);
78104 return err;
....@@ -87,76 +113,42 @@
87113 return 0;
88114 }
89115
90
-static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
91
- struct snd_pcm_hw_params *hw_params)
116
+static int pcm_hw_params(struct snd_pcm_substream *substream,
117
+ struct snd_pcm_hw_params *hw_params)
92118 {
93119 struct snd_tscm *tscm = substream->private_data;
94
- int err;
95
-
96
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
97
- params_buffer_bytes(hw_params));
98
- if (err < 0)
99
- return err;
120
+ int err = 0;
100121
101122 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
123
+ unsigned int rate = params_rate(hw_params);
124
+ unsigned int frames_per_period = params_period_size(hw_params);
125
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
126
+
102127 mutex_lock(&tscm->mutex);
103
- tscm->substreams_counter++;
128
+ err = snd_tscm_stream_reserve_duplex(tscm, rate,
129
+ frames_per_period, frames_per_buffer);
130
+ if (err >= 0)
131
+ ++tscm->substreams_counter;
104132 mutex_unlock(&tscm->mutex);
105133 }
106134
107
- return 0;
135
+ return err;
108136 }
109137
110
-static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
111
- struct snd_pcm_hw_params *hw_params)
112
-{
113
- struct snd_tscm *tscm = substream->private_data;
114
- int err;
115
-
116
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
117
- params_buffer_bytes(hw_params));
118
- if (err < 0)
119
- return err;
120
-
121
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
122
- mutex_lock(&tscm->mutex);
123
- tscm->substreams_counter++;
124
- mutex_unlock(&tscm->mutex);
125
- }
126
-
127
- return 0;
128
-}
129
-
130
-static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
138
+static int pcm_hw_free(struct snd_pcm_substream *substream)
131139 {
132140 struct snd_tscm *tscm = substream->private_data;
133141
134142 mutex_lock(&tscm->mutex);
135143
136144 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
137
- tscm->substreams_counter--;
145
+ --tscm->substreams_counter;
138146
139147 snd_tscm_stream_stop_duplex(tscm);
140148
141149 mutex_unlock(&tscm->mutex);
142150
143
- return snd_pcm_lib_free_vmalloc_buffer(substream);
144
-}
145
-
146
-static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
147
-{
148
- struct snd_tscm *tscm = substream->private_data;
149
-
150
- mutex_lock(&tscm->mutex);
151
-
152
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
153
- tscm->substreams_counter--;
154
-
155
- snd_tscm_stream_stop_duplex(tscm);
156
-
157
- mutex_unlock(&tscm->mutex);
158
-
159
- return snd_pcm_lib_free_vmalloc_buffer(substream);
151
+ return 0;
160152 }
161153
162154 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
....@@ -233,28 +225,28 @@
233225 {
234226 struct snd_tscm *tscm = sbstrm->private_data;
235227
236
- return amdtp_stream_pcm_pointer(&tscm->tx_stream);
228
+ return amdtp_domain_stream_pcm_pointer(&tscm->domain, &tscm->tx_stream);
237229 }
238230
239231 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
240232 {
241233 struct snd_tscm *tscm = sbstrm->private_data;
242234
243
- return amdtp_stream_pcm_pointer(&tscm->rx_stream);
235
+ return amdtp_domain_stream_pcm_pointer(&tscm->domain, &tscm->rx_stream);
244236 }
245237
246238 static int pcm_capture_ack(struct snd_pcm_substream *substream)
247239 {
248240 struct snd_tscm *tscm = substream->private_data;
249241
250
- return amdtp_stream_pcm_ack(&tscm->tx_stream);
242
+ return amdtp_domain_stream_pcm_ack(&tscm->domain, &tscm->tx_stream);
251243 }
252244
253245 static int pcm_playback_ack(struct snd_pcm_substream *substream)
254246 {
255247 struct snd_tscm *tscm = substream->private_data;
256248
257
- return amdtp_stream_pcm_ack(&tscm->rx_stream);
249
+ return amdtp_domain_stream_pcm_ack(&tscm->domain, &tscm->rx_stream);
258250 }
259251
260252 int snd_tscm_create_pcm_devices(struct snd_tscm *tscm)
....@@ -262,26 +254,22 @@
262254 static const struct snd_pcm_ops capture_ops = {
263255 .open = pcm_open,
264256 .close = pcm_close,
265
- .ioctl = snd_pcm_lib_ioctl,
266
- .hw_params = pcm_capture_hw_params,
267
- .hw_free = pcm_capture_hw_free,
257
+ .hw_params = pcm_hw_params,
258
+ .hw_free = pcm_hw_free,
268259 .prepare = pcm_capture_prepare,
269260 .trigger = pcm_capture_trigger,
270261 .pointer = pcm_capture_pointer,
271262 .ack = pcm_capture_ack,
272
- .page = snd_pcm_lib_get_vmalloc_page,
273263 };
274264 static const struct snd_pcm_ops playback_ops = {
275265 .open = pcm_open,
276266 .close = pcm_close,
277
- .ioctl = snd_pcm_lib_ioctl,
278
- .hw_params = pcm_playback_hw_params,
279
- .hw_free = pcm_playback_hw_free,
267
+ .hw_params = pcm_hw_params,
268
+ .hw_free = pcm_hw_free,
280269 .prepare = pcm_playback_prepare,
281270 .trigger = pcm_playback_trigger,
282271 .pointer = pcm_playback_pointer,
283272 .ack = pcm_playback_ack,
284
- .page = snd_pcm_lib_get_vmalloc_page,
285273 };
286274 struct snd_pcm *pcm;
287275 int err;
....@@ -295,6 +283,7 @@
295283 "%s PCM", tscm->card->shortname);
296284 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
297285 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
286
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
298287
299288 return 0;
300289 }