Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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
14 const 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
27 int 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
44 static 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
61 static 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);
83 end:
84         return err;
85 }
86
87 static 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
98 static 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);
158 end:
159         return err;
160 }
161
162 static 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         }
185 end:
186         return err;
187 }
188
189 int 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         }
271 end:
272         return err;
273 }
274
275 void 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
286 static 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         }
310 end:
311         return err;
312 }
313
314 /*
315  * This function should be called before starting streams or after stopping
316  * streams.
317  */
318 static 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
331 int 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);
344 end:
345         return err;
346 }
347
348 void 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
358 void 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
377 static void dice_lock_changed(struct snd_dice *dice)
378 {
379         dice->dev_lock_changed = true;
380         wake_up(&dice->hwdep_wait);
381 }
382
383 int 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;
397 out:
398         spin_unlock_irq(&dice->lock);
399         return err;
400 }
401
402 void 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);
411 out:
412         spin_unlock_irq(&dice->lock);
413 }