1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * dice_pcm.c - a part of driver for DICE based devices
4 *
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
7 */
8
9 #include "dice.h"
10
dice_rate_constraint(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)11 static int dice_rate_constraint(struct snd_pcm_hw_params *params,
12 struct snd_pcm_hw_rule *rule)
13 {
14 struct snd_pcm_substream *substream = rule->private;
15 struct snd_dice *dice = substream->private_data;
16 unsigned int index = substream->pcm->device;
17
18 const struct snd_interval *c =
19 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
20 struct snd_interval *r =
21 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
22 struct snd_interval rates = {
23 .min = UINT_MAX, .max = 0, .integer = 1
24 };
25 unsigned int *pcm_channels;
26 enum snd_dice_rate_mode mode;
27 unsigned int i, rate;
28
29 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
30 pcm_channels = dice->tx_pcm_chs[index];
31 else
32 pcm_channels = dice->rx_pcm_chs[index];
33
34 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
35 rate = snd_dice_rates[i];
36 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
37 continue;
38
39 if (!snd_interval_test(c, pcm_channels[mode]))
40 continue;
41
42 rates.min = min(rates.min, rate);
43 rates.max = max(rates.max, rate);
44 }
45
46 return snd_interval_refine(r, &rates);
47 }
48
dice_channels_constraint(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)49 static int dice_channels_constraint(struct snd_pcm_hw_params *params,
50 struct snd_pcm_hw_rule *rule)
51 {
52 struct snd_pcm_substream *substream = rule->private;
53 struct snd_dice *dice = substream->private_data;
54 unsigned int index = substream->pcm->device;
55
56 const struct snd_interval *r =
57 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
58 struct snd_interval *c =
59 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
60 struct snd_interval channels = {
61 .min = UINT_MAX, .max = 0, .integer = 1
62 };
63 unsigned int *pcm_channels;
64 enum snd_dice_rate_mode mode;
65 unsigned int i, rate;
66
67 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
68 pcm_channels = dice->tx_pcm_chs[index];
69 else
70 pcm_channels = dice->rx_pcm_chs[index];
71
72 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
73 rate = snd_dice_rates[i];
74 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
75 continue;
76
77 if (!snd_interval_test(r, rate))
78 continue;
79
80 channels.min = min(channels.min, pcm_channels[mode]);
81 channels.max = max(channels.max, pcm_channels[mode]);
82 }
83
84 return snd_interval_refine(c, &channels);
85 }
86
limit_channels_and_rates(struct snd_dice * dice,struct snd_pcm_runtime * runtime,enum amdtp_stream_direction dir,unsigned int index)87 static int limit_channels_and_rates(struct snd_dice *dice,
88 struct snd_pcm_runtime *runtime,
89 enum amdtp_stream_direction dir,
90 unsigned int index)
91 {
92 struct snd_pcm_hardware *hw = &runtime->hw;
93 unsigned int *pcm_channels;
94 unsigned int i;
95
96 if (dir == AMDTP_IN_STREAM)
97 pcm_channels = dice->tx_pcm_chs[index];
98 else
99 pcm_channels = dice->rx_pcm_chs[index];
100
101 hw->channels_min = UINT_MAX;
102 hw->channels_max = 0;
103
104 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
105 enum snd_dice_rate_mode mode;
106 unsigned int rate, channels;
107
108 rate = snd_dice_rates[i];
109 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
110 continue;
111 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
112
113 channels = pcm_channels[mode];
114 if (channels == 0)
115 continue;
116 hw->channels_min = min(hw->channels_min, channels);
117 hw->channels_max = max(hw->channels_max, channels);
118 }
119
120 snd_pcm_limit_hw_rates(runtime);
121
122 return 0;
123 }
124
init_hw_info(struct snd_dice * dice,struct snd_pcm_substream * substream)125 static int init_hw_info(struct snd_dice *dice,
126 struct snd_pcm_substream *substream)
127 {
128 struct snd_pcm_runtime *runtime = substream->runtime;
129 struct snd_pcm_hardware *hw = &runtime->hw;
130 unsigned int index = substream->pcm->device;
131 enum amdtp_stream_direction dir;
132 struct amdtp_stream *stream;
133 int err;
134
135 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
136 hw->formats = AM824_IN_PCM_FORMAT_BITS;
137 dir = AMDTP_IN_STREAM;
138 stream = &dice->tx_stream[index];
139 } else {
140 hw->formats = AM824_OUT_PCM_FORMAT_BITS;
141 dir = AMDTP_OUT_STREAM;
142 stream = &dice->rx_stream[index];
143 }
144
145 err = limit_channels_and_rates(dice, substream->runtime, dir,
146 index);
147 if (err < 0)
148 return err;
149
150 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
151 dice_rate_constraint, substream,
152 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
153 if (err < 0)
154 return err;
155 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
156 dice_channels_constraint, substream,
157 SNDRV_PCM_HW_PARAM_RATE, -1);
158 if (err < 0)
159 return err;
160
161 return amdtp_am824_add_pcm_hw_constraints(stream, runtime);
162 }
163
pcm_open(struct snd_pcm_substream * substream)164 static int pcm_open(struct snd_pcm_substream *substream)
165 {
166 struct snd_dice *dice = substream->private_data;
167 struct amdtp_domain *d = &dice->domain;
168 unsigned int source;
169 bool internal;
170 int err;
171
172 err = snd_dice_stream_lock_try(dice);
173 if (err < 0)
174 return err;
175
176 err = init_hw_info(dice, substream);
177 if (err < 0)
178 goto err_locked;
179
180 err = snd_dice_transaction_get_clock_source(dice, &source);
181 if (err < 0)
182 goto err_locked;
183 switch (source) {
184 case CLOCK_SOURCE_AES1:
185 case CLOCK_SOURCE_AES2:
186 case CLOCK_SOURCE_AES3:
187 case CLOCK_SOURCE_AES4:
188 case CLOCK_SOURCE_AES_ANY:
189 case CLOCK_SOURCE_ADAT:
190 case CLOCK_SOURCE_TDIF:
191 case CLOCK_SOURCE_WC:
192 internal = false;
193 break;
194 default:
195 internal = true;
196 break;
197 }
198
199 mutex_lock(&dice->mutex);
200
201 // When source of clock is not internal or any stream is reserved for
202 // transmission of PCM frames, the available sampling rate is limited
203 // at current one.
204 if (!internal ||
205 (dice->substreams_counter > 0 && d->events_per_period > 0)) {
206 unsigned int frames_per_period = d->events_per_period;
207 unsigned int frames_per_buffer = d->events_per_buffer;
208 unsigned int rate;
209
210 err = snd_dice_transaction_get_rate(dice, &rate);
211 if (err < 0) {
212 mutex_unlock(&dice->mutex);
213 goto err_locked;
214 }
215
216 substream->runtime->hw.rate_min = rate;
217 substream->runtime->hw.rate_max = rate;
218
219 if (frames_per_period > 0) {
220 // For double_pcm_frame quirk.
221 if (rate > 96000 && !dice->disable_double_pcm_frames) {
222 frames_per_period *= 2;
223 frames_per_buffer *= 2;
224 }
225
226 err = snd_pcm_hw_constraint_minmax(substream->runtime,
227 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
228 frames_per_period, frames_per_period);
229 if (err < 0) {
230 mutex_unlock(&dice->mutex);
231 goto err_locked;
232 }
233
234 err = snd_pcm_hw_constraint_minmax(substream->runtime,
235 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
236 frames_per_buffer, frames_per_buffer);
237 if (err < 0) {
238 mutex_unlock(&dice->mutex);
239 goto err_locked;
240 }
241 }
242 }
243
244 mutex_unlock(&dice->mutex);
245
246 snd_pcm_set_sync(substream);
247
248 return 0;
249 err_locked:
250 snd_dice_stream_lock_release(dice);
251 return err;
252 }
253
pcm_close(struct snd_pcm_substream * substream)254 static int pcm_close(struct snd_pcm_substream *substream)
255 {
256 struct snd_dice *dice = substream->private_data;
257
258 snd_dice_stream_lock_release(dice);
259
260 return 0;
261 }
262
pcm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)263 static int pcm_hw_params(struct snd_pcm_substream *substream,
264 struct snd_pcm_hw_params *hw_params)
265 {
266 struct snd_dice *dice = substream->private_data;
267 int err = 0;
268
269 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
270 unsigned int rate = params_rate(hw_params);
271 unsigned int events_per_period = params_period_size(hw_params);
272 unsigned int events_per_buffer = params_buffer_size(hw_params);
273
274 mutex_lock(&dice->mutex);
275 // For double_pcm_frame quirk.
276 if (rate > 96000 && !dice->disable_double_pcm_frames) {
277 events_per_period /= 2;
278 events_per_buffer /= 2;
279 }
280 err = snd_dice_stream_reserve_duplex(dice, rate,
281 events_per_period, events_per_buffer);
282 if (err >= 0)
283 ++dice->substreams_counter;
284 mutex_unlock(&dice->mutex);
285 }
286
287 return err;
288 }
289
pcm_hw_free(struct snd_pcm_substream * substream)290 static int pcm_hw_free(struct snd_pcm_substream *substream)
291 {
292 struct snd_dice *dice = substream->private_data;
293
294 mutex_lock(&dice->mutex);
295
296 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
297 --dice->substreams_counter;
298
299 snd_dice_stream_stop_duplex(dice);
300
301 mutex_unlock(&dice->mutex);
302
303 return 0;
304 }
305
capture_prepare(struct snd_pcm_substream * substream)306 static int capture_prepare(struct snd_pcm_substream *substream)
307 {
308 struct snd_dice *dice = substream->private_data;
309 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
310 int err;
311
312 mutex_lock(&dice->mutex);
313 err = snd_dice_stream_start_duplex(dice);
314 mutex_unlock(&dice->mutex);
315 if (err >= 0)
316 amdtp_stream_pcm_prepare(stream);
317
318 return 0;
319 }
playback_prepare(struct snd_pcm_substream * substream)320 static int playback_prepare(struct snd_pcm_substream *substream)
321 {
322 struct snd_dice *dice = substream->private_data;
323 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
324 int err;
325
326 mutex_lock(&dice->mutex);
327 err = snd_dice_stream_start_duplex(dice);
328 mutex_unlock(&dice->mutex);
329 if (err >= 0)
330 amdtp_stream_pcm_prepare(stream);
331
332 return err;
333 }
334
capture_trigger(struct snd_pcm_substream * substream,int cmd)335 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
336 {
337 struct snd_dice *dice = substream->private_data;
338 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
339
340 switch (cmd) {
341 case SNDRV_PCM_TRIGGER_START:
342 amdtp_stream_pcm_trigger(stream, substream);
343 break;
344 case SNDRV_PCM_TRIGGER_STOP:
345 amdtp_stream_pcm_trigger(stream, NULL);
346 break;
347 default:
348 return -EINVAL;
349 }
350
351 return 0;
352 }
playback_trigger(struct snd_pcm_substream * substream,int cmd)353 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
354 {
355 struct snd_dice *dice = substream->private_data;
356 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
357
358 switch (cmd) {
359 case SNDRV_PCM_TRIGGER_START:
360 amdtp_stream_pcm_trigger(stream, substream);
361 break;
362 case SNDRV_PCM_TRIGGER_STOP:
363 amdtp_stream_pcm_trigger(stream, NULL);
364 break;
365 default:
366 return -EINVAL;
367 }
368
369 return 0;
370 }
371
capture_pointer(struct snd_pcm_substream * substream)372 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
373 {
374 struct snd_dice *dice = substream->private_data;
375 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
376
377 return amdtp_domain_stream_pcm_pointer(&dice->domain, stream);
378 }
playback_pointer(struct snd_pcm_substream * substream)379 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
380 {
381 struct snd_dice *dice = substream->private_data;
382 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
383
384 return amdtp_domain_stream_pcm_pointer(&dice->domain, stream);
385 }
386
capture_ack(struct snd_pcm_substream * substream)387 static int capture_ack(struct snd_pcm_substream *substream)
388 {
389 struct snd_dice *dice = substream->private_data;
390 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
391
392 return amdtp_domain_stream_pcm_ack(&dice->domain, stream);
393 }
394
playback_ack(struct snd_pcm_substream * substream)395 static int playback_ack(struct snd_pcm_substream *substream)
396 {
397 struct snd_dice *dice = substream->private_data;
398 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
399
400 return amdtp_domain_stream_pcm_ack(&dice->domain, stream);
401 }
402
snd_dice_create_pcm(struct snd_dice * dice)403 int snd_dice_create_pcm(struct snd_dice *dice)
404 {
405 static const struct snd_pcm_ops capture_ops = {
406 .open = pcm_open,
407 .close = pcm_close,
408 .hw_params = pcm_hw_params,
409 .hw_free = pcm_hw_free,
410 .prepare = capture_prepare,
411 .trigger = capture_trigger,
412 .pointer = capture_pointer,
413 .ack = capture_ack,
414 };
415 static const struct snd_pcm_ops playback_ops = {
416 .open = pcm_open,
417 .close = pcm_close,
418 .hw_params = pcm_hw_params,
419 .hw_free = pcm_hw_free,
420 .prepare = playback_prepare,
421 .trigger = playback_trigger,
422 .pointer = playback_pointer,
423 .ack = playback_ack,
424 };
425 struct snd_pcm *pcm;
426 unsigned int capture, playback;
427 int i, j;
428 int err;
429
430 for (i = 0; i < MAX_STREAMS; i++) {
431 capture = playback = 0;
432 for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) {
433 if (dice->tx_pcm_chs[i][j] > 0)
434 capture = 1;
435 if (dice->rx_pcm_chs[i][j] > 0)
436 playback = 1;
437 }
438
439 err = snd_pcm_new(dice->card, "DICE", i, playback, capture,
440 &pcm);
441 if (err < 0)
442 return err;
443 pcm->private_data = dice;
444 strcpy(pcm->name, dice->card->shortname);
445
446 if (capture > 0)
447 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
448 &capture_ops);
449
450 if (playback > 0)
451 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
452 &playback_ops);
453
454 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
455 NULL, 0, 0);
456 }
457
458 return 0;
459 }
460