xref: /linux/sound/firewire/motu/motu-pcm.c (revision e58e871becec2d3b04ed91c0c16fe8deac9c9dfa)
1 /*
2  * motu-pcm.c - a part of driver for MOTU FireWire series
3  *
4  * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5  *
6  * Licensed under the terms of the GNU General Public License, version 2.
7  */
8 
9 #include <sound/pcm_params.h>
10 #include "motu.h"
11 
12 static int motu_rate_constraint(struct snd_pcm_hw_params *params,
13 				struct snd_pcm_hw_rule *rule)
14 {
15 	struct snd_motu_packet_format *formats = rule->private;
16 
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
23 	};
24 	unsigned int i, pcm_channels, rate, mode;
25 
26 	for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
27 		rate = snd_motu_clock_rates[i];
28 		mode = i / 2;
29 
30 		pcm_channels = formats->fixed_part_pcm_chunks[mode] +
31 			       formats->differed_part_pcm_chunks[mode];
32 		if (!snd_interval_test(c, pcm_channels))
33 			continue;
34 
35 		rates.min = min(rates.min, rate);
36 		rates.max = max(rates.max, rate);
37 	}
38 
39 	return snd_interval_refine(r, &rates);
40 }
41 
42 static int motu_channels_constraint(struct snd_pcm_hw_params *params,
43 				    struct snd_pcm_hw_rule *rule)
44 {
45 	struct snd_motu_packet_format *formats = rule->private;
46 
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
53 	};
54 	unsigned int i, pcm_channels, rate, mode;
55 
56 	for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
57 		rate = snd_motu_clock_rates[i];
58 		mode = i / 2;
59 
60 		if (!snd_interval_test(r, rate))
61 			continue;
62 
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);
67 	}
68 
69 	return snd_interval_refine(c, &channels);
70 }
71 
72 static void limit_channels_and_rates(struct snd_motu *motu,
73 				     struct snd_pcm_runtime *runtime,
74 				     struct snd_motu_packet_format *formats)
75 {
76 	struct snd_pcm_hardware *hw = &runtime->hw;
77 	unsigned int i, pcm_channels, rate, mode;
78 
79 	hw->channels_min = UINT_MAX;
80 	hw->channels_max = 0;
81 
82 	for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
83 		rate = snd_motu_clock_rates[i];
84 		mode = i / 2;
85 
86 		pcm_channels = formats->fixed_part_pcm_chunks[mode] +
87 			       formats->differed_part_pcm_chunks[mode];
88 		if (pcm_channels == 0)
89 			continue;
90 
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);
94 	}
95 
96 	snd_pcm_limit_hw_rates(runtime);
97 }
98 
99 static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
100 {
101 	hw->periods_min = 2;			/* SNDRV_PCM_INFO_BATCH */
102 	hw->periods_max = UINT_MAX;
103 
104 	hw->period_bytes_min = 4 * hw->channels_max;    /* byte for a frame */
105 
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;
109 }
110 
111 static int init_hw_info(struct snd_motu *motu,
112 			struct snd_pcm_substream *substream)
113 {
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;
118 	int err;
119 
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;
126 
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;
131 	} else {
132 		hw->formats = SNDRV_PCM_FMTBIT_S32;
133 		stream = &motu->rx_stream;
134 		formats = &motu->rx_packet_formats;
135 	}
136 
137 	limit_channels_and_rates(motu, runtime, formats);
138 	limit_period_and_buffer(hw);
139 
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);
143 	if (err < 0)
144 		return err;
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);
148 	if (err < 0)
149 		return err;
150 
151 	return amdtp_motu_add_pcm_hw_constraints(stream, runtime);
152 }
153 
154 static int pcm_open(struct snd_pcm_substream *substream)
155 {
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;
159 	unsigned int rate;
160 	int err;
161 
162 	err = snd_motu_stream_lock_try(motu);
163 	if (err < 0)
164 		return err;
165 
166 	mutex_lock(&motu->mutex);
167 
168 	err = protocol->cache_packet_formats(motu);
169 	if (err < 0)
170 		goto err_locked;
171 
172 	err = init_hw_info(motu, substream);
173 	if (err < 0)
174 		goto err_locked;
175 
176 	/*
177 	 * When source of clock is not internal or any PCM streams are running,
178 	 * available sampling rate is limited at current sampling rate.
179 	 */
180 	err = protocol->get_clock_source(motu, &src);
181 	if (err < 0)
182 		goto err_locked;
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);
187 		if (err < 0)
188 			goto err_locked;
189 		substream->runtime->hw.rate_min = rate;
190 		substream->runtime->hw.rate_max = rate;
191 	}
192 
193 	snd_pcm_set_sync(substream);
194 
195 	mutex_unlock(&motu->mutex);
196 
197 	return err;
198 err_locked:
199 	mutex_unlock(&motu->mutex);
200 	snd_motu_stream_lock_release(motu);
201 	return err;
202 }
203 
204 static int pcm_close(struct snd_pcm_substream *substream)
205 {
206 	struct snd_motu *motu = substream->private_data;
207 
208 	snd_motu_stream_lock_release(motu);
209 
210 	return 0;
211 }
212 
213 static int capture_hw_params(struct snd_pcm_substream *substream,
214 			     struct snd_pcm_hw_params *hw_params)
215 {
216 	struct snd_motu *motu = substream->private_data;
217 	int err;
218 
219 	err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
220 					       params_buffer_bytes(hw_params));
221 	if (err < 0)
222 		return err;
223 
224 	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
225 		mutex_lock(&motu->mutex);
226 		motu->capture_substreams++;
227 		mutex_unlock(&motu->mutex);
228 	}
229 
230 	return 0;
231 }
232 static int playback_hw_params(struct snd_pcm_substream *substream,
233 			      struct snd_pcm_hw_params *hw_params)
234 {
235 	struct snd_motu *motu = substream->private_data;
236 	int err;
237 
238 	err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
239 					       params_buffer_bytes(hw_params));
240 	if (err < 0)
241 		return err;
242 
243 	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
244 		mutex_lock(&motu->mutex);
245 		motu->playback_substreams++;
246 		mutex_unlock(&motu->mutex);
247 	}
248 
249 	return 0;
250 }
251 
252 static int capture_hw_free(struct snd_pcm_substream *substream)
253 {
254 	struct snd_motu *motu = substream->private_data;
255 
256 	mutex_lock(&motu->mutex);
257 
258 	if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
259 		motu->capture_substreams--;
260 
261 	snd_motu_stream_stop_duplex(motu);
262 
263 	mutex_unlock(&motu->mutex);
264 
265 	return snd_pcm_lib_free_vmalloc_buffer(substream);
266 }
267 
268 static int playback_hw_free(struct snd_pcm_substream *substream)
269 {
270 	struct snd_motu *motu = substream->private_data;
271 
272 	mutex_lock(&motu->mutex);
273 
274 	if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
275 		motu->playback_substreams--;
276 
277 	snd_motu_stream_stop_duplex(motu);
278 
279 	mutex_unlock(&motu->mutex);
280 
281 	return snd_pcm_lib_free_vmalloc_buffer(substream);
282 }
283 
284 static int capture_prepare(struct snd_pcm_substream *substream)
285 {
286 	struct snd_motu *motu = substream->private_data;
287 	int err;
288 
289 	mutex_lock(&motu->mutex);
290 	err = snd_motu_stream_start_duplex(motu, substream->runtime->rate);
291 	mutex_unlock(&motu->mutex);
292 	if (err >= 0)
293 		amdtp_stream_pcm_prepare(&motu->tx_stream);
294 
295 	return 0;
296 }
297 static int playback_prepare(struct snd_pcm_substream *substream)
298 {
299 	struct snd_motu *motu = substream->private_data;
300 	int err;
301 
302 	mutex_lock(&motu->mutex);
303 	err = snd_motu_stream_start_duplex(motu, substream->runtime->rate);
304 	mutex_unlock(&motu->mutex);
305 	if (err >= 0)
306 		amdtp_stream_pcm_prepare(&motu->rx_stream);
307 
308 	return err;
309 }
310 
311 static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
312 {
313 	struct snd_motu *motu = substream->private_data;
314 
315 	switch (cmd) {
316 	case SNDRV_PCM_TRIGGER_START:
317 		amdtp_stream_pcm_trigger(&motu->tx_stream, substream);
318 		break;
319 	case SNDRV_PCM_TRIGGER_STOP:
320 		amdtp_stream_pcm_trigger(&motu->tx_stream, NULL);
321 		break;
322 	default:
323 		return -EINVAL;
324 	}
325 
326 	return 0;
327 }
328 static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
329 {
330 	struct snd_motu *motu = substream->private_data;
331 
332 	switch (cmd) {
333 	case SNDRV_PCM_TRIGGER_START:
334 		amdtp_stream_pcm_trigger(&motu->rx_stream, substream);
335 		break;
336 	case SNDRV_PCM_TRIGGER_STOP:
337 		amdtp_stream_pcm_trigger(&motu->rx_stream, NULL);
338 		break;
339 	default:
340 		return -EINVAL;
341 	}
342 
343 	return 0;
344 }
345 
346 static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
347 {
348 	struct snd_motu *motu = substream->private_data;
349 
350 	return amdtp_stream_pcm_pointer(&motu->tx_stream);
351 }
352 static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
353 {
354 	struct snd_motu *motu = substream->private_data;
355 
356 	return amdtp_stream_pcm_pointer(&motu->rx_stream);
357 }
358 
359 int snd_motu_create_pcm_devices(struct snd_motu *motu)
360 {
361 	static struct snd_pcm_ops capture_ops = {
362 		.open      = pcm_open,
363 		.close     = pcm_close,
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,
372 	};
373 	static struct snd_pcm_ops playback_ops = {
374 		.open      = pcm_open,
375 		.close     = pcm_close,
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,
384 	};
385 	struct snd_pcm *pcm;
386 	int err;
387 
388 	err = snd_pcm_new(motu->card, motu->card->driver, 0, 1, 1, &pcm);
389 	if (err < 0)
390 		return err;
391 	pcm->private_data = motu;
392 	strcpy(pcm->name, motu->card->shortname);
393 
394 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
395 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
396 
397 	return 0;
398 }
399