2 * motu-pcm.c - a part of driver for MOTU FireWire series
4 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 * Licensed under the terms of the GNU General Public License, version 2.
9 #include <sound/pcm_params.h>
12 static int motu_rate_constraint(struct snd_pcm_hw_params *params,
13 struct snd_pcm_hw_rule *rule)
15 struct snd_motu_packet_format *formats = rule->private;
17 const struct snd_interval *c =
18 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
19 struct snd_interval *r =
20 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
21 struct snd_interval rates = {
22 .min = UINT_MAX, .max = 0, .integer = 1
24 unsigned int i, pcm_channels, rate, mode;
26 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
27 rate = snd_motu_clock_rates[i];
30 pcm_channels = formats->fixed_part_pcm_chunks[mode] +
31 formats->differed_part_pcm_chunks[mode];
32 if (!snd_interval_test(c, pcm_channels))
35 rates.min = min(rates.min, rate);
36 rates.max = max(rates.max, rate);
39 return snd_interval_refine(r, &rates);
42 static int motu_channels_constraint(struct snd_pcm_hw_params *params,
43 struct snd_pcm_hw_rule *rule)
45 struct snd_motu_packet_format *formats = rule->private;
47 const struct snd_interval *r =
48 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
49 struct snd_interval *c =
50 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
51 struct snd_interval channels = {
52 .min = UINT_MAX, .max = 0, .integer = 1
54 unsigned int i, pcm_channels, rate, mode;
56 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
57 rate = snd_motu_clock_rates[i];
60 if (!snd_interval_test(r, rate))
63 pcm_channels = formats->fixed_part_pcm_chunks[mode] +
64 formats->differed_part_pcm_chunks[mode];
65 channels.min = min(channels.min, pcm_channels);
66 channels.max = max(channels.max, pcm_channels);
69 return snd_interval_refine(c, &channels);
72 static void limit_channels_and_rates(struct snd_motu *motu,
73 struct snd_pcm_runtime *runtime,
74 struct snd_motu_packet_format *formats)
76 struct snd_pcm_hardware *hw = &runtime->hw;
77 unsigned int i, pcm_channels, rate, mode;
79 hw->channels_min = UINT_MAX;
82 for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
83 rate = snd_motu_clock_rates[i];
86 pcm_channels = formats->fixed_part_pcm_chunks[mode] +
87 formats->differed_part_pcm_chunks[mode];
88 if (pcm_channels == 0)
91 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
92 hw->channels_min = min(hw->channels_min, pcm_channels);
93 hw->channels_max = max(hw->channels_max, pcm_channels);
96 snd_pcm_limit_hw_rates(runtime);
99 static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
101 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */
102 hw->periods_max = UINT_MAX;
104 hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */
106 /* Just to prevent from allocating much pages. */
107 hw->period_bytes_max = hw->period_bytes_min * 2048;
108 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
111 static int init_hw_info(struct snd_motu *motu,
112 struct snd_pcm_substream *substream)
114 struct snd_pcm_runtime *runtime = substream->runtime;
115 struct snd_pcm_hardware *hw = &runtime->hw;
116 struct amdtp_stream *stream;
117 struct snd_motu_packet_format *formats;
120 hw->info = SNDRV_PCM_INFO_MMAP |
121 SNDRV_PCM_INFO_MMAP_VALID |
122 SNDRV_PCM_INFO_BATCH |
123 SNDRV_PCM_INFO_INTERLEAVED |
124 SNDRV_PCM_INFO_JOINT_DUPLEX |
125 SNDRV_PCM_INFO_BLOCK_TRANSFER;
127 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
128 hw->formats = SNDRV_PCM_FMTBIT_S32;
129 stream = &motu->tx_stream;
130 formats = &motu->tx_packet_formats;
132 hw->formats = SNDRV_PCM_FMTBIT_S32;
133 stream = &motu->rx_stream;
134 formats = &motu->rx_packet_formats;
137 limit_channels_and_rates(motu, runtime, formats);
138 limit_period_and_buffer(hw);
140 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
141 motu_rate_constraint, formats,
142 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
145 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
146 motu_channels_constraint, formats,
147 SNDRV_PCM_HW_PARAM_RATE, -1);
151 return amdtp_motu_add_pcm_hw_constraints(stream, runtime);
154 static int pcm_open(struct snd_pcm_substream *substream)
156 struct snd_motu *motu = substream->private_data;
157 const struct snd_motu_protocol *const protocol = motu->spec->protocol;
158 enum snd_motu_clock_source src;
162 err = snd_motu_stream_lock_try(motu);
166 mutex_lock(&motu->mutex);
168 err = protocol->cache_packet_formats(motu);
172 err = init_hw_info(motu, substream);
177 * When source of clock is not internal or any PCM streams are running,
178 * available sampling rate is limited at current sampling rate.
180 err = protocol->get_clock_source(motu, &src);
183 if (src != SND_MOTU_CLOCK_SOURCE_INTERNAL ||
184 amdtp_stream_pcm_running(&motu->tx_stream) ||
185 amdtp_stream_pcm_running(&motu->rx_stream)) {
186 err = protocol->get_clock_rate(motu, &rate);
189 substream->runtime->hw.rate_min = rate;
190 substream->runtime->hw.rate_max = rate;
193 snd_pcm_set_sync(substream);
195 mutex_unlock(&motu->mutex);
199 mutex_unlock(&motu->mutex);
200 snd_motu_stream_lock_release(motu);
204 static int pcm_close(struct snd_pcm_substream *substream)
206 struct snd_motu *motu = substream->private_data;
208 snd_motu_stream_lock_release(motu);
213 static int capture_hw_params(struct snd_pcm_substream *substream,
214 struct snd_pcm_hw_params *hw_params)
216 struct snd_motu *motu = substream->private_data;
219 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
220 params_buffer_bytes(hw_params));
224 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
225 mutex_lock(&motu->mutex);
226 motu->capture_substreams++;
227 mutex_unlock(&motu->mutex);
232 static int playback_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *hw_params)
235 struct snd_motu *motu = substream->private_data;
238 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
239 params_buffer_bytes(hw_params));
243 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
244 mutex_lock(&motu->mutex);
245 motu->playback_substreams++;
246 mutex_unlock(&motu->mutex);
252 static int capture_hw_free(struct snd_pcm_substream *substream)
254 struct snd_motu *motu = substream->private_data;
256 mutex_lock(&motu->mutex);
258 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
259 motu->capture_substreams--;
261 snd_motu_stream_stop_duplex(motu);
263 mutex_unlock(&motu->mutex);
265 return snd_pcm_lib_free_vmalloc_buffer(substream);
268 static int playback_hw_free(struct snd_pcm_substream *substream)
270 struct snd_motu *motu = substream->private_data;
272 mutex_lock(&motu->mutex);
274 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
275 motu->playback_substreams--;
277 snd_motu_stream_stop_duplex(motu);
279 mutex_unlock(&motu->mutex);
281 return snd_pcm_lib_free_vmalloc_buffer(substream);
284 static int capture_prepare(struct snd_pcm_substream *substream)
286 struct snd_motu *motu = substream->private_data;
289 mutex_lock(&motu->mutex);
290 err = snd_motu_stream_start_duplex(motu, substream->runtime->rate);
291 mutex_unlock(&motu->mutex);
293 amdtp_stream_pcm_prepare(&motu->tx_stream);
297 static int playback_prepare(struct snd_pcm_substream *substream)
299 struct snd_motu *motu = substream->private_data;
302 mutex_lock(&motu->mutex);
303 err = snd_motu_stream_start_duplex(motu, substream->runtime->rate);
304 mutex_unlock(&motu->mutex);
306 amdtp_stream_pcm_prepare(&motu->rx_stream);
311 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
313 struct snd_motu *motu = substream->private_data;
316 case SNDRV_PCM_TRIGGER_START:
317 amdtp_stream_pcm_trigger(&motu->tx_stream, substream);
319 case SNDRV_PCM_TRIGGER_STOP:
320 amdtp_stream_pcm_trigger(&motu->tx_stream, NULL);
328 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
330 struct snd_motu *motu = substream->private_data;
333 case SNDRV_PCM_TRIGGER_START:
334 amdtp_stream_pcm_trigger(&motu->rx_stream, substream);
336 case SNDRV_PCM_TRIGGER_STOP:
337 amdtp_stream_pcm_trigger(&motu->rx_stream, NULL);
346 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
348 struct snd_motu *motu = substream->private_data;
350 return amdtp_stream_pcm_pointer(&motu->tx_stream);
352 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
354 struct snd_motu *motu = substream->private_data;
356 return amdtp_stream_pcm_pointer(&motu->rx_stream);
359 int snd_motu_create_pcm_devices(struct snd_motu *motu)
361 static struct snd_pcm_ops capture_ops = {
364 .ioctl = snd_pcm_lib_ioctl,
365 .hw_params = capture_hw_params,
366 .hw_free = capture_hw_free,
367 .prepare = capture_prepare,
368 .trigger = capture_trigger,
369 .pointer = capture_pointer,
370 .page = snd_pcm_lib_get_vmalloc_page,
371 .mmap = snd_pcm_lib_mmap_vmalloc,
373 static struct snd_pcm_ops playback_ops = {
376 .ioctl = snd_pcm_lib_ioctl,
377 .hw_params = playback_hw_params,
378 .hw_free = playback_hw_free,
379 .prepare = playback_prepare,
380 .trigger = playback_trigger,
381 .pointer = playback_pointer,
382 .page = snd_pcm_lib_get_vmalloc_page,
383 .mmap = snd_pcm_lib_mmap_vmalloc,
388 err = snd_pcm_new(motu->card, motu->card->driver, 0, 1, 1, &pcm);
391 pcm->private_data = motu;
392 strcpy(pcm->name, motu->card->shortname);
394 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
395 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);