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