blob: 716db092d7c77c7a57f90803ef9d0747984e8efa [file] [log] [blame]
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +09001/*
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
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090012#define CALLBACK_TIMEOUT 200
13
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +090014const 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
Takashi Sakamoto9a028432014-12-09 00:10:36 +090027static void release_resources(struct snd_dice *dice,
28 struct fw_iso_resources *resources)
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +090029{
Takashi Sakamoto3e93d422015-10-18 22:39:49 +090030 __be32 channel;
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +090031
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090032 /* Reset channel number */
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +090033 channel = cpu_to_be32((u32)-1);
Takashi Sakamoto9a028432014-12-09 00:10:36 +090034 if (resources == &dice->tx_resources)
35 snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
Takashi Sakamoto3e93d422015-10-18 22:39:49 +090036 &channel, sizeof(channel));
Takashi Sakamoto9a028432014-12-09 00:10:36 +090037 else
38 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
Takashi Sakamoto3e93d422015-10-18 22:39:49 +090039 &channel, sizeof(channel));
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090040
Takashi Sakamoto9a028432014-12-09 00:10:36 +090041 fw_iso_resources_free(resources);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090042}
43
Takashi Sakamoto9a028432014-12-09 00:10:36 +090044static int keep_resources(struct snd_dice *dice,
45 struct fw_iso_resources *resources,
46 unsigned int max_payload_bytes)
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090047{
Takashi Sakamoto3e93d422015-10-18 22:39:49 +090048 __be32 channel;
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090049 int err;
50
Takashi Sakamoto9a028432014-12-09 00:10:36 +090051 err = fw_iso_resources_allocate(resources, max_payload_bytes,
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090052 fw_parent_device(dice->unit)->max_speed);
53 if (err < 0)
54 goto end;
55
56 /* Set channel number */
Takashi Sakamoto9a028432014-12-09 00:10:36 +090057 channel = cpu_to_be32(resources->channel);
58 if (resources == &dice->tx_resources)
59 err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
Takashi Sakamoto3e93d422015-10-18 22:39:49 +090060 &channel, sizeof(channel));
Takashi Sakamoto9a028432014-12-09 00:10:36 +090061 else
62 err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
Takashi Sakamoto3e93d422015-10-18 22:39:49 +090063 &channel, sizeof(channel));
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090064 if (err < 0)
Takashi Sakamoto9a028432014-12-09 00:10:36 +090065 release_resources(dice, resources);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090066end:
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +090067 return err;
68}
69
Takashi Sakamoto9a028432014-12-09 00:10:36 +090070static void stop_stream(struct snd_dice *dice, struct amdtp_stream *stream)
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +090071{
Takashi Sakamoto9a028432014-12-09 00:10:36 +090072 amdtp_stream_pcm_abort(stream);
73 amdtp_stream_stop(stream);
Takashi Sakamotoc50fb912014-11-29 00:59:15 +090074
Takashi Sakamoto9a028432014-12-09 00:10:36 +090075 if (stream == &dice->tx_stream)
76 release_resources(dice, &dice->tx_resources);
77 else
78 release_resources(dice, &dice->rx_resources);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090079}
80
Takashi Sakamoto9a028432014-12-09 00:10:36 +090081static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
82 unsigned int rate)
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090083{
Takashi Sakamoto9a028432014-12-09 00:10:36 +090084 struct fw_iso_resources *resources;
Takashi Sakamoto1bc8e122016-02-08 22:54:16 +090085 __be32 reg[2];
Takashi Sakamoto6f688262016-02-08 22:54:19 +090086 unsigned int i, pcm_chs, midi_ports;
Takashi Sakamoto27ec83b2015-09-19 11:21:50 +090087 bool double_pcm_frames;
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090088 int err;
89
Takashi Sakamoto9a028432014-12-09 00:10:36 +090090 if (stream == &dice->tx_stream) {
91 resources = &dice->tx_resources;
Takashi Sakamoto1bc8e122016-02-08 22:54:16 +090092 err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
93 reg, sizeof(reg));
Takashi Sakamoto9a028432014-12-09 00:10:36 +090094 } else {
95 resources = &dice->rx_resources;
Takashi Sakamoto1bc8e122016-02-08 22:54:16 +090096 err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
97 reg, sizeof(reg));
Takashi Sakamoto9a028432014-12-09 00:10:36 +090098 }
Takashi Sakamoto288a8d02014-12-09 00:10:35 +090099
Takashi Sakamoto1bc8e122016-02-08 22:54:16 +0900100 if (err < 0)
101 goto end;
102
103 pcm_chs = be32_to_cpu(reg[0]);
104 midi_ports = be32_to_cpu(reg[1]);
105
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900106 /*
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 */
Takashi Sakamoto6f688262016-02-08 22:54:19 +0900116 double_pcm_frames = rate > 96000;
Takashi Sakamoto27ec83b2015-09-19 11:21:50 +0900117 if (double_pcm_frames) {
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900118 rate /= 2;
119 pcm_chs *= 2;
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900120 }
121
Takashi Sakamoto51c29fd2015-09-19 11:21:56 +0900122 err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports,
123 double_pcm_frames);
Takashi Sakamoto547e6312015-09-19 11:21:49 +0900124 if (err < 0)
125 goto end;
126
Takashi Sakamoto27ec83b2015-09-19 11:21:50 +0900127 if (double_pcm_frames) {
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900128 pcm_chs /= 2;
129
130 for (i = 0; i < pcm_chs; i++) {
Takashi Sakamotof65be912015-09-19 11:21:58 +0900131 amdtp_am824_set_pcm_position(stream, i, i * 2);
132 amdtp_am824_set_pcm_position(stream, i + pcm_chs,
133 i * 2 + 1);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900134 }
135 }
136
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900137 err = keep_resources(dice, resources,
138 amdtp_stream_get_max_payload(stream));
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900139 if (err < 0) {
140 dev_err(&dice->unit->device,
141 "fail to keep isochronous resources\n");
142 goto end;
143 }
144
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900145 err = amdtp_stream_start(stream, resources->channel,
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900146 fw_parent_device(dice->unit)->max_speed);
147 if (err < 0)
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900148 release_resources(dice, resources);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900149end:
150 return err;
151}
152
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900153static int get_sync_mode(struct snd_dice *dice, enum cip_flags *sync_mode)
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900154{
Takashi Sakamoto8fc01fc2014-12-09 00:10:37 +0900155 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 }
176end:
177 return err;
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900178}
179
180int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
181{
182 struct amdtp_stream *master, *slave;
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900183 unsigned int curr_rate;
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900184 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 }
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900200
201 /* Some packet queueing errors. */
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900202 if (amdtp_streaming_error(master) || amdtp_streaming_error(slave))
203 stop_stream(dice, master);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900204
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 }
Takashi Sakamotoa113ff82014-12-09 00:10:39 +0900212 if (rate == 0)
213 rate = curr_rate;
Takashi Sakamoto1bc8e122016-02-08 22:54:16 +0900214 if (rate != curr_rate) {
215 err = -EINVAL;
216 goto end;
217 }
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900218
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900219 if (!amdtp_stream_running(master)) {
220 stop_stream(dice, slave);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900221 snd_dice_transaction_clear_enable(dice);
222
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900223 amdtp_stream_set_sync(sync_mode, master, slave);
224
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900225 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
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900232 /* Start both streams. */
233 err = start_stream(dice, master, rate);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900234 if (err < 0) {
235 dev_err(&dice->unit->device,
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900236 "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);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900244 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");
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900250 stop_stream(dice, master);
251 stop_stream(dice, slave);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900252 goto end;
253 }
254
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900255 /* Wait first callbacks */
256 if (!amdtp_stream_wait_callback(master, CALLBACK_TIMEOUT) ||
257 !amdtp_stream_wait_callback(slave, CALLBACK_TIMEOUT)) {
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900258 snd_dice_transaction_clear_enable(dice);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900259 stop_stream(dice, master);
260 stop_stream(dice, slave);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900261 err = -ETIMEDOUT;
262 }
263 }
264end:
265 return err;
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900266}
267
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900268void snd_dice_stream_stop_duplex(struct snd_dice *dice)
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900269{
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900270 if (dice->substreams_counter > 0)
271 return;
272
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900273 snd_dice_transaction_clear_enable(dice);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900274
275 stop_stream(dice, &dice->tx_stream);
276 stop_stream(dice, &dice->rx_stream);
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900277}
278
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900279static 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
Takashi Sakamoto59558152015-09-19 11:21:55 +0900298 err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900299 if (err < 0) {
300 amdtp_stream_destroy(stream);
301 fw_iso_resources_destroy(resources);
302 }
303end:
304 return err;
305}
306
Takashi Sakamotod23c2cc2015-02-21 23:54:59 +0900307/*
308 * This function should be called before starting streams or after stopping
309 * streams.
310 */
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900311static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
312{
Takashi Sakamotod23c2cc2015-02-21 23:54:59 +0900313 struct fw_iso_resources *resources;
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900314
315 if (stream == &dice->tx_stream)
Takashi Sakamotod23c2cc2015-02-21 23:54:59 +0900316 resources = &dice->tx_resources;
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900317 else
Takashi Sakamotod23c2cc2015-02-21 23:54:59 +0900318 resources = &dice->rx_resources;
319
320 amdtp_stream_destroy(stream);
321 fw_iso_resources_destroy(resources);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900322}
323
324int snd_dice_stream_init_duplex(struct snd_dice *dice)
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900325{
326 int err;
327
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900328 dice->substreams_counter = 0;
329
330 err = init_stream(dice, &dice->tx_stream);
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900331 if (err < 0)
332 goto end;
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900333
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900334 err = init_stream(dice, &dice->rx_stream);
Takashi Sakamotod23c2cc2015-02-21 23:54:59 +0900335 if (err < 0)
336 destroy_stream(dice, &dice->tx_stream);
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900337end:
338 return err;
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900339}
340
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900341void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900342{
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900343 snd_dice_transaction_clear_enable(dice);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900344
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900345 destroy_stream(dice, &dice->tx_stream);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900346 destroy_stream(dice, &dice->rx_stream);
347
348 dice->substreams_counter = 0;
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900349}
350
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900351void snd_dice_stream_update_duplex(struct snd_dice *dice)
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900352{
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
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900363 stop_stream(dice, &dice->rx_stream);
364 stop_stream(dice, &dice->tx_stream);
Takashi Sakamoto288a8d02014-12-09 00:10:35 +0900365
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900366 fw_iso_resources_update(&dice->rx_resources);
Takashi Sakamoto9a028432014-12-09 00:10:36 +0900367 fw_iso_resources_update(&dice->tx_resources);
Takashi Sakamoto6eb6c812014-11-29 00:59:14 +0900368}
369
370static void dice_lock_changed(struct snd_dice *dice)
371{
372 dice->dev_lock_changed = true;
373 wake_up(&dice->hwdep_wait);
374}
375
376int 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;
390out:
391 spin_unlock_irq(&dice->lock);
392 return err;
393}
394
395void 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);
404out:
405 spin_unlock_irq(&dice->lock);
406}