1/*
2 * dice_stream.c - a part of driver for DICE based devices
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10#include "dice.h"
11
12#define	CALLBACK_TIMEOUT	200
13
14const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
15	/* mode 0 */
16	[0] =  32000,
17	[1] =  44100,
18	[2] =  48000,
19	/* mode 1 */
20	[3] =  88200,
21	[4] =  96000,
22	/* mode 2 */
23	[5] = 176400,
24	[6] = 192000,
25};
26
27int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
28				  unsigned int *mode)
29{
30	int i;
31
32	for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
33		if (!(dice->clock_caps & BIT(i)))
34			continue;
35		if (snd_dice_rates[i] != rate)
36			continue;
37
38		*mode = (i - 1) / 2;
39		return 0;
40	}
41	return -EINVAL;
42}
43
44static void release_resources(struct snd_dice *dice,
45			      struct fw_iso_resources *resources)
46{
47	unsigned int channel;
48
49	/* Reset channel number */
50	channel = cpu_to_be32((u32)-1);
51	if (resources == &dice->tx_resources)
52		snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
53					      &channel, 4);
54	else
55		snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
56					      &channel, 4);
57
58	fw_iso_resources_free(resources);
59}
60
61static int keep_resources(struct snd_dice *dice,
62			  struct fw_iso_resources *resources,
63			  unsigned int max_payload_bytes)
64{
65	unsigned int channel;
66	int err;
67
68	err = fw_iso_resources_allocate(resources, max_payload_bytes,
69				fw_parent_device(dice->unit)->max_speed);
70	if (err < 0)
71		goto end;
72
73	/* Set channel number */
74	channel = cpu_to_be32(resources->channel);
75	if (resources == &dice->tx_resources)
76		err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
77						    &channel, 4);
78	else
79		err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
80						    &channel, 4);
81	if (err < 0)
82		release_resources(dice, resources);
83end:
84	return err;
85}
86
87static void stop_stream(struct snd_dice *dice, struct amdtp_stream *stream)
88{
89	amdtp_stream_pcm_abort(stream);
90	amdtp_stream_stop(stream);
91
92	if (stream == &dice->tx_stream)
93		release_resources(dice, &dice->tx_resources);
94	else
95		release_resources(dice, &dice->rx_resources);
96}
97
98static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
99			unsigned int rate)
100{
101	struct fw_iso_resources *resources;
102	unsigned int i, mode, pcm_chs, midi_ports;
103	int err;
104
105	err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
106	if (err < 0)
107		goto end;
108	if (stream == &dice->tx_stream) {
109		resources = &dice->tx_resources;
110		pcm_chs = dice->tx_channels[mode];
111		midi_ports = dice->tx_midi_ports[mode];
112	} else {
113		resources = &dice->rx_resources;
114		pcm_chs = dice->rx_channels[mode];
115		midi_ports = dice->rx_midi_ports[mode];
116	}
117
118	/*
119	 * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
120	 * one data block of AMDTP packet. Thus sampling transfer frequency is
121	 * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
122	 * transferred on AMDTP packets at 96 kHz. Two successive samples of a
123	 * channel are stored consecutively in the packet. This quirk is called
124	 * as 'Dual Wire'.
125	 * For this quirk, blocking mode is required and PCM buffer size should
126	 * be aligned to SYT_INTERVAL.
127	 */
128	if (mode > 1) {
129		rate /= 2;
130		pcm_chs *= 2;
131		stream->double_pcm_frames = true;
132	} else {
133		stream->double_pcm_frames = false;
134	}
135
136	amdtp_stream_set_parameters(stream, rate, pcm_chs, midi_ports);
137	if (mode > 1) {
138		pcm_chs /= 2;
139
140		for (i = 0; i < pcm_chs; i++) {
141			stream->pcm_positions[i] = i * 2;
142			stream->pcm_positions[i + pcm_chs] = i * 2 + 1;
143		}
144	}
145
146	err = keep_resources(dice, resources,
147			     amdtp_stream_get_max_payload(stream));
148	if (err < 0) {
149		dev_err(&dice->unit->device,
150			"fail to keep isochronous resources\n");
151		goto end;
152	}
153
154	err = amdtp_stream_start(stream, resources->channel,
155				 fw_parent_device(dice->unit)->max_speed);
156	if (err < 0)
157		release_resources(dice, resources);
158end:
159	return err;
160}
161
162static int get_sync_mode(struct snd_dice *dice, enum cip_flags *sync_mode)
163{
164	u32 source;
165	int err;
166
167	err = snd_dice_transaction_get_clock_source(dice, &source);
168	if (err < 0)
169		goto end;
170
171	switch (source) {
172	/* So-called 'SYT Match' modes, sync_to_syt value of packets received */
173	case CLOCK_SOURCE_ARX4:	/* in 4th stream */
174	case CLOCK_SOURCE_ARX3:	/* in 3rd stream */
175	case CLOCK_SOURCE_ARX2:	/* in 2nd stream */
176		err = -ENOSYS;
177		break;
178	case CLOCK_SOURCE_ARX1:	/* in 1st stream, which this driver uses */
179		*sync_mode = 0;
180		break;
181	default:
182		*sync_mode = CIP_SYNC_TO_DEVICE;
183		break;
184	}
185end:
186	return err;
187}
188
189int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
190{
191	struct amdtp_stream *master, *slave;
192	unsigned int curr_rate;
193	enum cip_flags sync_mode;
194	int err = 0;
195
196	if (dice->substreams_counter == 0)
197		goto end;
198
199	err = get_sync_mode(dice, &sync_mode);
200	if (err < 0)
201		goto end;
202	if (sync_mode == CIP_SYNC_TO_DEVICE) {
203		master = &dice->tx_stream;
204		slave  = &dice->rx_stream;
205	} else {
206		master = &dice->rx_stream;
207		slave  = &dice->tx_stream;
208	}
209
210	/* Some packet queueing errors. */
211	if (amdtp_streaming_error(master) || amdtp_streaming_error(slave))
212		stop_stream(dice, master);
213
214	/* Stop stream if rate is different. */
215	err = snd_dice_transaction_get_rate(dice, &curr_rate);
216	if (err < 0) {
217		dev_err(&dice->unit->device,
218			"fail to get sampling rate\n");
219		goto end;
220	}
221	if (rate == 0)
222		rate = curr_rate;
223	if (rate != curr_rate)
224		stop_stream(dice, master);
225
226	if (!amdtp_stream_running(master)) {
227		stop_stream(dice, slave);
228		snd_dice_transaction_clear_enable(dice);
229
230		amdtp_stream_set_sync(sync_mode, master, slave);
231
232		err = snd_dice_transaction_set_rate(dice, rate);
233		if (err < 0) {
234			dev_err(&dice->unit->device,
235				"fail to set sampling rate\n");
236			goto end;
237		}
238
239		/* Start both streams. */
240		err = start_stream(dice, master, rate);
241		if (err < 0) {
242			dev_err(&dice->unit->device,
243				"fail to start AMDTP master stream\n");
244			goto end;
245		}
246		err = start_stream(dice, slave, rate);
247		if (err < 0) {
248			dev_err(&dice->unit->device,
249				"fail to start AMDTP slave stream\n");
250			stop_stream(dice, master);
251			goto end;
252		}
253		err = snd_dice_transaction_set_enable(dice);
254		if (err < 0) {
255			dev_err(&dice->unit->device,
256				"fail to enable interface\n");
257			stop_stream(dice, master);
258			stop_stream(dice, slave);
259			goto end;
260		}
261
262		/* Wait first callbacks */
263		if (!amdtp_stream_wait_callback(master, CALLBACK_TIMEOUT) ||
264		    !amdtp_stream_wait_callback(slave, CALLBACK_TIMEOUT)) {
265			snd_dice_transaction_clear_enable(dice);
266			stop_stream(dice, master);
267			stop_stream(dice, slave);
268			err = -ETIMEDOUT;
269		}
270	}
271end:
272	return err;
273}
274
275void snd_dice_stream_stop_duplex(struct snd_dice *dice)
276{
277	if (dice->substreams_counter > 0)
278		return;
279
280	snd_dice_transaction_clear_enable(dice);
281
282	stop_stream(dice, &dice->tx_stream);
283	stop_stream(dice, &dice->rx_stream);
284}
285
286static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
287{
288	int err;
289	struct fw_iso_resources *resources;
290	enum amdtp_stream_direction dir;
291
292	if (stream == &dice->tx_stream) {
293		resources = &dice->tx_resources;
294		dir = AMDTP_IN_STREAM;
295	} else {
296		resources = &dice->rx_resources;
297		dir = AMDTP_OUT_STREAM;
298	}
299
300	err = fw_iso_resources_init(resources, dice->unit);
301	if (err < 0)
302		goto end;
303	resources->channels_mask = 0x00000000ffffffffuLL;
304
305	err = amdtp_stream_init(stream, dice->unit, dir, CIP_BLOCKING);
306	if (err < 0) {
307		amdtp_stream_destroy(stream);
308		fw_iso_resources_destroy(resources);
309	}
310end:
311	return err;
312}
313
314/*
315 * This function should be called before starting streams or after stopping
316 * streams.
317 */
318static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
319{
320	struct fw_iso_resources *resources;
321
322	if (stream == &dice->tx_stream)
323		resources = &dice->tx_resources;
324	else
325		resources = &dice->rx_resources;
326
327	amdtp_stream_destroy(stream);
328	fw_iso_resources_destroy(resources);
329}
330
331int snd_dice_stream_init_duplex(struct snd_dice *dice)
332{
333	int err;
334
335	dice->substreams_counter = 0;
336
337	err = init_stream(dice, &dice->tx_stream);
338	if (err < 0)
339		goto end;
340
341	err = init_stream(dice, &dice->rx_stream);
342	if (err < 0)
343		destroy_stream(dice, &dice->tx_stream);
344end:
345	return err;
346}
347
348void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
349{
350	snd_dice_transaction_clear_enable(dice);
351
352	destroy_stream(dice, &dice->tx_stream);
353	destroy_stream(dice, &dice->rx_stream);
354
355	dice->substreams_counter = 0;
356}
357
358void snd_dice_stream_update_duplex(struct snd_dice *dice)
359{
360	/*
361	 * On a bus reset, the DICE firmware disables streaming and then goes
362	 * off contemplating its own navel for hundreds of milliseconds before
363	 * it can react to any of our attempts to reenable streaming.  This
364	 * means that we lose synchronization anyway, so we force our streams
365	 * to stop so that the application can restart them in an orderly
366	 * manner.
367	 */
368	dice->global_enabled = false;
369
370	stop_stream(dice, &dice->rx_stream);
371	stop_stream(dice, &dice->tx_stream);
372
373	fw_iso_resources_update(&dice->rx_resources);
374	fw_iso_resources_update(&dice->tx_resources);
375}
376
377static void dice_lock_changed(struct snd_dice *dice)
378{
379	dice->dev_lock_changed = true;
380	wake_up(&dice->hwdep_wait);
381}
382
383int snd_dice_stream_lock_try(struct snd_dice *dice)
384{
385	int err;
386
387	spin_lock_irq(&dice->lock);
388
389	if (dice->dev_lock_count < 0) {
390		err = -EBUSY;
391		goto out;
392	}
393
394	if (dice->dev_lock_count++ == 0)
395		dice_lock_changed(dice);
396	err = 0;
397out:
398	spin_unlock_irq(&dice->lock);
399	return err;
400}
401
402void snd_dice_stream_lock_release(struct snd_dice *dice)
403{
404	spin_lock_irq(&dice->lock);
405
406	if (WARN_ON(dice->dev_lock_count <= 0))
407		goto out;
408
409	if (--dice->dev_lock_count == 0)
410		dice_lock_changed(dice);
411out:
412	spin_unlock_irq(&dice->lock);
413}
414