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