1 // SPDX-License-Identifier: GPL-2.0-only
3 * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family
5 * Copyright (c) 2014-2015 Takashi Sakamoto
10 #define CALLBACK_TIMEOUT 500
12 const unsigned int snd_dg00x_stream_rates
[SND_DG00X_RATE_COUNT
] = {
13 [SND_DG00X_RATE_44100
] = 44100,
14 [SND_DG00X_RATE_48000
] = 48000,
15 [SND_DG00X_RATE_88200
] = 88200,
16 [SND_DG00X_RATE_96000
] = 96000,
19 /* Multi Bit Linear Audio data channels for each sampling transfer frequency. */
21 snd_dg00x_stream_pcm_channels
[SND_DG00X_RATE_COUNT
] = {
22 /* Analog/ADAT/SPDIF */
23 [SND_DG00X_RATE_44100
] = (8 + 8 + 2),
24 [SND_DG00X_RATE_48000
] = (8 + 8 + 2),
26 [SND_DG00X_RATE_88200
] = (8 + 2),
27 [SND_DG00X_RATE_96000
] = (8 + 2),
30 int snd_dg00x_stream_get_local_rate(struct snd_dg00x
*dg00x
, unsigned int *rate
)
36 err
= snd_fw_transaction(dg00x
->unit
, TCODE_READ_QUADLET_REQUEST
,
37 DG00X_ADDR_BASE
+ DG00X_OFFSET_LOCAL_RATE
,
38 ®
, sizeof(reg
), 0);
42 data
= be32_to_cpu(reg
) & 0x0f;
43 if (data
< ARRAY_SIZE(snd_dg00x_stream_rates
))
44 *rate
= snd_dg00x_stream_rates
[data
];
51 int snd_dg00x_stream_set_local_rate(struct snd_dg00x
*dg00x
, unsigned int rate
)
56 for (i
= 0; i
< ARRAY_SIZE(snd_dg00x_stream_rates
); i
++) {
57 if (rate
== snd_dg00x_stream_rates
[i
])
60 if (i
== ARRAY_SIZE(snd_dg00x_stream_rates
))
64 return snd_fw_transaction(dg00x
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
65 DG00X_ADDR_BASE
+ DG00X_OFFSET_LOCAL_RATE
,
66 ®
, sizeof(reg
), 0);
69 int snd_dg00x_stream_get_clock(struct snd_dg00x
*dg00x
,
70 enum snd_dg00x_clock
*clock
)
75 err
= snd_fw_transaction(dg00x
->unit
, TCODE_READ_QUADLET_REQUEST
,
76 DG00X_ADDR_BASE
+ DG00X_OFFSET_CLOCK_SOURCE
,
77 ®
, sizeof(reg
), 0);
81 *clock
= be32_to_cpu(reg
) & 0x0f;
82 if (*clock
>= SND_DG00X_CLOCK_COUNT
)
88 int snd_dg00x_stream_check_external_clock(struct snd_dg00x
*dg00x
, bool *detect
)
93 err
= snd_fw_transaction(dg00x
->unit
, TCODE_READ_QUADLET_REQUEST
,
94 DG00X_ADDR_BASE
+ DG00X_OFFSET_DETECT_EXTERNAL
,
95 ®
, sizeof(reg
), 0);
97 *detect
= be32_to_cpu(reg
) > 0;
102 int snd_dg00x_stream_get_external_rate(struct snd_dg00x
*dg00x
,
109 err
= snd_fw_transaction(dg00x
->unit
, TCODE_READ_QUADLET_REQUEST
,
110 DG00X_ADDR_BASE
+ DG00X_OFFSET_EXTERNAL_RATE
,
111 ®
, sizeof(reg
), 0);
115 data
= be32_to_cpu(reg
) & 0x0f;
116 if (data
< ARRAY_SIZE(snd_dg00x_stream_rates
))
117 *rate
= snd_dg00x_stream_rates
[data
];
118 /* This means desync. */
125 static void finish_session(struct snd_dg00x
*dg00x
)
129 data
= cpu_to_be32(0x00000003);
130 snd_fw_transaction(dg00x
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
131 DG00X_ADDR_BASE
+ DG00X_OFFSET_STREAMING_SET
,
132 &data
, sizeof(data
), 0);
134 // Unregister isochronous channels for both direction.
136 snd_fw_transaction(dg00x
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
137 DG00X_ADDR_BASE
+ DG00X_OFFSET_ISOC_CHANNELS
,
138 &data
, sizeof(data
), 0);
140 // Just after finishing the session, the device may lost transmitting
141 // functionality for a short time.
145 static int begin_session(struct snd_dg00x
*dg00x
)
151 // Register isochronous channels for both direction.
152 data
= cpu_to_be32((dg00x
->tx_resources
.channel
<< 16) |
153 dg00x
->rx_resources
.channel
);
154 err
= snd_fw_transaction(dg00x
->unit
, TCODE_WRITE_QUADLET_REQUEST
,
155 DG00X_ADDR_BASE
+ DG00X_OFFSET_ISOC_CHANNELS
,
156 &data
, sizeof(data
), 0);
160 err
= snd_fw_transaction(dg00x
->unit
, TCODE_READ_QUADLET_REQUEST
,
161 DG00X_ADDR_BASE
+ DG00X_OFFSET_STREAMING_STATE
,
162 &data
, sizeof(data
), 0);
165 curr
= be32_to_cpu(data
);
172 data
= cpu_to_be32(curr
);
173 err
= snd_fw_transaction(dg00x
->unit
,
174 TCODE_WRITE_QUADLET_REQUEST
,
176 DG00X_OFFSET_STREAMING_SET
,
177 &data
, sizeof(data
), 0);
188 static int keep_resources(struct snd_dg00x
*dg00x
, struct amdtp_stream
*stream
,
191 struct fw_iso_resources
*resources
;
195 // Check sampling rate.
196 for (i
= 0; i
< SND_DG00X_RATE_COUNT
; i
++) {
197 if (snd_dg00x_stream_rates
[i
] == rate
)
200 if (i
== SND_DG00X_RATE_COUNT
)
203 if (stream
== &dg00x
->tx_stream
)
204 resources
= &dg00x
->tx_resources
;
206 resources
= &dg00x
->rx_resources
;
208 err
= amdtp_dot_set_parameters(stream
, rate
,
209 snd_dg00x_stream_pcm_channels
[i
]);
213 return fw_iso_resources_allocate(resources
,
214 amdtp_stream_get_max_payload(stream
),
215 fw_parent_device(dg00x
->unit
)->max_speed
);
218 static int init_stream(struct snd_dg00x
*dg00x
, struct amdtp_stream
*s
)
220 struct fw_iso_resources
*resources
;
221 enum amdtp_stream_direction dir
;
224 if (s
== &dg00x
->tx_stream
) {
225 resources
= &dg00x
->tx_resources
;
226 dir
= AMDTP_IN_STREAM
;
228 resources
= &dg00x
->rx_resources
;
229 dir
= AMDTP_OUT_STREAM
;
232 err
= fw_iso_resources_init(resources
, dg00x
->unit
);
236 err
= amdtp_dot_init(s
, dg00x
->unit
, dir
);
238 fw_iso_resources_destroy(resources
);
243 static void destroy_stream(struct snd_dg00x
*dg00x
, struct amdtp_stream
*s
)
245 amdtp_stream_destroy(s
);
247 if (s
== &dg00x
->tx_stream
)
248 fw_iso_resources_destroy(&dg00x
->tx_resources
);
250 fw_iso_resources_destroy(&dg00x
->rx_resources
);
253 int snd_dg00x_stream_init_duplex(struct snd_dg00x
*dg00x
)
257 err
= init_stream(dg00x
, &dg00x
->rx_stream
);
261 err
= init_stream(dg00x
, &dg00x
->tx_stream
);
263 destroy_stream(dg00x
, &dg00x
->rx_stream
);
265 err
= amdtp_domain_init(&dg00x
->domain
);
267 destroy_stream(dg00x
, &dg00x
->rx_stream
);
268 destroy_stream(dg00x
, &dg00x
->tx_stream
);
275 * This function should be called before starting streams or after stopping
278 void snd_dg00x_stream_destroy_duplex(struct snd_dg00x
*dg00x
)
280 amdtp_domain_destroy(&dg00x
->domain
);
282 destroy_stream(dg00x
, &dg00x
->rx_stream
);
283 destroy_stream(dg00x
, &dg00x
->tx_stream
);
286 int snd_dg00x_stream_reserve_duplex(struct snd_dg00x
*dg00x
, unsigned int rate
,
287 unsigned int frames_per_period
,
288 unsigned int frames_per_buffer
)
290 unsigned int curr_rate
;
293 err
= snd_dg00x_stream_get_local_rate(dg00x
, &curr_rate
);
299 if (dg00x
->substreams_counter
== 0 || curr_rate
!= rate
) {
300 amdtp_domain_stop(&dg00x
->domain
);
302 finish_session(dg00x
);
304 fw_iso_resources_free(&dg00x
->tx_resources
);
305 fw_iso_resources_free(&dg00x
->rx_resources
);
307 err
= snd_dg00x_stream_set_local_rate(dg00x
, rate
);
311 err
= keep_resources(dg00x
, &dg00x
->rx_stream
, rate
);
315 err
= keep_resources(dg00x
, &dg00x
->tx_stream
, rate
);
317 fw_iso_resources_free(&dg00x
->rx_resources
);
321 err
= amdtp_domain_set_events_per_period(&dg00x
->domain
,
322 frames_per_period
, frames_per_buffer
);
324 fw_iso_resources_free(&dg00x
->rx_resources
);
325 fw_iso_resources_free(&dg00x
->tx_resources
);
333 int snd_dg00x_stream_start_duplex(struct snd_dg00x
*dg00x
)
335 unsigned int generation
= dg00x
->rx_resources
.generation
;
338 if (dg00x
->substreams_counter
== 0)
341 if (amdtp_streaming_error(&dg00x
->tx_stream
) ||
342 amdtp_streaming_error(&dg00x
->rx_stream
)) {
343 amdtp_domain_stop(&dg00x
->domain
);
344 finish_session(dg00x
);
347 if (generation
!= fw_parent_device(dg00x
->unit
)->card
->generation
) {
348 err
= fw_iso_resources_update(&dg00x
->tx_resources
);
352 err
= fw_iso_resources_update(&dg00x
->rx_resources
);
358 * No packets are transmitted without receiving packets, reagardless of
359 * which source of clock is used.
361 if (!amdtp_stream_running(&dg00x
->rx_stream
)) {
362 int spd
= fw_parent_device(dg00x
->unit
)->max_speed
;
364 err
= begin_session(dg00x
);
368 err
= amdtp_domain_add_stream(&dg00x
->domain
, &dg00x
->rx_stream
,
369 dg00x
->rx_resources
.channel
, spd
);
373 err
= amdtp_domain_add_stream(&dg00x
->domain
, &dg00x
->tx_stream
,
374 dg00x
->tx_resources
.channel
, spd
);
378 err
= amdtp_domain_start(&dg00x
->domain
, 0);
382 if (!amdtp_stream_wait_callback(&dg00x
->rx_stream
,
384 !amdtp_stream_wait_callback(&dg00x
->tx_stream
,
393 amdtp_domain_stop(&dg00x
->domain
);
394 finish_session(dg00x
);
399 void snd_dg00x_stream_stop_duplex(struct snd_dg00x
*dg00x
)
401 if (dg00x
->substreams_counter
== 0) {
402 amdtp_domain_stop(&dg00x
->domain
);
403 finish_session(dg00x
);
405 fw_iso_resources_free(&dg00x
->tx_resources
);
406 fw_iso_resources_free(&dg00x
->rx_resources
);
410 void snd_dg00x_stream_update_duplex(struct snd_dg00x
*dg00x
)
412 fw_iso_resources_update(&dg00x
->tx_resources
);
413 fw_iso_resources_update(&dg00x
->rx_resources
);
415 amdtp_stream_update(&dg00x
->tx_stream
);
416 amdtp_stream_update(&dg00x
->rx_stream
);
419 void snd_dg00x_stream_lock_changed(struct snd_dg00x
*dg00x
)
421 dg00x
->dev_lock_changed
= true;
422 wake_up(&dg00x
->hwdep_wait
);
425 int snd_dg00x_stream_lock_try(struct snd_dg00x
*dg00x
)
429 spin_lock_irq(&dg00x
->lock
);
431 /* user land lock this */
432 if (dg00x
->dev_lock_count
< 0) {
437 /* this is the first time */
438 if (dg00x
->dev_lock_count
++ == 0)
439 snd_dg00x_stream_lock_changed(dg00x
);
442 spin_unlock_irq(&dg00x
->lock
);
446 void snd_dg00x_stream_lock_release(struct snd_dg00x
*dg00x
)
448 spin_lock_irq(&dg00x
->lock
);
450 if (WARN_ON(dg00x
->dev_lock_count
<= 0))
452 if (--dg00x
->dev_lock_count
== 0)
453 snd_dg00x_stream_lock_changed(dg00x
);
455 spin_unlock_irq(&dg00x
->lock
);