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