1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family
4  *
5  * Copyright (c) 2014-2015 Takashi Sakamoto
6  */
7 
8 #include "digi00x.h"
9 
10 #define CALLBACK_TIMEOUT 500
11 
12 const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT] = {
13 	[SND_DG00X_RATE_44100] = 44100,
14 	[SND_DG00X_RATE_48000] = 48000,
15 	[SND_DG00X_RATE_88200] = 88200,
16 	[SND_DG00X_RATE_96000] = 96000,
17 };
18 
19 /* Multi Bit Linear Audio data channels for each sampling transfer frequency. */
20 const unsigned int
21 snd_dg00x_stream_pcm_channels[SND_DG00X_RATE_COUNT] = {
22 	/* Analog/ADAT/SPDIF */
23 	[SND_DG00X_RATE_44100] = (8 + 8 + 2),
24 	[SND_DG00X_RATE_48000] = (8 + 8 + 2),
25 	/* Analog/SPDIF */
26 	[SND_DG00X_RATE_88200] = (8 + 2),
27 	[SND_DG00X_RATE_96000] = (8 + 2),
28 };
29 
30 int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x, unsigned int *rate)
31 {
32 	u32 data;
33 	__be32 reg;
34 	int err;
35 
36 	err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
37 				 DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE,
38 				 &reg, sizeof(reg), 0);
39 	if (err < 0)
40 		return err;
41 
42 	data = be32_to_cpu(reg) & 0x0f;
43 	if (data < ARRAY_SIZE(snd_dg00x_stream_rates))
44 		*rate = snd_dg00x_stream_rates[data];
45 	else
46 		err = -EIO;
47 
48 	return err;
49 }
50 
51 int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate)
52 {
53 	__be32 reg;
54 	unsigned int i;
55 
56 	for (i = 0; i < ARRAY_SIZE(snd_dg00x_stream_rates); i++) {
57 		if (rate == snd_dg00x_stream_rates[i])
58 			break;
59 	}
60 	if (i == ARRAY_SIZE(snd_dg00x_stream_rates))
61 		return -EINVAL;
62 
63 	reg = cpu_to_be32(i);
64 	return snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
65 				  DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE,
66 				  &reg, sizeof(reg), 0);
67 }
68 
69 int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x,
70 			       enum snd_dg00x_clock *clock)
71 {
72 	__be32 reg;
73 	int err;
74 
75 	err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
76 				 DG00X_ADDR_BASE + DG00X_OFFSET_CLOCK_SOURCE,
77 				 &reg, sizeof(reg), 0);
78 	if (err < 0)
79 		return err;
80 
81 	*clock = be32_to_cpu(reg) & 0x0f;
82 	if (*clock >= SND_DG00X_CLOCK_COUNT)
83 		err = -EIO;
84 
85 	return err;
86 }
87 
88 int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, bool *detect)
89 {
90 	__be32 reg;
91 	int err;
92 
93 	err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
94 				 DG00X_ADDR_BASE + DG00X_OFFSET_DETECT_EXTERNAL,
95 				 &reg, sizeof(reg), 0);
96 	if (err >= 0)
97 		*detect = be32_to_cpu(reg) > 0;
98 
99 	return err;
100 }
101 
102 int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x,
103 				       unsigned int *rate)
104 {
105 	u32 data;
106 	__be32 reg;
107 	int err;
108 
109 	err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
110 				 DG00X_ADDR_BASE + DG00X_OFFSET_EXTERNAL_RATE,
111 				 &reg, sizeof(reg), 0);
112 	if (err < 0)
113 		return err;
114 
115 	data = be32_to_cpu(reg) & 0x0f;
116 	if (data < ARRAY_SIZE(snd_dg00x_stream_rates))
117 		*rate = snd_dg00x_stream_rates[data];
118 	/* This means desync. */
119 	else
120 		err = -EBUSY;
121 
122 	return err;
123 }
124 
125 static void finish_session(struct snd_dg00x *dg00x)
126 {
127 	__be32 data;
128 
129 	amdtp_stream_stop(&dg00x->tx_stream);
130 	amdtp_stream_stop(&dg00x->rx_stream);
131 
132 	data = cpu_to_be32(0x00000003);
133 	snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
134 			   DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_SET,
135 			   &data, sizeof(data), 0);
136 
137 	// Unregister isochronous channels for both direction.
138 	data = 0;
139 	snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
140 			   DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS,
141 			   &data, sizeof(data), 0);
142 
143 	// Just after finishing the session, the device may lost transmitting
144 	// functionality for a short time.
145 	msleep(50);
146 }
147 
148 static int begin_session(struct snd_dg00x *dg00x)
149 {
150 	__be32 data;
151 	u32 curr;
152 	int err;
153 
154 	// Register isochronous channels for both direction.
155 	data = cpu_to_be32((dg00x->tx_resources.channel << 16) |
156 			   dg00x->rx_resources.channel);
157 	err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
158 				 DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS,
159 				 &data, sizeof(data), 0);
160 	if (err < 0)
161 		return err;
162 
163 	err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
164 				 DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_STATE,
165 				 &data, sizeof(data), 0);
166 	if (err < 0)
167 		return err;
168 	curr = be32_to_cpu(data);
169 
170 	if (curr == 0)
171 		curr = 2;
172 
173 	curr--;
174 	while (curr > 0) {
175 		data = cpu_to_be32(curr);
176 		err = snd_fw_transaction(dg00x->unit,
177 					 TCODE_WRITE_QUADLET_REQUEST,
178 					 DG00X_ADDR_BASE +
179 					 DG00X_OFFSET_STREAMING_SET,
180 					 &data, sizeof(data), 0);
181 		if (err < 0)
182 			break;
183 
184 		msleep(20);
185 		curr--;
186 	}
187 
188 	return err;
189 }
190 
191 static int keep_resources(struct snd_dg00x *dg00x, struct amdtp_stream *stream,
192 			  unsigned int rate)
193 {
194 	struct fw_iso_resources *resources;
195 	int i;
196 	int err;
197 
198 	// Check sampling rate.
199 	for (i = 0; i < SND_DG00X_RATE_COUNT; i++) {
200 		if (snd_dg00x_stream_rates[i] == rate)
201 			break;
202 	}
203 	if (i == SND_DG00X_RATE_COUNT)
204 		return -EINVAL;
205 
206 	if (stream == &dg00x->tx_stream)
207 		resources = &dg00x->tx_resources;
208 	else
209 		resources = &dg00x->rx_resources;
210 
211 	err = amdtp_dot_set_parameters(stream, rate,
212 				       snd_dg00x_stream_pcm_channels[i]);
213 	if (err < 0)
214 		return err;
215 
216 	return fw_iso_resources_allocate(resources,
217 				amdtp_stream_get_max_payload(stream),
218 				fw_parent_device(dg00x->unit)->max_speed);
219 }
220 
221 int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x)
222 {
223 	int err;
224 
225 	/* For out-stream. */
226 	err = fw_iso_resources_init(&dg00x->rx_resources, dg00x->unit);
227 	if (err < 0)
228 		goto error;
229 	err = amdtp_dot_init(&dg00x->rx_stream, dg00x->unit, AMDTP_OUT_STREAM);
230 	if (err < 0)
231 		goto error;
232 
233 	/* For in-stream. */
234 	err = fw_iso_resources_init(&dg00x->tx_resources, dg00x->unit);
235 	if (err < 0)
236 		goto error;
237 	err = amdtp_dot_init(&dg00x->tx_stream, dg00x->unit, AMDTP_IN_STREAM);
238 	if (err < 0)
239 		goto error;
240 
241 	return 0;
242 error:
243 	snd_dg00x_stream_destroy_duplex(dg00x);
244 	return err;
245 }
246 
247 /*
248  * This function should be called before starting streams or after stopping
249  * streams.
250  */
251 void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x)
252 {
253 	amdtp_stream_destroy(&dg00x->rx_stream);
254 	fw_iso_resources_destroy(&dg00x->rx_resources);
255 
256 	amdtp_stream_destroy(&dg00x->tx_stream);
257 	fw_iso_resources_destroy(&dg00x->tx_resources);
258 }
259 
260 int snd_dg00x_stream_reserve_duplex(struct snd_dg00x *dg00x, unsigned int rate)
261 {
262 	unsigned int curr_rate;
263 	int err;
264 
265 	err = snd_dg00x_stream_get_local_rate(dg00x, &curr_rate);
266 	if (err < 0)
267 		return err;
268 	if (rate == 0)
269 		rate = curr_rate;
270 
271 	if (dg00x->substreams_counter == 0 || curr_rate != rate) {
272 		finish_session(dg00x);
273 
274 		fw_iso_resources_free(&dg00x->tx_resources);
275 		fw_iso_resources_free(&dg00x->rx_resources);
276 
277 		err = snd_dg00x_stream_set_local_rate(dg00x, rate);
278 		if (err < 0)
279 			return err;
280 
281 		err = keep_resources(dg00x, &dg00x->rx_stream, rate);
282 		if (err < 0)
283 			return err;
284 
285 		err = keep_resources(dg00x, &dg00x->tx_stream, rate);
286 		if (err < 0) {
287 			fw_iso_resources_free(&dg00x->rx_resources);
288 			return err;
289 		}
290 	}
291 
292 	return 0;
293 }
294 
295 int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x)
296 {
297 	unsigned int generation = dg00x->rx_resources.generation;
298 	int err = 0;
299 
300 	if (dg00x->substreams_counter == 0)
301 		return 0;
302 
303 	if (amdtp_streaming_error(&dg00x->tx_stream) ||
304 	    amdtp_streaming_error(&dg00x->rx_stream))
305 		finish_session(dg00x);
306 
307 	if (generation != fw_parent_device(dg00x->unit)->card->generation) {
308 		err = fw_iso_resources_update(&dg00x->tx_resources);
309 		if (err < 0)
310 			goto error;
311 
312 		err = fw_iso_resources_update(&dg00x->rx_resources);
313 		if (err < 0)
314 			goto error;
315 	}
316 
317 	/*
318 	 * No packets are transmitted without receiving packets, reagardless of
319 	 * which source of clock is used.
320 	 */
321 	if (!amdtp_stream_running(&dg00x->rx_stream)) {
322 		err = begin_session(dg00x);
323 		if (err < 0)
324 			goto error;
325 
326 		err = amdtp_stream_start(&dg00x->rx_stream,
327 				dg00x->rx_resources.channel,
328 				fw_parent_device(dg00x->unit)->max_speed);
329 		if (err < 0)
330 			goto error;
331 
332 		if (!amdtp_stream_wait_callback(&dg00x->rx_stream,
333 					      CALLBACK_TIMEOUT)) {
334 			err = -ETIMEDOUT;
335 			goto error;
336 		}
337 	}
338 
339 	/*
340 	 * The value of SYT field in transmitted packets is always 0x0000. Thus,
341 	 * duplex streams with timestamp synchronization cannot be built.
342 	 */
343 	if (!amdtp_stream_running(&dg00x->tx_stream)) {
344 		err = amdtp_stream_start(&dg00x->tx_stream,
345 				dg00x->tx_resources.channel,
346 				fw_parent_device(dg00x->unit)->max_speed);
347 		if (err < 0)
348 			goto error;
349 
350 		if (!amdtp_stream_wait_callback(&dg00x->tx_stream,
351 					      CALLBACK_TIMEOUT)) {
352 			err = -ETIMEDOUT;
353 			goto error;
354 		}
355 	}
356 
357 	return 0;
358 error:
359 	finish_session(dg00x);
360 
361 	return err;
362 }
363 
364 void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x)
365 {
366 	if (dg00x->substreams_counter == 0) {
367 		finish_session(dg00x);
368 
369 		fw_iso_resources_free(&dg00x->tx_resources);
370 		fw_iso_resources_free(&dg00x->rx_resources);
371 	}
372 }
373 
374 void snd_dg00x_stream_update_duplex(struct snd_dg00x *dg00x)
375 {
376 	fw_iso_resources_update(&dg00x->tx_resources);
377 	fw_iso_resources_update(&dg00x->rx_resources);
378 
379 	amdtp_stream_update(&dg00x->tx_stream);
380 	amdtp_stream_update(&dg00x->rx_stream);
381 }
382 
383 void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x)
384 {
385 	dg00x->dev_lock_changed = true;
386 	wake_up(&dg00x->hwdep_wait);
387 }
388 
389 int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x)
390 {
391 	int err;
392 
393 	spin_lock_irq(&dg00x->lock);
394 
395 	/* user land lock this */
396 	if (dg00x->dev_lock_count < 0) {
397 		err = -EBUSY;
398 		goto end;
399 	}
400 
401 	/* this is the first time */
402 	if (dg00x->dev_lock_count++ == 0)
403 		snd_dg00x_stream_lock_changed(dg00x);
404 	err = 0;
405 end:
406 	spin_unlock_irq(&dg00x->lock);
407 	return err;
408 }
409 
410 void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x)
411 {
412 	spin_lock_irq(&dg00x->lock);
413 
414 	if (WARN_ON(dg00x->dev_lock_count <= 0))
415 		goto end;
416 	if (--dg00x->dev_lock_count == 0)
417 		snd_dg00x_stream_lock_changed(dg00x);
418 end:
419 	spin_unlock_irq(&dg00x->lock);
420 }
421