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 READY_TIMEOUT_MS	4000
15 
get_clock(struct snd_tscm * tscm,u32 * data)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 
set_clock(struct snd_tscm * tscm,unsigned int rate,enum snd_tscm_clock clock)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 
snd_tscm_stream_get_rate(struct snd_tscm * tscm,unsigned int * rate)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 
snd_tscm_stream_get_clock(struct snd_tscm * tscm,enum snd_tscm_clock * clock)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 
enable_data_channels(struct snd_tscm * tscm)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 
set_stream_formats(struct snd_tscm * tscm,unsigned int rate)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 
finish_session(struct snd_tscm * tscm)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 
begin_session(struct snd_tscm * tscm)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 
keep_resources(struct snd_tscm * tscm,unsigned int rate,struct amdtp_stream * stream)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 
init_stream(struct snd_tscm * tscm,struct amdtp_stream * s)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 
destroy_stream(struct snd_tscm * tscm,struct amdtp_stream * s)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 
snd_tscm_stream_init_duplex(struct snd_tscm * tscm)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.
snd_tscm_stream_update_duplex(struct snd_tscm * tscm)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.
snd_tscm_stream_destroy_duplex(struct snd_tscm * tscm)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 
snd_tscm_stream_reserve_duplex(struct snd_tscm * tscm,unsigned int rate,unsigned int frames_per_period,unsigned int frames_per_buffer)386 int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate,
387 				   unsigned int frames_per_period,
388 				   unsigned int frames_per_buffer)
389 {
390 	unsigned int curr_rate;
391 	int err;
392 
393 	err = snd_tscm_stream_get_rate(tscm, &curr_rate);
394 	if (err < 0)
395 		return err;
396 
397 	if (tscm->substreams_counter == 0 || rate != curr_rate) {
398 		amdtp_domain_stop(&tscm->domain);
399 
400 		finish_session(tscm);
401 
402 		fw_iso_resources_free(&tscm->tx_resources);
403 		fw_iso_resources_free(&tscm->rx_resources);
404 
405 		err = set_clock(tscm, rate, INT_MAX);
406 		if (err < 0)
407 			return err;
408 
409 		err = keep_resources(tscm, rate, &tscm->tx_stream);
410 		if (err < 0)
411 			return err;
412 
413 		err = keep_resources(tscm, rate, &tscm->rx_stream);
414 		if (err < 0) {
415 			fw_iso_resources_free(&tscm->tx_resources);
416 			return err;
417 		}
418 
419 		err = amdtp_domain_set_events_per_period(&tscm->domain,
420 					frames_per_period, frames_per_buffer);
421 		if (err < 0) {
422 			fw_iso_resources_free(&tscm->tx_resources);
423 			fw_iso_resources_free(&tscm->rx_resources);
424 			return err;
425 		}
426 
427 		tscm->need_long_tx_init_skip = (rate != curr_rate);
428 	}
429 
430 	return 0;
431 }
432 
snd_tscm_stream_start_duplex(struct snd_tscm * tscm,unsigned int rate)433 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
434 {
435 	unsigned int generation = tscm->rx_resources.generation;
436 	int err;
437 
438 	if (tscm->substreams_counter == 0)
439 		return 0;
440 
441 	if (amdtp_streaming_error(&tscm->rx_stream) ||
442 	    amdtp_streaming_error(&tscm->tx_stream)) {
443 		amdtp_domain_stop(&tscm->domain);
444 		finish_session(tscm);
445 	}
446 
447 	if (generation != fw_parent_device(tscm->unit)->card->generation) {
448 		err = fw_iso_resources_update(&tscm->tx_resources);
449 		if (err < 0)
450 			goto error;
451 
452 		err = fw_iso_resources_update(&tscm->rx_resources);
453 		if (err < 0)
454 			goto error;
455 	}
456 
457 	if (!amdtp_stream_running(&tscm->rx_stream)) {
458 		int spd = fw_parent_device(tscm->unit)->max_speed;
459 		unsigned int tx_init_skip_cycles;
460 
461 		err = set_stream_formats(tscm, rate);
462 		if (err < 0)
463 			goto error;
464 
465 		err = begin_session(tscm);
466 		if (err < 0)
467 			goto error;
468 
469 		err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
470 					      tscm->rx_resources.channel, spd);
471 		if (err < 0)
472 			goto error;
473 
474 		err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
475 					      tscm->tx_resources.channel, spd);
476 		if (err < 0)
477 			goto error;
478 
479 		if (tscm->need_long_tx_init_skip)
480 			tx_init_skip_cycles = 16000;
481 		else
482 			tx_init_skip_cycles = 0;
483 
484 		// MEMO: Just after starting packet streaming, it transfers packets without any
485 		// event. Enough after receiving the sequence of packets, it multiplexes events into
486 		// the packet. However, just after changing sampling transfer frequency, it stops
487 		// multiplexing during packet transmission. Enough after, it restarts multiplexing
488 		// again. The device ignores presentation time expressed by the value of syt field
489 		// of CIP header in received packets. The sequence of the number of data blocks per
490 		// packet is important for media clock recovery.
491 		err = amdtp_domain_start(&tscm->domain, tx_init_skip_cycles, true, true);
492 		if (err < 0)
493 			goto error;
494 
495 		if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) {
496 			err = -ETIMEDOUT;
497 			goto error;
498 		}
499 	}
500 
501 	return 0;
502 error:
503 	amdtp_domain_stop(&tscm->domain);
504 	finish_session(tscm);
505 
506 	return err;
507 }
508 
snd_tscm_stream_stop_duplex(struct snd_tscm * tscm)509 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
510 {
511 	if (tscm->substreams_counter == 0) {
512 		amdtp_domain_stop(&tscm->domain);
513 		finish_session(tscm);
514 
515 		fw_iso_resources_free(&tscm->tx_resources);
516 		fw_iso_resources_free(&tscm->rx_resources);
517 
518 		tscm->need_long_tx_init_skip = false;
519 	}
520 }
521 
snd_tscm_stream_lock_changed(struct snd_tscm * tscm)522 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
523 {
524 	tscm->dev_lock_changed = true;
525 	wake_up(&tscm->hwdep_wait);
526 }
527 
snd_tscm_stream_lock_try(struct snd_tscm * tscm)528 int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
529 {
530 	int err;
531 
532 	spin_lock_irq(&tscm->lock);
533 
534 	/* user land lock this */
535 	if (tscm->dev_lock_count < 0) {
536 		err = -EBUSY;
537 		goto end;
538 	}
539 
540 	/* this is the first time */
541 	if (tscm->dev_lock_count++ == 0)
542 		snd_tscm_stream_lock_changed(tscm);
543 	err = 0;
544 end:
545 	spin_unlock_irq(&tscm->lock);
546 	return err;
547 }
548 
snd_tscm_stream_lock_release(struct snd_tscm * tscm)549 void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
550 {
551 	spin_lock_irq(&tscm->lock);
552 
553 	if (WARN_ON(tscm->dev_lock_count <= 0))
554 		goto end;
555 	if (--tscm->dev_lock_count == 0)
556 		snd_tscm_stream_lock_changed(tscm);
557 end:
558 	spin_unlock_irq(&tscm->lock);
559 }
560