Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * dice_stream.c - a part of driver for DICE based devices
  4 *
  5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
  6 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
  7 */
  8
  9#include "dice.h"
 10
 11#define	READY_TIMEOUT_MS	200
 12#define NOTIFICATION_TIMEOUT_MS	100
 13
 14struct reg_params {
 15	unsigned int count;
 16	unsigned int size;
 17};
 18
 19const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
 20	/* mode 0 */
 21	[0] =  32000,
 22	[1] =  44100,
 23	[2] =  48000,
 24	/* mode 1 */
 25	[3] =  88200,
 26	[4] =  96000,
 27	/* mode 2 */
 28	[5] = 176400,
 29	[6] = 192000,
 30};
 31
 32int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
 33				  enum snd_dice_rate_mode *mode)
 34{
 35	/* Corresponding to each entry in snd_dice_rates. */
 36	static const enum snd_dice_rate_mode modes[] = {
 37		[0] = SND_DICE_RATE_MODE_LOW,
 38		[1] = SND_DICE_RATE_MODE_LOW,
 39		[2] = SND_DICE_RATE_MODE_LOW,
 40		[3] = SND_DICE_RATE_MODE_MIDDLE,
 41		[4] = SND_DICE_RATE_MODE_MIDDLE,
 42		[5] = SND_DICE_RATE_MODE_HIGH,
 43		[6] = SND_DICE_RATE_MODE_HIGH,
 44	};
 45	int i;
 46
 47	for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
 48		if (!(dice->clock_caps & BIT(i)))
 49			continue;
 50		if (snd_dice_rates[i] != rate)
 51			continue;
 52
 53		*mode = modes[i];
 54		return 0;
 55	}
 56
 57	return -EINVAL;
 58}
 59
 60static int select_clock(struct snd_dice *dice, unsigned int rate)
 61{
 62	__be32 reg, new;
 63	u32 data;
 64	int i;
 65	int err;
 66
 67	err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT,
 68					       &reg, sizeof(reg));
 69	if (err < 0)
 70		return err;
 71
 72	data = be32_to_cpu(reg);
 73
 74	data &= ~CLOCK_RATE_MASK;
 75	for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
 76		if (snd_dice_rates[i] == rate)
 77			break;
 78	}
 79	if (i == ARRAY_SIZE(snd_dice_rates))
 80		return -EINVAL;
 81	data |= i << CLOCK_RATE_SHIFT;
 82
 83	if (completion_done(&dice->clock_accepted))
 84		reinit_completion(&dice->clock_accepted);
 85
 86	new = cpu_to_be32(data);
 87	err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
 88						&new, sizeof(new));
 89	if (err < 0)
 90		return err;
 91
 92	if (wait_for_completion_timeout(&dice->clock_accepted,
 93			msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) {
 94		if (reg != new)
 95			return -ETIMEDOUT;
 96	}
 97
 98	return 0;
 99}
100
101static int get_register_params(struct snd_dice *dice,
102			       struct reg_params *tx_params,
103			       struct reg_params *rx_params)
104{
105	__be32 reg[2];
106	int err;
107
108	err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, sizeof(reg));
109	if (err < 0)
110		return err;
111	tx_params->count =
112			min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
113	tx_params->size = be32_to_cpu(reg[1]) * 4;
114
115	err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, sizeof(reg));
116	if (err < 0)
117		return err;
118	rx_params->count =
119			min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
120	rx_params->size = be32_to_cpu(reg[1]) * 4;
121
122	return 0;
123}
124
125static void release_resources(struct snd_dice *dice)
126{
127	int i;
128
129	for (i = 0; i < MAX_STREAMS; ++i) {
130		fw_iso_resources_free(&dice->tx_resources[i]);
131		fw_iso_resources_free(&dice->rx_resources[i]);
132	}
133}
134
135static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
136			 struct reg_params *params)
137{
138	__be32 reg;
139	unsigned int i;
140
141	for (i = 0; i < params->count; i++) {
142		reg = cpu_to_be32((u32)-1);
143		if (dir == AMDTP_IN_STREAM) {
144			snd_dice_transaction_write_tx(dice,
145					params->size * i + TX_ISOCHRONOUS,
146					&reg, sizeof(reg));
147		} else {
148			snd_dice_transaction_write_rx(dice,
149					params->size * i + RX_ISOCHRONOUS,
150					&reg, sizeof(reg));
151		}
152	}
153}
154
155static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream,
156			  struct fw_iso_resources *resources, unsigned int rate,
157			  unsigned int pcm_chs, unsigned int midi_ports)
158{
159	bool double_pcm_frames;
160	unsigned int i;
161	int err;
162
163	// At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
164	// one data block of AMDTP packet. Thus sampling transfer frequency is
165	// a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
166	// transferred on AMDTP packets at 96 kHz. Two successive samples of a
167	// channel are stored consecutively in the packet. This quirk is called
168	// as 'Dual Wire'.
169	// For this quirk, blocking mode is required and PCM buffer size should
170	// be aligned to SYT_INTERVAL.
171	double_pcm_frames = (rate > 96000 && !dice->disable_double_pcm_frames);
172	if (double_pcm_frames) {
173		rate /= 2;
174		pcm_chs *= 2;
175	}
176
177	err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports,
178					 double_pcm_frames);
179	if (err < 0)
180		return err;
181
182	if (double_pcm_frames) {
183		pcm_chs /= 2;
184
185		for (i = 0; i < pcm_chs; i++) {
186			amdtp_am824_set_pcm_position(stream, i, i * 2);
187			amdtp_am824_set_pcm_position(stream, i + pcm_chs,
188						     i * 2 + 1);
189		}
190	}
191
192	return fw_iso_resources_allocate(resources,
193				amdtp_stream_get_max_payload(stream),
194				fw_parent_device(dice->unit)->max_speed);
195}
196
197static int keep_dual_resources(struct snd_dice *dice, unsigned int rate,
198			       enum amdtp_stream_direction dir,
199			       struct reg_params *params)
200{
201	enum snd_dice_rate_mode mode;
202	int i;
203	int err;
204
205	err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
206	if (err < 0)
207		return err;
208
209	for (i = 0; i < params->count; ++i) {
210		__be32 reg[2];
211		struct amdtp_stream *stream;
212		struct fw_iso_resources *resources;
213		unsigned int pcm_cache;
214		unsigned int pcm_chs;
215		unsigned int midi_ports;
216
217		if (dir == AMDTP_IN_STREAM) {
218			stream = &dice->tx_stream[i];
219			resources = &dice->tx_resources[i];
220
221			pcm_cache = dice->tx_pcm_chs[i][mode];
222			err = snd_dice_transaction_read_tx(dice,
223					params->size * i + TX_NUMBER_AUDIO,
224					reg, sizeof(reg));
225		} else {
226			stream = &dice->rx_stream[i];
227			resources = &dice->rx_resources[i];
228
229			pcm_cache = dice->rx_pcm_chs[i][mode];
230			err = snd_dice_transaction_read_rx(dice,
231					params->size * i + RX_NUMBER_AUDIO,
232					reg, sizeof(reg));
233		}
234		if (err < 0)
235			return err;
236		pcm_chs = be32_to_cpu(reg[0]);
237		midi_ports = be32_to_cpu(reg[1]);
238
239		// These are important for developer of this driver.
240		if (pcm_chs != pcm_cache) {
241			dev_info(&dice->unit->device,
242				 "cache mismatch: pcm: %u:%u, midi: %u\n",
243				 pcm_chs, pcm_cache, midi_ports);
244			return -EPROTO;
245		}
246
247		err = keep_resources(dice, stream, resources, rate, pcm_chs,
248				     midi_ports);
249		if (err < 0)
250			return err;
251	}
252
253	return 0;
254}
255
256static void finish_session(struct snd_dice *dice, struct reg_params *tx_params,
257			   struct reg_params *rx_params)
258{
259	stop_streams(dice, AMDTP_IN_STREAM, tx_params);
260	stop_streams(dice, AMDTP_OUT_STREAM, rx_params);
261
262	snd_dice_transaction_clear_enable(dice);
263}
264
265int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate,
266				   unsigned int events_per_period,
267				   unsigned int events_per_buffer)
268{
269	unsigned int curr_rate;
270	int err;
271
272	// Check sampling transmission frequency.
273	err = snd_dice_transaction_get_rate(dice, &curr_rate);
274	if (err < 0)
275		return err;
276	if (rate == 0)
277		rate = curr_rate;
278
279	if (dice->substreams_counter == 0 || curr_rate != rate) {
280		struct reg_params tx_params, rx_params;
281
282		amdtp_domain_stop(&dice->domain);
283
284		err = get_register_params(dice, &tx_params, &rx_params);
285		if (err < 0)
286			return err;
287		finish_session(dice, &tx_params, &rx_params);
288
289		release_resources(dice);
290
291		// Just after owning the unit (GLOBAL_OWNER), the unit can
292		// return invalid stream formats. Selecting clock parameters
293		// have an effect for the unit to refine it.
294		err = select_clock(dice, rate);
295		if (err < 0)
296			return err;
297
298		// After changing sampling transfer frequency, the value of
299		// register can be changed.
300		err = get_register_params(dice, &tx_params, &rx_params);
301		if (err < 0)
302			return err;
303
304		err = keep_dual_resources(dice, rate, AMDTP_IN_STREAM,
305					  &tx_params);
306		if (err < 0)
307			goto error;
308
309		err = keep_dual_resources(dice, rate, AMDTP_OUT_STREAM,
310					  &rx_params);
311		if (err < 0)
312			goto error;
313
314		err = amdtp_domain_set_events_per_period(&dice->domain,
315					events_per_period, events_per_buffer);
316		if (err < 0)
317			goto error;
318	}
319
320	return 0;
321error:
322	release_resources(dice);
323	return err;
324}
325
326static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
327			 unsigned int rate, struct reg_params *params)
328{
329	unsigned int max_speed = fw_parent_device(dice->unit)->max_speed;
330	int i;
331	int err;
332
333	for (i = 0; i < params->count; i++) {
334		struct amdtp_stream *stream;
335		struct fw_iso_resources *resources;
336		__be32 reg;
337
338		if (dir == AMDTP_IN_STREAM) {
339			stream = dice->tx_stream + i;
340			resources = dice->tx_resources + i;
341		} else {
342			stream = dice->rx_stream + i;
343			resources = dice->rx_resources + i;
344		}
345
346		reg = cpu_to_be32(resources->channel);
347		if (dir == AMDTP_IN_STREAM) {
348			err = snd_dice_transaction_write_tx(dice,
349					params->size * i + TX_ISOCHRONOUS,
350					&reg, sizeof(reg));
351		} else {
352			err = snd_dice_transaction_write_rx(dice,
353					params->size * i + RX_ISOCHRONOUS,
354					&reg, sizeof(reg));
355		}
356		if (err < 0)
357			return err;
358
359		if (dir == AMDTP_IN_STREAM) {
360			reg = cpu_to_be32(max_speed);
361			err = snd_dice_transaction_write_tx(dice,
362					params->size * i + TX_SPEED,
363					&reg, sizeof(reg));
364			if (err < 0)
365				return err;
366		}
367
368		err = amdtp_domain_add_stream(&dice->domain, stream,
369					      resources->channel, max_speed);
370		if (err < 0)
371			return err;
372	}
373
374	return 0;
375}
376
377/*
378 * MEMO: After this function, there're two states of streams:
379 *  - None streams are running.
380 *  - All streams are running.
381 */
382int snd_dice_stream_start_duplex(struct snd_dice *dice)
383{
384	unsigned int generation = dice->rx_resources[0].generation;
385	struct reg_params tx_params, rx_params;
386	unsigned int i;
387	unsigned int rate;
388	enum snd_dice_rate_mode mode;
389	int err;
390
391	if (dice->substreams_counter == 0)
392		return -EIO;
393
394	err = get_register_params(dice, &tx_params, &rx_params);
395	if (err < 0)
396		return err;
397
398	// Check error of packet streaming.
399	for (i = 0; i < MAX_STREAMS; ++i) {
400		if (amdtp_streaming_error(&dice->tx_stream[i]) ||
401		    amdtp_streaming_error(&dice->rx_stream[i])) {
402			amdtp_domain_stop(&dice->domain);
403			finish_session(dice, &tx_params, &rx_params);
404			break;
405		}
406	}
407
408	if (generation != fw_parent_device(dice->unit)->card->generation) {
409		for (i = 0; i < MAX_STREAMS; ++i) {
410			if (i < tx_params.count)
411				fw_iso_resources_update(dice->tx_resources + i);
412			if (i < rx_params.count)
413				fw_iso_resources_update(dice->rx_resources + i);
414		}
415	}
416
417	// Check required streams are running or not.
418	err = snd_dice_transaction_get_rate(dice, &rate);
419	if (err < 0)
420		return err;
421	err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
422	if (err < 0)
423		return err;
424	for (i = 0; i < MAX_STREAMS; ++i) {
425		if (dice->tx_pcm_chs[i][mode] > 0 &&
426		    !amdtp_stream_running(&dice->tx_stream[i]))
427			break;
428		if (dice->rx_pcm_chs[i][mode] > 0 &&
429		    !amdtp_stream_running(&dice->rx_stream[i]))
430			break;
431	}
432	if (i < MAX_STREAMS) {
433		// Start both streams.
434		err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params);
435		if (err < 0)
436			goto error;
437
438		err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params);
439		if (err < 0)
440			goto error;
441
442		err = snd_dice_transaction_set_enable(dice);
443		if (err < 0) {
444			dev_err(&dice->unit->device,
445				"fail to enable interface\n");
446			goto error;
447		}
448
449		// MEMO: The device immediately starts packet transmission when enabled. Some
450		// devices are strictly to generate any discontinuity in the sequence of tx packet
451		// when they receives invalid sequence of presentation time in CIP header. The
452		// sequence replay for media clock recovery can suppress the behaviour.
453		err = amdtp_domain_start(&dice->domain, 0, true, false);
454		if (err < 0)
455			goto error;
456
457		if (!amdtp_domain_wait_ready(&dice->domain, READY_TIMEOUT_MS)) {
458			err = -ETIMEDOUT;
459			goto error;
460		}
461	}
462
463	return 0;
464error:
465	amdtp_domain_stop(&dice->domain);
466	finish_session(dice, &tx_params, &rx_params);
467	return err;
468}
469
470/*
471 * MEMO: After this function, there're two states of streams:
472 *  - None streams are running.
473 *  - All streams are running.
474 */
475void snd_dice_stream_stop_duplex(struct snd_dice *dice)
476{
477	struct reg_params tx_params, rx_params;
478
479	if (dice->substreams_counter == 0) {
480		if (get_register_params(dice, &tx_params, &rx_params) >= 0)
481			finish_session(dice, &tx_params, &rx_params);
482
483		amdtp_domain_stop(&dice->domain);
484		release_resources(dice);
485	}
486}
487
488static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir,
489		       unsigned int index)
490{
491	struct amdtp_stream *stream;
492	struct fw_iso_resources *resources;
493	int err;
494
495	if (dir == AMDTP_IN_STREAM) {
496		stream = &dice->tx_stream[index];
497		resources = &dice->tx_resources[index];
498	} else {
499		stream = &dice->rx_stream[index];
500		resources = &dice->rx_resources[index];
501	}
502
503	err = fw_iso_resources_init(resources, dice->unit);
504	if (err < 0)
505		goto end;
506	resources->channels_mask = 0x00000000ffffffffuLL;
507
508	err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING);
509	if (err < 0) {
510		amdtp_stream_destroy(stream);
511		fw_iso_resources_destroy(resources);
512	}
513end:
514	return err;
515}
516
517/*
518 * This function should be called before starting streams or after stopping
519 * streams.
520 */
521static void destroy_stream(struct snd_dice *dice,
522			   enum amdtp_stream_direction dir,
523			   unsigned int index)
524{
525	struct amdtp_stream *stream;
526	struct fw_iso_resources *resources;
527
528	if (dir == AMDTP_IN_STREAM) {
529		stream = &dice->tx_stream[index];
530		resources = &dice->tx_resources[index];
531	} else {
532		stream = &dice->rx_stream[index];
533		resources = &dice->rx_resources[index];
534	}
535
536	amdtp_stream_destroy(stream);
537	fw_iso_resources_destroy(resources);
538}
539
540int snd_dice_stream_init_duplex(struct snd_dice *dice)
541{
542	int i, err;
543
544	for (i = 0; i < MAX_STREAMS; i++) {
545		err = init_stream(dice, AMDTP_IN_STREAM, i);
546		if (err < 0) {
547			for (; i >= 0; i--)
548				destroy_stream(dice, AMDTP_IN_STREAM, i);
549			goto end;
550		}
551	}
552
553	for (i = 0; i < MAX_STREAMS; i++) {
554		err = init_stream(dice, AMDTP_OUT_STREAM, i);
555		if (err < 0) {
556			for (; i >= 0; i--)
557				destroy_stream(dice, AMDTP_OUT_STREAM, i);
558			for (i = 0; i < MAX_STREAMS; i++)
559				destroy_stream(dice, AMDTP_IN_STREAM, i);
560			goto end;
561		}
562	}
563
564	err = amdtp_domain_init(&dice->domain);
565	if (err < 0) {
566		for (i = 0; i < MAX_STREAMS; ++i) {
567			destroy_stream(dice, AMDTP_OUT_STREAM, i);
568			destroy_stream(dice, AMDTP_IN_STREAM, i);
569		}
570	}
571end:
572	return err;
573}
574
575void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
576{
577	unsigned int i;
578
579	for (i = 0; i < MAX_STREAMS; i++) {
580		destroy_stream(dice, AMDTP_IN_STREAM, i);
581		destroy_stream(dice, AMDTP_OUT_STREAM, i);
582	}
583
584	amdtp_domain_destroy(&dice->domain);
585}
586
587void snd_dice_stream_update_duplex(struct snd_dice *dice)
588{
589	struct reg_params tx_params, rx_params;
590
591	/*
592	 * On a bus reset, the DICE firmware disables streaming and then goes
593	 * off contemplating its own navel for hundreds of milliseconds before
594	 * it can react to any of our attempts to reenable streaming.  This
595	 * means that we lose synchronization anyway, so we force our streams
596	 * to stop so that the application can restart them in an orderly
597	 * manner.
598	 */
599	dice->global_enabled = false;
600
601	if (get_register_params(dice, &tx_params, &rx_params) == 0) {
602		amdtp_domain_stop(&dice->domain);
603
604		stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
605		stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
606	}
607}
608
609int snd_dice_stream_detect_current_formats(struct snd_dice *dice)
610{
611	unsigned int rate;
612	enum snd_dice_rate_mode mode;
613	__be32 reg[2];
614	struct reg_params tx_params, rx_params;
615	int i;
616	int err;
617
618	/* If extended protocol is available, detect detail spec. */
619	err = snd_dice_detect_extension_formats(dice);
620	if (err >= 0)
621		return err;
622
623	/*
624	 * Available stream format is restricted at current mode of sampling
625	 * clock.
626	 */
627	err = snd_dice_transaction_get_rate(dice, &rate);
628	if (err < 0)
629		return err;
630
631	err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
632	if (err < 0)
633		return err;
634
635	/*
636	 * Just after owning the unit (GLOBAL_OWNER), the unit can return
637	 * invalid stream formats. Selecting clock parameters have an effect
638	 * for the unit to refine it.
639	 */
640	err = select_clock(dice, rate);
641	if (err < 0)
642		return err;
643
644	err = get_register_params(dice, &tx_params, &rx_params);
645	if (err < 0)
646		return err;
647
648	for (i = 0; i < tx_params.count; ++i) {
649		err = snd_dice_transaction_read_tx(dice,
650				tx_params.size * i + TX_NUMBER_AUDIO,
651				reg, sizeof(reg));
652		if (err < 0)
653			return err;
654		dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]);
655		dice->tx_midi_ports[i] = max_t(unsigned int,
656				be32_to_cpu(reg[1]), dice->tx_midi_ports[i]);
657	}
658	for (i = 0; i < rx_params.count; ++i) {
659		err = snd_dice_transaction_read_rx(dice,
660				rx_params.size * i + RX_NUMBER_AUDIO,
661				reg, sizeof(reg));
662		if (err < 0)
663			return err;
664		dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]);
665		dice->rx_midi_ports[i] = max_t(unsigned int,
666				be32_to_cpu(reg[1]), dice->rx_midi_ports[i]);
667	}
668
669	return 0;
670}
671
672static void dice_lock_changed(struct snd_dice *dice)
673{
674	dice->dev_lock_changed = true;
675	wake_up(&dice->hwdep_wait);
676}
677
678int snd_dice_stream_lock_try(struct snd_dice *dice)
679{
680	int err;
681
682	spin_lock_irq(&dice->lock);
683
684	if (dice->dev_lock_count < 0) {
685		err = -EBUSY;
686		goto out;
687	}
688
689	if (dice->dev_lock_count++ == 0)
690		dice_lock_changed(dice);
691	err = 0;
692out:
693	spin_unlock_irq(&dice->lock);
694	return err;
695}
696
697void snd_dice_stream_lock_release(struct snd_dice *dice)
698{
699	spin_lock_irq(&dice->lock);
700
701	if (WARN_ON(dice->dev_lock_count <= 0))
702		goto out;
703
704	if (--dice->dev_lock_count == 0)
705		dice_lock_changed(dice);
706out:
707	spin_unlock_irq(&dice->lock);
708}