1 // SPDX-License-Identifier: GPL-2.0-only
3 * dice_pcm.c - a part of driver for DICE based devices
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
11 static int dice_rate_constraint(struct snd_pcm_hw_params *params,
12 struct snd_pcm_hw_rule *rule)
14 struct snd_pcm_substream *substream = rule->private;
15 struct snd_dice *dice = substream->private_data;
16 unsigned int index = substream->pcm->device;
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
25 unsigned int *pcm_channels;
26 enum snd_dice_rate_mode mode;
29 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
30 pcm_channels = dice->tx_pcm_chs[index];
32 pcm_channels = dice->rx_pcm_chs[index];
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)
39 if (!snd_interval_test(c, pcm_channels[mode]))
42 rates.min = min(rates.min, rate);
43 rates.max = max(rates.max, rate);
46 return snd_interval_refine(r, &rates);
49 static int dice_channels_constraint(struct snd_pcm_hw_params *params,
50 struct snd_pcm_hw_rule *rule)
52 struct snd_pcm_substream *substream = rule->private;
53 struct snd_dice *dice = substream->private_data;
54 unsigned int index = substream->pcm->device;
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
63 unsigned int *pcm_channels;
64 enum snd_dice_rate_mode mode;
67 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
68 pcm_channels = dice->tx_pcm_chs[index];
70 pcm_channels = dice->rx_pcm_chs[index];
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)
77 if (!snd_interval_test(r, rate))
80 channels.min = min(channels.min, pcm_channels[mode]);
81 channels.max = max(channels.max, pcm_channels[mode]);
84 return snd_interval_refine(c, &channels);
87 static int limit_channels_and_rates(struct snd_dice *dice,
88 struct snd_pcm_runtime *runtime,
89 enum amdtp_stream_direction dir,
92 struct snd_pcm_hardware *hw = &runtime->hw;
93 unsigned int *pcm_channels;
96 if (dir == AMDTP_IN_STREAM)
97 pcm_channels = dice->tx_pcm_chs[index];
99 pcm_channels = dice->rx_pcm_chs[index];
101 hw->channels_min = UINT_MAX;
102 hw->channels_max = 0;
104 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
105 enum snd_dice_rate_mode mode;
106 unsigned int rate, channels;
108 rate = snd_dice_rates[i];
109 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
111 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
113 channels = pcm_channels[mode];
116 hw->channels_min = min(hw->channels_min, channels);
117 hw->channels_max = max(hw->channels_max, channels);
120 snd_pcm_limit_hw_rates(runtime);
125 static int init_hw_info(struct snd_dice *dice,
126 struct snd_pcm_substream *substream)
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;
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];
140 hw->formats = AM824_OUT_PCM_FORMAT_BITS;
141 dir = AMDTP_OUT_STREAM;
142 stream = &dice->rx_stream[index];
145 err = limit_channels_and_rates(dice, substream->runtime, dir,
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);
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);
161 return amdtp_am824_add_pcm_hw_constraints(stream, runtime);
164 static int pcm_open(struct snd_pcm_substream *substream)
166 struct snd_dice *dice = substream->private_data;
171 err = snd_dice_stream_lock_try(dice);
175 err = init_hw_info(dice, substream);
179 err = snd_dice_transaction_get_clock_source(dice, &source);
183 case CLOCK_SOURCE_AES1:
184 case CLOCK_SOURCE_AES2:
185 case CLOCK_SOURCE_AES3:
186 case CLOCK_SOURCE_AES4:
187 case CLOCK_SOURCE_AES_ANY:
188 case CLOCK_SOURCE_ADAT:
189 case CLOCK_SOURCE_TDIF:
190 case CLOCK_SOURCE_WC:
199 * When source of clock is not internal or any PCM streams are running,
200 * available sampling rate is limited at current sampling rate.
203 amdtp_stream_pcm_running(&dice->tx_stream[0]) ||
204 amdtp_stream_pcm_running(&dice->tx_stream[1]) ||
205 amdtp_stream_pcm_running(&dice->rx_stream[0]) ||
206 amdtp_stream_pcm_running(&dice->rx_stream[1])) {
209 err = snd_dice_transaction_get_rate(dice, &rate);
212 substream->runtime->hw.rate_min = rate;
213 substream->runtime->hw.rate_max = rate;
216 snd_pcm_set_sync(substream);
220 snd_dice_stream_lock_release(dice);
224 static int pcm_close(struct snd_pcm_substream *substream)
226 struct snd_dice *dice = substream->private_data;
228 snd_dice_stream_lock_release(dice);
233 static int pcm_hw_params(struct snd_pcm_substream *substream,
234 struct snd_pcm_hw_params *hw_params)
236 struct snd_dice *dice = substream->private_data;
239 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
240 params_buffer_bytes(hw_params));
244 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
245 unsigned int rate = params_rate(hw_params);
247 mutex_lock(&dice->mutex);
248 err = snd_dice_stream_reserve_duplex(dice, rate);
250 ++dice->substreams_counter;
251 mutex_unlock(&dice->mutex);
257 static int pcm_hw_free(struct snd_pcm_substream *substream)
259 struct snd_dice *dice = substream->private_data;
261 mutex_lock(&dice->mutex);
263 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
264 --dice->substreams_counter;
266 snd_dice_stream_stop_duplex(dice);
268 mutex_unlock(&dice->mutex);
270 return snd_pcm_lib_free_vmalloc_buffer(substream);
273 static int capture_prepare(struct snd_pcm_substream *substream)
275 struct snd_dice *dice = substream->private_data;
276 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
279 mutex_lock(&dice->mutex);
280 err = snd_dice_stream_start_duplex(dice);
281 mutex_unlock(&dice->mutex);
283 amdtp_stream_pcm_prepare(stream);
287 static int playback_prepare(struct snd_pcm_substream *substream)
289 struct snd_dice *dice = substream->private_data;
290 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
293 mutex_lock(&dice->mutex);
294 err = snd_dice_stream_start_duplex(dice);
295 mutex_unlock(&dice->mutex);
297 amdtp_stream_pcm_prepare(stream);
302 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
304 struct snd_dice *dice = substream->private_data;
305 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
308 case SNDRV_PCM_TRIGGER_START:
309 amdtp_stream_pcm_trigger(stream, substream);
311 case SNDRV_PCM_TRIGGER_STOP:
312 amdtp_stream_pcm_trigger(stream, NULL);
320 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
322 struct snd_dice *dice = substream->private_data;
323 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
326 case SNDRV_PCM_TRIGGER_START:
327 amdtp_stream_pcm_trigger(stream, substream);
329 case SNDRV_PCM_TRIGGER_STOP:
330 amdtp_stream_pcm_trigger(stream, NULL);
339 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
341 struct snd_dice *dice = substream->private_data;
342 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
344 return amdtp_stream_pcm_pointer(stream);
346 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
348 struct snd_dice *dice = substream->private_data;
349 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
351 return amdtp_stream_pcm_pointer(stream);
354 static int capture_ack(struct snd_pcm_substream *substream)
356 struct snd_dice *dice = substream->private_data;
357 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
359 return amdtp_stream_pcm_ack(stream);
362 static int playback_ack(struct snd_pcm_substream *substream)
364 struct snd_dice *dice = substream->private_data;
365 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
367 return amdtp_stream_pcm_ack(stream);
370 int snd_dice_create_pcm(struct snd_dice *dice)
372 static const struct snd_pcm_ops capture_ops = {
375 .ioctl = snd_pcm_lib_ioctl,
376 .hw_params = pcm_hw_params,
377 .hw_free = pcm_hw_free,
378 .prepare = capture_prepare,
379 .trigger = capture_trigger,
380 .pointer = capture_pointer,
382 .page = snd_pcm_lib_get_vmalloc_page,
384 static const struct snd_pcm_ops playback_ops = {
387 .ioctl = snd_pcm_lib_ioctl,
388 .hw_params = pcm_hw_params,
389 .hw_free = pcm_hw_free,
390 .prepare = playback_prepare,
391 .trigger = playback_trigger,
392 .pointer = playback_pointer,
394 .page = snd_pcm_lib_get_vmalloc_page,
397 unsigned int capture, playback;
401 for (i = 0; i < MAX_STREAMS; i++) {
402 capture = playback = 0;
403 for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) {
404 if (dice->tx_pcm_chs[i][j] > 0)
406 if (dice->rx_pcm_chs[i][j] > 0)
410 err = snd_pcm_new(dice->card, "DICE", i, playback, capture,
414 pcm->private_data = dice;
415 strcpy(pcm->name, dice->card->shortname);
418 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
422 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,