xref: /linux/sound/firewire/fireface/ff-pcm.c (revision e58e871becec2d3b04ed91c0c16fe8deac9c9dfa)
1 /*
2  * ff-pcm.c - a part of driver for RME Fireface series
3  *
4  * Copyright (c) 2015-2017 Takashi Sakamoto
5  *
6  * Licensed under the terms of the GNU General Public License, version 2.
7  */
8 
9 #include "ff.h"
10 
11 static inline unsigned int get_multiplier_mode_with_index(unsigned int index)
12 {
13 	return ((int)index - 1) / 2;
14 }
15 
16 static int hw_rule_rate(struct snd_pcm_hw_params *params,
17 			struct snd_pcm_hw_rule *rule)
18 {
19 	const unsigned int *pcm_channels = rule->private;
20 	struct snd_interval *r =
21 		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
22 	const struct snd_interval *c =
23 		hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
24 	struct snd_interval t = {
25 		.min = UINT_MAX, .max = 0, .integer = 1
26 	};
27 	unsigned int i, mode;
28 
29 	for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
30 		mode = get_multiplier_mode_with_index(i);
31 		if (!snd_interval_test(c, pcm_channels[mode]))
32 			continue;
33 
34 		t.min = min(t.min, amdtp_rate_table[i]);
35 		t.max = max(t.max, amdtp_rate_table[i]);
36 	}
37 
38 	return snd_interval_refine(r, &t);
39 }
40 
41 static int hw_rule_channels(struct snd_pcm_hw_params *params,
42 			    struct snd_pcm_hw_rule *rule)
43 {
44 	const unsigned int *pcm_channels = rule->private;
45 	struct snd_interval *c =
46 		hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
47 	const struct snd_interval *r =
48 		hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
49 	struct snd_interval t = {
50 		.min = UINT_MAX, .max = 0, .integer = 1
51 	};
52 	unsigned int i, mode;
53 
54 	for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
55 		mode = get_multiplier_mode_with_index(i);
56 		if (!snd_interval_test(r, amdtp_rate_table[i]))
57 			continue;
58 
59 		t.min = min(t.min, pcm_channels[mode]);
60 		t.max = max(t.max, pcm_channels[mode]);
61 	}
62 
63 	return snd_interval_refine(c, &t);
64 }
65 
66 static void limit_channels_and_rates(struct snd_pcm_hardware *hw,
67 				     const unsigned int *pcm_channels)
68 {
69 	unsigned int mode;
70 	unsigned int rate, channels;
71 	int i;
72 
73 	hw->channels_min = UINT_MAX;
74 	hw->channels_max = 0;
75 	hw->rate_min = UINT_MAX;
76 	hw->rate_max = 0;
77 
78 	for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {
79 		mode = get_multiplier_mode_with_index(i);
80 
81 		channels = pcm_channels[mode];
82 		if (pcm_channels[mode] == 0)
83 			continue;
84 		hw->channels_min = min(hw->channels_min, channels);
85 		hw->channels_max = max(hw->channels_max, channels);
86 
87 		rate = amdtp_rate_table[i];
88 		hw->rates |= snd_pcm_rate_to_rate_bit(rate);
89 		hw->rate_min = min(hw->rate_min, rate);
90 		hw->rate_max = max(hw->rate_max, rate);
91 	}
92 }
93 
94 static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
95 {
96 	hw->periods_min = 2;		/* SNDRV_PCM_INFO_BATCH */
97 	hw->periods_max = UINT_MAX;
98 
99 	hw->period_bytes_min = 4 * hw->channels_max;	/* bytes for a frame */
100 
101 	/* Just to prevent from allocating much pages. */
102 	hw->period_bytes_max = hw->period_bytes_min * 2048;
103 	hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
104 }
105 
106 static int pcm_init_hw_params(struct snd_ff *ff,
107 			      struct snd_pcm_substream *substream)
108 {
109 	struct snd_pcm_runtime *runtime = substream->runtime;
110 	struct amdtp_stream *s;
111 	const unsigned int *pcm_channels;
112 	int err;
113 
114 	runtime->hw.info = SNDRV_PCM_INFO_BATCH |
115 			   SNDRV_PCM_INFO_BLOCK_TRANSFER |
116 			   SNDRV_PCM_INFO_INTERLEAVED |
117 			   SNDRV_PCM_INFO_JOINT_DUPLEX |
118 			   SNDRV_PCM_INFO_MMAP |
119 			   SNDRV_PCM_INFO_MMAP_VALID;
120 
121 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
122 		runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
123 		s = &ff->tx_stream;
124 		pcm_channels = ff->spec->pcm_capture_channels;
125 	} else {
126 		runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
127 		s = &ff->rx_stream;
128 		pcm_channels = ff->spec->pcm_playback_channels;
129 	}
130 
131 	/* limit rates */
132 	limit_channels_and_rates(&runtime->hw, pcm_channels);
133 	limit_period_and_buffer(&runtime->hw);
134 
135 	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
136 				  hw_rule_channels, (void *)pcm_channels,
137 				  SNDRV_PCM_HW_PARAM_RATE, -1);
138 	if (err < 0)
139 		return err;
140 
141 	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
142 				  hw_rule_rate, (void *)pcm_channels,
143 				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
144 	if (err < 0)
145 		return err;
146 
147 	return amdtp_ff_add_pcm_hw_constraints(s, runtime);
148 }
149 
150 static int pcm_open(struct snd_pcm_substream *substream)
151 {
152 	struct snd_ff *ff = substream->private_data;
153 	unsigned int rate;
154 	enum snd_ff_clock_src src;
155 	int i, err;
156 
157 	err = snd_ff_stream_lock_try(ff);
158 	if (err < 0)
159 		return err;
160 
161 	err = pcm_init_hw_params(ff, substream);
162 	if (err < 0) {
163 		snd_ff_stream_lock_release(ff);
164 		return err;
165 	}
166 
167 	err = ff->spec->protocol->get_clock(ff, &rate, &src);
168 	if (err < 0) {
169 		snd_ff_stream_lock_release(ff);
170 		return err;
171 	}
172 
173 	if (src != SND_FF_CLOCK_SRC_INTERNAL) {
174 		for (i = 0; i < CIP_SFC_COUNT; ++i) {
175 			if (amdtp_rate_table[i] == rate)
176 				break;
177 		}
178 		/*
179 		 * The unit is configured at sampling frequency which packet
180 		 * streaming engine can't support.
181 		 */
182 		if (i >= CIP_SFC_COUNT) {
183 			snd_ff_stream_lock_release(ff);
184 			return -EIO;
185 		}
186 
187 		substream->runtime->hw.rate_min = rate;
188 		substream->runtime->hw.rate_max = rate;
189 	} else {
190 		if (amdtp_stream_pcm_running(&ff->rx_stream) ||
191 		    amdtp_stream_pcm_running(&ff->tx_stream)) {
192 			rate = amdtp_rate_table[ff->rx_stream.sfc];
193 			substream->runtime->hw.rate_min = rate;
194 			substream->runtime->hw.rate_max = rate;
195 		}
196 	}
197 
198 	snd_pcm_set_sync(substream);
199 
200 	return 0;
201 }
202 
203 static int pcm_close(struct snd_pcm_substream *substream)
204 {
205 	struct snd_ff *ff = substream->private_data;
206 
207 	snd_ff_stream_lock_release(ff);
208 
209 	return 0;
210 }
211 
212 static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
213 				 struct snd_pcm_hw_params *hw_params)
214 {
215 	struct snd_ff *ff = substream->private_data;
216 	int err;
217 
218 	err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
219 					       params_buffer_bytes(hw_params));
220 	if (err < 0)
221 		return err;
222 
223 	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
224 		mutex_lock(&ff->mutex);
225 		ff->substreams_counter++;
226 		mutex_unlock(&ff->mutex);
227 	}
228 
229 	return 0;
230 }
231 
232 static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
233 				  struct snd_pcm_hw_params *hw_params)
234 {
235 	struct snd_ff *ff = 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(&ff->mutex);
245 		ff->substreams_counter++;
246 		mutex_unlock(&ff->mutex);
247 	}
248 
249 	return 0;
250 }
251 
252 static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
253 {
254 	struct snd_ff *ff = substream->private_data;
255 
256 	mutex_lock(&ff->mutex);
257 
258 	if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
259 		ff->substreams_counter--;
260 
261 	snd_ff_stream_stop_duplex(ff);
262 
263 	mutex_unlock(&ff->mutex);
264 
265 	return snd_pcm_lib_free_vmalloc_buffer(substream);
266 }
267 
268 static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
269 {
270 	struct snd_ff *ff = substream->private_data;
271 
272 	mutex_lock(&ff->mutex);
273 
274 	if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
275 		ff->substreams_counter--;
276 
277 	snd_ff_stream_stop_duplex(ff);
278 
279 	mutex_unlock(&ff->mutex);
280 
281 	return snd_pcm_lib_free_vmalloc_buffer(substream);
282 }
283 
284 static int pcm_capture_prepare(struct snd_pcm_substream *substream)
285 {
286 	struct snd_ff *ff = substream->private_data;
287 	struct snd_pcm_runtime *runtime = substream->runtime;
288 	int err;
289 
290 	mutex_lock(&ff->mutex);
291 
292 	err = snd_ff_stream_start_duplex(ff, runtime->rate);
293 	if (err >= 0)
294 		amdtp_stream_pcm_prepare(&ff->tx_stream);
295 
296 	mutex_unlock(&ff->mutex);
297 
298 	return err;
299 }
300 
301 static int pcm_playback_prepare(struct snd_pcm_substream *substream)
302 {
303 	struct snd_ff *ff = substream->private_data;
304 	struct snd_pcm_runtime *runtime = substream->runtime;
305 	int err;
306 
307 	mutex_lock(&ff->mutex);
308 
309 	err = snd_ff_stream_start_duplex(ff, runtime->rate);
310 	if (err >= 0)
311 		amdtp_stream_pcm_prepare(&ff->rx_stream);
312 
313 	mutex_unlock(&ff->mutex);
314 
315 	return err;
316 }
317 
318 static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
319 {
320 	struct snd_ff *ff = substream->private_data;
321 
322 	switch (cmd) {
323 	case SNDRV_PCM_TRIGGER_START:
324 		amdtp_stream_pcm_trigger(&ff->tx_stream, substream);
325 		break;
326 	case SNDRV_PCM_TRIGGER_STOP:
327 		amdtp_stream_pcm_trigger(&ff->tx_stream, NULL);
328 		break;
329 	default:
330 		return -EINVAL;
331 	}
332 
333 	return 0;
334 }
335 
336 static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
337 {
338 	struct snd_ff *ff = substream->private_data;
339 
340 	switch (cmd) {
341 	case SNDRV_PCM_TRIGGER_START:
342 		amdtp_stream_pcm_trigger(&ff->rx_stream, substream);
343 		break;
344 	case SNDRV_PCM_TRIGGER_STOP:
345 		amdtp_stream_pcm_trigger(&ff->rx_stream, NULL);
346 		break;
347 	default:
348 		return -EINVAL;
349 	}
350 
351 	return 0;
352 }
353 
354 static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
355 {
356 	struct snd_ff *ff = sbstrm->private_data;
357 
358 	return amdtp_stream_pcm_pointer(&ff->tx_stream);
359 }
360 
361 static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
362 {
363 	struct snd_ff *ff = sbstrm->private_data;
364 
365 	return amdtp_stream_pcm_pointer(&ff->rx_stream);
366 }
367 
368 static struct snd_pcm_ops pcm_capture_ops = {
369 	.open		= pcm_open,
370 	.close		= pcm_close,
371 	.ioctl		= snd_pcm_lib_ioctl,
372 	.hw_params	= pcm_capture_hw_params,
373 	.hw_free	= pcm_capture_hw_free,
374 	.prepare	= pcm_capture_prepare,
375 	.trigger	= pcm_capture_trigger,
376 	.pointer	= pcm_capture_pointer,
377 	.page		= snd_pcm_lib_get_vmalloc_page,
378 };
379 
380 static struct snd_pcm_ops pcm_playback_ops = {
381 	.open		= pcm_open,
382 	.close		= pcm_close,
383 	.ioctl		= snd_pcm_lib_ioctl,
384 	.hw_params	= pcm_playback_hw_params,
385 	.hw_free	= pcm_playback_hw_free,
386 	.prepare	= pcm_playback_prepare,
387 	.trigger	= pcm_playback_trigger,
388 	.pointer	= pcm_playback_pointer,
389 	.page		= snd_pcm_lib_get_vmalloc_page,
390 	.mmap		= snd_pcm_lib_mmap_vmalloc,
391 };
392 
393 int snd_ff_create_pcm_devices(struct snd_ff *ff)
394 {
395 	struct snd_pcm *pcm;
396 	int err;
397 
398 	err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm);
399 	if (err < 0)
400 		return err;
401 
402 	pcm->private_data = ff;
403 	snprintf(pcm->name, sizeof(pcm->name),
404 		 "%s PCM", ff->card->shortname);
405 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
406 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
407 
408 	return 0;
409 }
410