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