1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * tascam-stream.c - a part of driver for TASCAM FireWire series
4  *
5  * Copyright (c) 2015 Takashi Sakamoto
6  */
7 
8 #include <linux/delay.h>
9 #include "tascam.h"
10 
11 #define CLOCK_STATUS_MASK      0xffff0000
12 #define CLOCK_CONFIG_MASK      0x0000ffff
13 
14 #define CALLBACK_TIMEOUT 500
15 
16 static int get_clock(struct snd_tscm *tscm, u32 *data)
17 {
18 	int trial = 0;
19 	__be32 reg;
20 	int err;
21 
22 	while (trial++ < 5) {
23 		err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
24 				TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
25 				&reg, sizeof(reg), 0);
26 		if (err < 0)
27 			return err;
28 
29 		*data = be32_to_cpu(reg);
30 		if (*data & CLOCK_STATUS_MASK)
31 			break;
32 
33 		// In intermediate state after changing clock status.
34 		msleep(50);
35 	}
36 
37 	// Still in the intermediate state.
38 	if (trial >= 5)
39 		return -EAGAIN;
40 
41 	return 0;
42 }
43 
44 static int set_clock(struct snd_tscm *tscm, unsigned int rate,
45 		     enum snd_tscm_clock clock)
46 {
47 	u32 data;
48 	__be32 reg;
49 	int err;
50 
51 	err = get_clock(tscm, &data);
52 	if (err < 0)
53 		return err;
54 	data &= CLOCK_CONFIG_MASK;
55 
56 	if (rate > 0) {
57 		data &= 0x000000ff;
58 		/* Base rate. */
59 		if ((rate % 44100) == 0) {
60 			data |= 0x00000100;
61 			/* Multiplier. */
62 			if (rate / 44100 == 2)
63 				data |= 0x00008000;
64 		} else if ((rate % 48000) == 0) {
65 			data |= 0x00000200;
66 			/* Multiplier. */
67 			if (rate / 48000 == 2)
68 				data |= 0x00008000;
69 		} else {
70 			return -EAGAIN;
71 		}
72 	}
73 
74 	if (clock != INT_MAX) {
75 		data &= 0x0000ff00;
76 		data |= clock + 1;
77 	}
78 
79 	reg = cpu_to_be32(data);
80 
81 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
82 				 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
83 				 &reg, sizeof(reg), 0);
84 	if (err < 0)
85 		return err;
86 
87 	if (data & 0x00008000)
88 		reg = cpu_to_be32(0x0000001a);
89 	else
90 		reg = cpu_to_be32(0x0000000d);
91 
92 	return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
93 				  TSCM_ADDR_BASE + TSCM_OFFSET_MULTIPLEX_MODE,
94 				  &reg, sizeof(reg), 0);
95 }
96 
97 int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate)
98 {
99 	u32 data;
100 	int err;
101 
102 	err = get_clock(tscm, &data);
103 	if (err < 0)
104 		return err;
105 
106 	data = (data & 0xff000000) >> 24;
107 
108 	/* Check base rate. */
109 	if ((data & 0x0f) == 0x01)
110 		*rate = 44100;
111 	else if ((data & 0x0f) == 0x02)
112 		*rate = 48000;
113 	else
114 		return -EAGAIN;
115 
116 	/* Check multiplier. */
117 	if ((data & 0xf0) == 0x80)
118 		*rate *= 2;
119 	else if ((data & 0xf0) != 0x00)
120 		return -EAGAIN;
121 
122 	return err;
123 }
124 
125 int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock)
126 {
127 	u32 data;
128 	int err;
129 
130 	err = get_clock(tscm, &data);
131 	if (err < 0)
132 		return err;
133 
134 	*clock = ((data & 0x00ff0000) >> 16) - 1;
135 	if (*clock < 0 || *clock > SND_TSCM_CLOCK_ADAT)
136 		return -EIO;
137 
138 	return 0;
139 }
140 
141 static int enable_data_channels(struct snd_tscm *tscm)
142 {
143 	__be32 reg;
144 	u32 data;
145 	unsigned int i;
146 	int err;
147 
148 	data = 0;
149 	for (i = 0; i < tscm->spec->pcm_capture_analog_channels; ++i)
150 		data |= BIT(i);
151 	if (tscm->spec->has_adat)
152 		data |= 0x0000ff00;
153 	if (tscm->spec->has_spdif)
154 		data |= 0x00030000;
155 
156 	reg = cpu_to_be32(data);
157 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
158 				 TSCM_ADDR_BASE + TSCM_OFFSET_TX_PCM_CHANNELS,
159 				 &reg, sizeof(reg), 0);
160 	if (err < 0)
161 		return err;
162 
163 	data = 0;
164 	for (i = 0; i < tscm->spec->pcm_playback_analog_channels; ++i)
165 		data |= BIT(i);
166 	if (tscm->spec->has_adat)
167 		data |= 0x0000ff00;
168 	if (tscm->spec->has_spdif)
169 		data |= 0x00030000;
170 
171 	reg = cpu_to_be32(data);
172 	return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
173 				  TSCM_ADDR_BASE + TSCM_OFFSET_RX_PCM_CHANNELS,
174 				  &reg, sizeof(reg), 0);
175 }
176 
177 static int set_stream_formats(struct snd_tscm *tscm, unsigned int rate)
178 {
179 	__be32 reg;
180 	int err;
181 
182 	// Set an option for unknown purpose.
183 	reg = cpu_to_be32(0x00200000);
184 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
185 				 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION,
186 				 &reg, sizeof(reg), 0);
187 	if (err < 0)
188 		return err;
189 
190 	return enable_data_channels(tscm);
191 }
192 
193 static void finish_session(struct snd_tscm *tscm)
194 {
195 	__be32 reg;
196 
197 	reg = 0;
198 	snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
199 			   TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
200 			   &reg, sizeof(reg), 0);
201 
202 	reg = 0;
203 	snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
204 			   TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON,
205 			   &reg, sizeof(reg), 0);
206 
207 	// Unregister channels.
208 	reg = cpu_to_be32(0x00000000);
209 	snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
210 			   TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH,
211 			   &reg, sizeof(reg), 0);
212 	reg = cpu_to_be32(0x00000000);
213 	snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
214 			   TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN,
215 			   &reg, sizeof(reg), 0);
216 	reg = cpu_to_be32(0x00000000);
217 	snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
218 			   TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH,
219 			   &reg, sizeof(reg), 0);
220 }
221 
222 static int begin_session(struct snd_tscm *tscm)
223 {
224 	__be32 reg;
225 	int err;
226 
227 	// Register the isochronous channel for transmitting stream.
228 	reg = cpu_to_be32(tscm->tx_resources.channel);
229 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
230 				 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH,
231 				 &reg, sizeof(reg), 0);
232 	if (err < 0)
233 		return err;
234 
235 	// Unknown.
236 	reg = cpu_to_be32(0x00000002);
237 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
238 				 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN,
239 				 &reg, sizeof(reg), 0);
240 	if (err < 0)
241 		return err;
242 
243 	// Register the isochronous channel for receiving stream.
244 	reg = cpu_to_be32(tscm->rx_resources.channel);
245 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
246 				 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH,
247 				 &reg, sizeof(reg), 0);
248 	if (err < 0)
249 		return err;
250 
251 	reg = cpu_to_be32(0x00000001);
252 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
253 				 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
254 				 &reg, sizeof(reg), 0);
255 	if (err < 0)
256 		return err;
257 
258 	reg = cpu_to_be32(0x00000001);
259 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
260 				 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON,
261 				 &reg, sizeof(reg), 0);
262 	if (err < 0)
263 		return err;
264 
265 	// Set an option for unknown purpose.
266 	reg = cpu_to_be32(0x00002000);
267 	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
268 				 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION,
269 				 &reg, sizeof(reg), 0);
270 	if (err < 0)
271 		return err;
272 
273 	// Start multiplexing PCM samples on packets.
274 	reg = cpu_to_be32(0x00000001);
275 	return snd_fw_transaction(tscm->unit,
276 				  TCODE_WRITE_QUADLET_REQUEST,
277 				  TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_ON,
278 				  &reg, sizeof(reg), 0);
279 }
280 
281 static int keep_resources(struct snd_tscm *tscm, unsigned int rate,
282 			  struct amdtp_stream *stream)
283 {
284 	struct fw_iso_resources *resources;
285 	int err;
286 
287 	if (stream == &tscm->tx_stream)
288 		resources = &tscm->tx_resources;
289 	else
290 		resources = &tscm->rx_resources;
291 
292 	err = amdtp_tscm_set_parameters(stream, rate);
293 	if (err < 0)
294 		return err;
295 
296 	return fw_iso_resources_allocate(resources,
297 				amdtp_stream_get_max_payload(stream),
298 				fw_parent_device(tscm->unit)->max_speed);
299 }
300 
301 static int init_stream(struct snd_tscm *tscm, struct amdtp_stream *s)
302 {
303 	struct fw_iso_resources *resources;
304 	enum amdtp_stream_direction dir;
305 	unsigned int pcm_channels;
306 	int err;
307 
308 	if (s == &tscm->tx_stream) {
309 		resources = &tscm->tx_resources;
310 		dir = AMDTP_IN_STREAM;
311 		pcm_channels = tscm->spec->pcm_capture_analog_channels;
312 	} else {
313 		resources = &tscm->rx_resources;
314 		dir = AMDTP_OUT_STREAM;
315 		pcm_channels = tscm->spec->pcm_playback_analog_channels;
316 	}
317 
318 	if (tscm->spec->has_adat)
319 		pcm_channels += 8;
320 	if (tscm->spec->has_spdif)
321 		pcm_channels += 2;
322 
323 	err = fw_iso_resources_init(resources, tscm->unit);
324 	if (err < 0)
325 		return err;
326 
327 	err = amdtp_tscm_init(s, tscm->unit, dir, pcm_channels);
328 	if (err < 0)
329 		fw_iso_resources_free(resources);
330 
331 	return err;
332 }
333 
334 static void destroy_stream(struct snd_tscm *tscm, struct amdtp_stream *s)
335 {
336 	amdtp_stream_destroy(s);
337 
338 	if (s == &tscm->tx_stream)
339 		fw_iso_resources_destroy(&tscm->tx_resources);
340 	else
341 		fw_iso_resources_destroy(&tscm->rx_resources);
342 }
343 
344 int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
345 {
346 	int err;
347 
348 	err = init_stream(tscm, &tscm->tx_stream);
349 	if (err < 0)
350 		return err;
351 
352 	err = init_stream(tscm, &tscm->rx_stream);
353 	if (err < 0) {
354 		destroy_stream(tscm, &tscm->tx_stream);
355 		return err;
356 	}
357 
358 	err = amdtp_domain_init(&tscm->domain);
359 	if (err < 0) {
360 		destroy_stream(tscm, &tscm->tx_stream);
361 		destroy_stream(tscm, &tscm->rx_stream);
362 	}
363 
364 	return err;
365 }
366 
367 // At bus reset, streaming is stopped and some registers are clear.
368 void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
369 {
370 	amdtp_domain_stop(&tscm->domain);
371 
372 	amdtp_stream_pcm_abort(&tscm->tx_stream);
373 	amdtp_stream_pcm_abort(&tscm->rx_stream);
374 }
375 
376 // This function should be called before starting streams or after stopping
377 // streams.
378 void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
379 {
380 	amdtp_domain_destroy(&tscm->domain);
381 
382 	destroy_stream(tscm, &tscm->rx_stream);
383 	destroy_stream(tscm, &tscm->tx_stream);
384 }
385 
386 int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate)
387 {
388 	unsigned int curr_rate;
389 	int err;
390 
391 	err = snd_tscm_stream_get_rate(tscm, &curr_rate);
392 	if (err < 0)
393 		return err;
394 
395 	if (tscm->substreams_counter == 0 || rate != curr_rate) {
396 		amdtp_domain_stop(&tscm->domain);
397 
398 		finish_session(tscm);
399 
400 		fw_iso_resources_free(&tscm->tx_resources);
401 		fw_iso_resources_free(&tscm->rx_resources);
402 
403 		err = set_clock(tscm, rate, INT_MAX);
404 		if (err < 0)
405 			return err;
406 
407 		err = keep_resources(tscm, rate, &tscm->tx_stream);
408 		if (err < 0)
409 			return err;
410 
411 		err = keep_resources(tscm, rate, &tscm->rx_stream);
412 		if (err < 0) {
413 			fw_iso_resources_free(&tscm->tx_resources);
414 			return err;
415 		}
416 	}
417 
418 	return 0;
419 }
420 
421 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
422 {
423 	unsigned int generation = tscm->rx_resources.generation;
424 	int err;
425 
426 	if (tscm->substreams_counter == 0)
427 		return 0;
428 
429 	if (amdtp_streaming_error(&tscm->rx_stream) ||
430 	    amdtp_streaming_error(&tscm->tx_stream)) {
431 		amdtp_domain_stop(&tscm->domain);
432 		finish_session(tscm);
433 	}
434 
435 	if (generation != fw_parent_device(tscm->unit)->card->generation) {
436 		err = fw_iso_resources_update(&tscm->tx_resources);
437 		if (err < 0)
438 			goto error;
439 
440 		err = fw_iso_resources_update(&tscm->rx_resources);
441 		if (err < 0)
442 			goto error;
443 	}
444 
445 	if (!amdtp_stream_running(&tscm->rx_stream)) {
446 		int spd = fw_parent_device(tscm->unit)->max_speed;
447 
448 		err = set_stream_formats(tscm, rate);
449 		if (err < 0)
450 			goto error;
451 
452 		err = begin_session(tscm);
453 		if (err < 0)
454 			goto error;
455 
456 		err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
457 					      tscm->rx_resources.channel, spd);
458 		if (err < 0)
459 			goto error;
460 
461 		err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
462 					      tscm->tx_resources.channel, spd);
463 		if (err < 0)
464 			goto error;
465 
466 		err = amdtp_domain_start(&tscm->domain);
467 		if (err < 0)
468 			return err;
469 
470 		if (!amdtp_stream_wait_callback(&tscm->rx_stream,
471 						CALLBACK_TIMEOUT) ||
472 		    !amdtp_stream_wait_callback(&tscm->tx_stream,
473 						CALLBACK_TIMEOUT)) {
474 			err = -ETIMEDOUT;
475 			goto error;
476 		}
477 	}
478 
479 	return 0;
480 error:
481 	amdtp_domain_stop(&tscm->domain);
482 	finish_session(tscm);
483 
484 	return err;
485 }
486 
487 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
488 {
489 	if (tscm->substreams_counter == 0) {
490 		amdtp_domain_stop(&tscm->domain);
491 		finish_session(tscm);
492 
493 		fw_iso_resources_free(&tscm->tx_resources);
494 		fw_iso_resources_free(&tscm->rx_resources);
495 	}
496 }
497 
498 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
499 {
500 	tscm->dev_lock_changed = true;
501 	wake_up(&tscm->hwdep_wait);
502 }
503 
504 int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
505 {
506 	int err;
507 
508 	spin_lock_irq(&tscm->lock);
509 
510 	/* user land lock this */
511 	if (tscm->dev_lock_count < 0) {
512 		err = -EBUSY;
513 		goto end;
514 	}
515 
516 	/* this is the first time */
517 	if (tscm->dev_lock_count++ == 0)
518 		snd_tscm_stream_lock_changed(tscm);
519 	err = 0;
520 end:
521 	spin_unlock_irq(&tscm->lock);
522 	return err;
523 }
524 
525 void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
526 {
527 	spin_lock_irq(&tscm->lock);
528 
529 	if (WARN_ON(tscm->dev_lock_count <= 0))
530 		goto end;
531 	if (--tscm->dev_lock_count == 0)
532 		snd_tscm_stream_lock_changed(tscm);
533 end:
534 	spin_unlock_irq(&tscm->lock);
535 }
536