2 * dice_stream.c - a part of driver for DICE based devices
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
7 * Licensed under the terms of the GNU General Public License, version 2.
12 #define CALLBACK_TIMEOUT 200
14 const unsigned int snd_dice_rates
[SND_DICE_RATES_COUNT
] = {
27 static void release_resources(struct snd_dice
*dice
,
28 struct fw_iso_resources
*resources
)
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
));
38 snd_dice_transaction_write_rx(dice
, RX_ISOCHRONOUS
,
39 &channel
, sizeof(channel
));
41 fw_iso_resources_free(resources
);
44 static int keep_resources(struct snd_dice
*dice
,
45 struct fw_iso_resources
*resources
,
46 unsigned int max_payload_bytes
)
51 err
= fw_iso_resources_allocate(resources
, max_payload_bytes
,
52 fw_parent_device(dice
->unit
)->max_speed
);
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
));
62 err
= snd_dice_transaction_write_rx(dice
, RX_ISOCHRONOUS
,
63 &channel
, sizeof(channel
));
65 release_resources(dice
, resources
);
70 static void stop_stream(struct snd_dice
*dice
, struct amdtp_stream
*stream
)
72 amdtp_stream_pcm_abort(stream
);
73 amdtp_stream_stop(stream
);
75 if (stream
== &dice
->tx_stream
)
76 release_resources(dice
, &dice
->tx_resources
);
78 release_resources(dice
, &dice
->rx_resources
);
81 static int start_stream(struct snd_dice
*dice
, struct amdtp_stream
*stream
,
84 struct fw_iso_resources
*resources
;
86 unsigned int i
, pcm_chs
, midi_ports
;
87 bool double_pcm_frames
;
90 if (stream
== &dice
->tx_stream
) {
91 resources
= &dice
->tx_resources
;
92 err
= snd_dice_transaction_read_tx(dice
, TX_NUMBER_AUDIO
,
95 resources
= &dice
->rx_resources
;
96 err
= snd_dice_transaction_read_rx(dice
, RX_NUMBER_AUDIO
,
103 pcm_chs
= be32_to_cpu(reg
[0]);
104 midi_ports
= be32_to_cpu(reg
[1]);
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
113 * For this quirk, blocking mode is required and PCM buffer size should
114 * be aligned to SYT_INTERVAL.
116 double_pcm_frames
= rate
> 96000;
117 if (double_pcm_frames
) {
122 err
= amdtp_am824_set_parameters(stream
, rate
, pcm_chs
, midi_ports
,
127 if (double_pcm_frames
) {
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
,
137 err
= keep_resources(dice
, resources
,
138 amdtp_stream_get_max_payload(stream
));
140 dev_err(&dice
->unit
->device
,
141 "fail to keep isochronous resources\n");
145 err
= amdtp_stream_start(stream
, resources
->channel
,
146 fw_parent_device(dice
->unit
)->max_speed
);
148 release_resources(dice
, resources
);
153 static int get_sync_mode(struct snd_dice
*dice
, enum cip_flags
*sync_mode
)
158 err
= snd_dice_transaction_get_clock_source(dice
, &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 */
169 case CLOCK_SOURCE_ARX1
: /* in 1st stream, which this driver uses */
173 *sync_mode
= CIP_SYNC_TO_DEVICE
;
180 int snd_dice_stream_start_duplex(struct snd_dice
*dice
, unsigned int rate
)
182 struct amdtp_stream
*master
, *slave
;
183 unsigned int curr_rate
;
184 enum cip_flags sync_mode
;
187 if (dice
->substreams_counter
== 0)
190 err
= get_sync_mode(dice
, &sync_mode
);
193 if (sync_mode
== CIP_SYNC_TO_DEVICE
) {
194 master
= &dice
->tx_stream
;
195 slave
= &dice
->rx_stream
;
197 master
= &dice
->rx_stream
;
198 slave
= &dice
->tx_stream
;
201 /* Some packet queueing errors. */
202 if (amdtp_streaming_error(master
) || amdtp_streaming_error(slave
))
203 stop_stream(dice
, master
);
205 /* Stop stream if rate is different. */
206 err
= snd_dice_transaction_get_rate(dice
, &curr_rate
);
208 dev_err(&dice
->unit
->device
,
209 "fail to get sampling rate\n");
214 if (rate
!= curr_rate
) {
219 if (!amdtp_stream_running(master
)) {
220 stop_stream(dice
, slave
);
221 snd_dice_transaction_clear_enable(dice
);
223 amdtp_stream_set_sync(sync_mode
, master
, slave
);
225 err
= snd_dice_transaction_set_rate(dice
, rate
);
227 dev_err(&dice
->unit
->device
,
228 "fail to set sampling rate\n");
232 /* Start both streams. */
233 err
= start_stream(dice
, master
, rate
);
235 dev_err(&dice
->unit
->device
,
236 "fail to start AMDTP master stream\n");
239 err
= start_stream(dice
, slave
, rate
);
241 dev_err(&dice
->unit
->device
,
242 "fail to start AMDTP slave stream\n");
243 stop_stream(dice
, master
);
246 err
= snd_dice_transaction_set_enable(dice
);
248 dev_err(&dice
->unit
->device
,
249 "fail to enable interface\n");
250 stop_stream(dice
, master
);
251 stop_stream(dice
, slave
);
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
);
268 void snd_dice_stream_stop_duplex(struct snd_dice
*dice
)
270 if (dice
->substreams_counter
> 0)
273 snd_dice_transaction_clear_enable(dice
);
275 stop_stream(dice
, &dice
->tx_stream
);
276 stop_stream(dice
, &dice
->rx_stream
);
279 static int init_stream(struct snd_dice
*dice
, struct amdtp_stream
*stream
)
282 struct fw_iso_resources
*resources
;
283 enum amdtp_stream_direction dir
;
285 if (stream
== &dice
->tx_stream
) {
286 resources
= &dice
->tx_resources
;
287 dir
= AMDTP_IN_STREAM
;
289 resources
= &dice
->rx_resources
;
290 dir
= AMDTP_OUT_STREAM
;
293 err
= fw_iso_resources_init(resources
, dice
->unit
);
296 resources
->channels_mask
= 0x00000000ffffffffuLL
;
298 err
= amdtp_am824_init(stream
, dice
->unit
, dir
, CIP_BLOCKING
);
300 amdtp_stream_destroy(stream
);
301 fw_iso_resources_destroy(resources
);
308 * This function should be called before starting streams or after stopping
311 static void destroy_stream(struct snd_dice
*dice
, struct amdtp_stream
*stream
)
313 struct fw_iso_resources
*resources
;
315 if (stream
== &dice
->tx_stream
)
316 resources
= &dice
->tx_resources
;
318 resources
= &dice
->rx_resources
;
320 amdtp_stream_destroy(stream
);
321 fw_iso_resources_destroy(resources
);
324 int snd_dice_stream_init_duplex(struct snd_dice
*dice
)
328 dice
->substreams_counter
= 0;
330 err
= init_stream(dice
, &dice
->tx_stream
);
334 err
= init_stream(dice
, &dice
->rx_stream
);
336 destroy_stream(dice
, &dice
->tx_stream
);
341 void snd_dice_stream_destroy_duplex(struct snd_dice
*dice
)
343 snd_dice_transaction_clear_enable(dice
);
345 destroy_stream(dice
, &dice
->tx_stream
);
346 destroy_stream(dice
, &dice
->rx_stream
);
348 dice
->substreams_counter
= 0;
351 void snd_dice_stream_update_duplex(struct snd_dice
*dice
)
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
361 dice
->global_enabled
= false;
363 stop_stream(dice
, &dice
->rx_stream
);
364 stop_stream(dice
, &dice
->tx_stream
);
366 fw_iso_resources_update(&dice
->rx_resources
);
367 fw_iso_resources_update(&dice
->tx_resources
);
370 static void dice_lock_changed(struct snd_dice
*dice
)
372 dice
->dev_lock_changed
= true;
373 wake_up(&dice
->hwdep_wait
);
376 int snd_dice_stream_lock_try(struct snd_dice
*dice
)
380 spin_lock_irq(&dice
->lock
);
382 if (dice
->dev_lock_count
< 0) {
387 if (dice
->dev_lock_count
++ == 0)
388 dice_lock_changed(dice
);
391 spin_unlock_irq(&dice
->lock
);
395 void snd_dice_stream_lock_release(struct snd_dice
*dice
)
397 spin_lock_irq(&dice
->lock
);
399 if (WARN_ON(dice
->dev_lock_count
<= 0))
402 if (--dice
->dev_lock_count
== 0)
403 dice_lock_changed(dice
);
405 spin_unlock_irq(&dice
->lock
);