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  
14  struct reg_params {
15  	unsigned int count;
16  	unsigned int size;
17  };
18  
19  const 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  
snd_dice_stream_get_rate_mode(struct snd_dice * dice,unsigned int rate,enum snd_dice_rate_mode * mode)32  int 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  
select_clock(struct snd_dice * dice,unsigned int rate)60  static 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  
get_register_params(struct snd_dice * dice,struct reg_params * tx_params,struct reg_params * rx_params)101  static 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  
release_resources(struct snd_dice * dice)125  static 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  
stop_streams(struct snd_dice * dice,enum amdtp_stream_direction dir,struct reg_params * params)135  static 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  
keep_resources(struct snd_dice * dice,struct amdtp_stream * stream,struct fw_iso_resources * resources,unsigned int rate,unsigned int pcm_chs,unsigned int midi_ports)155  static 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  
keep_dual_resources(struct snd_dice * dice,unsigned int rate,enum amdtp_stream_direction dir,struct reg_params * params)197  static 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  
finish_session(struct snd_dice * dice,struct reg_params * tx_params,struct reg_params * rx_params)256  static 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  
snd_dice_stream_reserve_duplex(struct snd_dice * dice,unsigned int rate,unsigned int events_per_period,unsigned int events_per_buffer)265  int 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;
321  error:
322  	release_resources(dice);
323  	return err;
324  }
325  
start_streams(struct snd_dice * dice,enum amdtp_stream_direction dir,unsigned int rate,struct reg_params * params)326  static 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   */
snd_dice_stream_start_duplex(struct snd_dice * dice)382  int 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;
464  error:
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   */
snd_dice_stream_stop_duplex(struct snd_dice * dice)475  void 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  
init_stream(struct snd_dice * dice,enum amdtp_stream_direction dir,unsigned int index)488  static 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  	}
513  end:
514  	return err;
515  }
516  
517  /*
518   * This function should be called before starting streams or after stopping
519   * streams.
520   */
destroy_stream(struct snd_dice * dice,enum amdtp_stream_direction dir,unsigned int index)521  static 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  
snd_dice_stream_init_duplex(struct snd_dice * dice)540  int 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  	}
571  end:
572  	return err;
573  }
574  
snd_dice_stream_destroy_duplex(struct snd_dice * dice)575  void 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  
snd_dice_stream_update_duplex(struct snd_dice * dice)587  void 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  
snd_dice_stream_detect_current_formats(struct snd_dice * dice)609  int 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  
dice_lock_changed(struct snd_dice * dice)672  static void dice_lock_changed(struct snd_dice *dice)
673  {
674  	dice->dev_lock_changed = true;
675  	wake_up(&dice->hwdep_wait);
676  }
677  
snd_dice_stream_lock_try(struct snd_dice * dice)678  int 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;
692  out:
693  	spin_unlock_irq(&dice->lock);
694  	return err;
695  }
696  
snd_dice_stream_lock_release(struct snd_dice * dice)697  void 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);
706  out:
707  	spin_unlock_irq(&dice->lock);
708  }
709