hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/firewire/digi00x/digi00x-pcm.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * digi00x-pcm.c - a part of driver for Digidesign Digi 002/003 family
34 *
45 * Copyright (c) 2014-2015 Takashi Sakamoto
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include "digi00x.h"
....@@ -101,14 +100,14 @@
101100 static int pcm_open(struct snd_pcm_substream *substream)
102101 {
103102 struct snd_dg00x *dg00x = substream->private_data;
103
+ struct amdtp_domain *d = &dg00x->domain;
104104 enum snd_dg00x_clock clock;
105105 bool detect;
106
- unsigned int rate;
107106 int err;
108107
109108 err = snd_dg00x_stream_lock_try(dg00x);
110109 if (err < 0)
111
- goto end;
110
+ return err;
112111
113112 err = pcm_init_hw_params(dg00x, substream);
114113 if (err < 0)
....@@ -128,19 +127,49 @@
128127 }
129128 }
130129
130
+ mutex_lock(&dg00x->mutex);
131
+
132
+ // When source of clock is not internal or any stream is reserved for
133
+ // transmission of PCM frames, the available sampling rate is limited
134
+ // at current one.
131135 if ((clock != SND_DG00X_CLOCK_INTERNAL) ||
132
- amdtp_stream_pcm_running(&dg00x->rx_stream) ||
133
- amdtp_stream_pcm_running(&dg00x->tx_stream)) {
136
+ (dg00x->substreams_counter > 0 && d->events_per_period > 0)) {
137
+ unsigned int frames_per_period = d->events_per_period;
138
+ unsigned int frames_per_buffer = d->events_per_buffer;
139
+ unsigned int rate;
140
+
134141 err = snd_dg00x_stream_get_external_rate(dg00x, &rate);
135
- if (err < 0)
142
+ if (err < 0) {
143
+ mutex_unlock(&dg00x->mutex);
136144 goto err_locked;
145
+ }
137146 substream->runtime->hw.rate_min = rate;
138147 substream->runtime->hw.rate_max = rate;
148
+
149
+ if (frames_per_period > 0) {
150
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
151
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
152
+ frames_per_period, frames_per_period);
153
+ if (err < 0) {
154
+ mutex_unlock(&dg00x->mutex);
155
+ goto err_locked;
156
+ }
157
+
158
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
159
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
160
+ frames_per_buffer, frames_per_buffer);
161
+ if (err < 0) {
162
+ mutex_unlock(&dg00x->mutex);
163
+ goto err_locked;
164
+ }
165
+ }
139166 }
140167
168
+ mutex_unlock(&dg00x->mutex);
169
+
141170 snd_pcm_set_sync(substream);
142
-end:
143
- return err;
171
+
172
+ return 0;
144173 err_locked:
145174 snd_dg00x_stream_lock_release(dg00x);
146175 return err;
....@@ -155,87 +184,52 @@
155184 return 0;
156185 }
157186
158
-static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
159
- struct snd_pcm_hw_params *hw_params)
187
+static int pcm_hw_params(struct snd_pcm_substream *substream,
188
+ struct snd_pcm_hw_params *hw_params)
160189 {
161190 struct snd_dg00x *dg00x = substream->private_data;
162
- int err;
163
-
164
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
165
- params_buffer_bytes(hw_params));
166
- if (err < 0)
167
- return err;
191
+ int err = 0;
168192
169193 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
194
+ unsigned int rate = params_rate(hw_params);
195
+ unsigned int frames_per_period = params_period_size(hw_params);
196
+ unsigned int frames_per_buffer = params_buffer_size(hw_params);
197
+
170198 mutex_lock(&dg00x->mutex);
171
- dg00x->substreams_counter++;
199
+ err = snd_dg00x_stream_reserve_duplex(dg00x, rate,
200
+ frames_per_period, frames_per_buffer);
201
+ if (err >= 0)
202
+ ++dg00x->substreams_counter;
172203 mutex_unlock(&dg00x->mutex);
173204 }
174205
175
- return 0;
206
+ return err;
176207 }
177208
178
-static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
179
- struct snd_pcm_hw_params *hw_params)
180
-{
181
- struct snd_dg00x *dg00x = substream->private_data;
182
- int err;
183
-
184
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
185
- params_buffer_bytes(hw_params));
186
- if (err < 0)
187
- return err;
188
-
189
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
190
- mutex_lock(&dg00x->mutex);
191
- dg00x->substreams_counter++;
192
- mutex_unlock(&dg00x->mutex);
193
- }
194
-
195
- return 0;
196
-}
197
-
198
-static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
209
+static int pcm_hw_free(struct snd_pcm_substream *substream)
199210 {
200211 struct snd_dg00x *dg00x = substream->private_data;
201212
202213 mutex_lock(&dg00x->mutex);
203214
204215 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
205
- dg00x->substreams_counter--;
216
+ --dg00x->substreams_counter;
206217
207218 snd_dg00x_stream_stop_duplex(dg00x);
208219
209220 mutex_unlock(&dg00x->mutex);
210221
211
- return snd_pcm_lib_free_vmalloc_buffer(substream);
212
-}
213
-
214
-static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
215
-{
216
- struct snd_dg00x *dg00x = substream->private_data;
217
-
218
- mutex_lock(&dg00x->mutex);
219
-
220
- if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
221
- dg00x->substreams_counter--;
222
-
223
- snd_dg00x_stream_stop_duplex(dg00x);
224
-
225
- mutex_unlock(&dg00x->mutex);
226
-
227
- return snd_pcm_lib_free_vmalloc_buffer(substream);
222
+ return 0;
228223 }
229224
230225 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
231226 {
232227 struct snd_dg00x *dg00x = substream->private_data;
233
- struct snd_pcm_runtime *runtime = substream->runtime;
234228 int err;
235229
236230 mutex_lock(&dg00x->mutex);
237231
238
- err = snd_dg00x_stream_start_duplex(dg00x, runtime->rate);
232
+ err = snd_dg00x_stream_start_duplex(dg00x);
239233 if (err >= 0)
240234 amdtp_stream_pcm_prepare(&dg00x->tx_stream);
241235
....@@ -247,12 +241,11 @@
247241 static int pcm_playback_prepare(struct snd_pcm_substream *substream)
248242 {
249243 struct snd_dg00x *dg00x = substream->private_data;
250
- struct snd_pcm_runtime *runtime = substream->runtime;
251244 int err;
252245
253246 mutex_lock(&dg00x->mutex);
254247
255
- err = snd_dg00x_stream_start_duplex(dg00x, runtime->rate);
248
+ err = snd_dg00x_stream_start_duplex(dg00x);
256249 if (err >= 0) {
257250 amdtp_stream_pcm_prepare(&dg00x->rx_stream);
258251 amdtp_dot_reset(&dg00x->rx_stream);
....@@ -303,28 +296,28 @@
303296 {
304297 struct snd_dg00x *dg00x = sbstrm->private_data;
305298
306
- return amdtp_stream_pcm_pointer(&dg00x->tx_stream);
299
+ return amdtp_domain_stream_pcm_pointer(&dg00x->domain, &dg00x->tx_stream);
307300 }
308301
309302 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
310303 {
311304 struct snd_dg00x *dg00x = sbstrm->private_data;
312305
313
- return amdtp_stream_pcm_pointer(&dg00x->rx_stream);
306
+ return amdtp_domain_stream_pcm_pointer(&dg00x->domain, &dg00x->rx_stream);
314307 }
315308
316309 static int pcm_capture_ack(struct snd_pcm_substream *substream)
317310 {
318311 struct snd_dg00x *dg00x = substream->private_data;
319312
320
- return amdtp_stream_pcm_ack(&dg00x->tx_stream);
313
+ return amdtp_domain_stream_pcm_ack(&dg00x->domain, &dg00x->tx_stream);
321314 }
322315
323316 static int pcm_playback_ack(struct snd_pcm_substream *substream)
324317 {
325318 struct snd_dg00x *dg00x = substream->private_data;
326319
327
- return amdtp_stream_pcm_ack(&dg00x->rx_stream);
320
+ return amdtp_domain_stream_pcm_ack(&dg00x->domain, &dg00x->rx_stream);
328321 }
329322
330323 int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x)
....@@ -332,26 +325,22 @@
332325 static const struct snd_pcm_ops capture_ops = {
333326 .open = pcm_open,
334327 .close = pcm_close,
335
- .ioctl = snd_pcm_lib_ioctl,
336
- .hw_params = pcm_capture_hw_params,
337
- .hw_free = pcm_capture_hw_free,
328
+ .hw_params = pcm_hw_params,
329
+ .hw_free = pcm_hw_free,
338330 .prepare = pcm_capture_prepare,
339331 .trigger = pcm_capture_trigger,
340332 .pointer = pcm_capture_pointer,
341333 .ack = pcm_capture_ack,
342
- .page = snd_pcm_lib_get_vmalloc_page,
343334 };
344335 static const struct snd_pcm_ops playback_ops = {
345336 .open = pcm_open,
346337 .close = pcm_close,
347
- .ioctl = snd_pcm_lib_ioctl,
348
- .hw_params = pcm_playback_hw_params,
349
- .hw_free = pcm_playback_hw_free,
338
+ .hw_params = pcm_hw_params,
339
+ .hw_free = pcm_hw_free,
350340 .prepare = pcm_playback_prepare,
351341 .trigger = pcm_playback_trigger,
352342 .pointer = pcm_playback_pointer,
353343 .ack = pcm_playback_ack,
354
- .page = snd_pcm_lib_get_vmalloc_page,
355344 };
356345 struct snd_pcm *pcm;
357346 int err;
....@@ -365,6 +354,7 @@
365354 "%s PCM", dg00x->card->shortname);
366355 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
367356 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
357
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
368358
369359 return 0;
370360 }