1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family 4 * 5 * Copyright (c) 2014-2015 Takashi Sakamoto 6 */ 7 8 #include "digi00x.h" 9 10 #define CALLBACK_TIMEOUT 500 11 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, 17 }; 18 19 /* Multi Bit Linear Audio data channels for each sampling transfer frequency. */ 20 const unsigned int 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), 25 /* Analog/SPDIF */ 26 [SND_DG00X_RATE_88200] = (8 + 2), 27 [SND_DG00X_RATE_96000] = (8 + 2), 28 }; 29 30 int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x, unsigned int *rate) 31 { 32 u32 data; 33 __be32 reg; 34 int err; 35 36 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 37 DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE, 38 ®, sizeof(reg), 0); 39 if (err < 0) 40 return err; 41 42 data = be32_to_cpu(reg) & 0x0f; 43 if (data < ARRAY_SIZE(snd_dg00x_stream_rates)) 44 *rate = snd_dg00x_stream_rates[data]; 45 else 46 err = -EIO; 47 48 return err; 49 } 50 51 int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate) 52 { 53 __be32 reg; 54 unsigned int i; 55 56 for (i = 0; i < ARRAY_SIZE(snd_dg00x_stream_rates); i++) { 57 if (rate == snd_dg00x_stream_rates[i]) 58 break; 59 } 60 if (i == ARRAY_SIZE(snd_dg00x_stream_rates)) 61 return -EINVAL; 62 63 reg = cpu_to_be32(i); 64 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, 65 DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE, 66 ®, sizeof(reg), 0); 67 } 68 69 int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x, 70 enum snd_dg00x_clock *clock) 71 { 72 __be32 reg; 73 int err; 74 75 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 76 DG00X_ADDR_BASE + DG00X_OFFSET_CLOCK_SOURCE, 77 ®, sizeof(reg), 0); 78 if (err < 0) 79 return err; 80 81 *clock = be32_to_cpu(reg) & 0x0f; 82 if (*clock >= SND_DG00X_CLOCK_COUNT) 83 err = -EIO; 84 85 return err; 86 } 87 88 int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, bool *detect) 89 { 90 __be32 reg; 91 int err; 92 93 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 94 DG00X_ADDR_BASE + DG00X_OFFSET_DETECT_EXTERNAL, 95 ®, sizeof(reg), 0); 96 if (err >= 0) 97 *detect = be32_to_cpu(reg) > 0; 98 99 return err; 100 } 101 102 int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x, 103 unsigned int *rate) 104 { 105 u32 data; 106 __be32 reg; 107 int err; 108 109 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 110 DG00X_ADDR_BASE + DG00X_OFFSET_EXTERNAL_RATE, 111 ®, sizeof(reg), 0); 112 if (err < 0) 113 return err; 114 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. */ 119 else 120 err = -EBUSY; 121 122 return err; 123 } 124 125 static void finish_session(struct snd_dg00x *dg00x) 126 { 127 __be32 data; 128 129 amdtp_stream_stop(&dg00x->tx_stream); 130 amdtp_stream_stop(&dg00x->rx_stream); 131 132 data = cpu_to_be32(0x00000003); 133 snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, 134 DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_SET, 135 &data, sizeof(data), 0); 136 137 // Unregister isochronous channels for both direction. 138 data = 0; 139 snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, 140 DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS, 141 &data, sizeof(data), 0); 142 143 // Just after finishing the session, the device may lost transmitting 144 // functionality for a short time. 145 msleep(50); 146 } 147 148 static int begin_session(struct snd_dg00x *dg00x) 149 { 150 __be32 data; 151 u32 curr; 152 int err; 153 154 // Register isochronous channels for both direction. 155 data = cpu_to_be32((dg00x->tx_resources.channel << 16) | 156 dg00x->rx_resources.channel); 157 err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, 158 DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS, 159 &data, sizeof(data), 0); 160 if (err < 0) 161 return err; 162 163 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 164 DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_STATE, 165 &data, sizeof(data), 0); 166 if (err < 0) 167 return err; 168 curr = be32_to_cpu(data); 169 170 if (curr == 0) 171 curr = 2; 172 173 curr--; 174 while (curr > 0) { 175 data = cpu_to_be32(curr); 176 err = snd_fw_transaction(dg00x->unit, 177 TCODE_WRITE_QUADLET_REQUEST, 178 DG00X_ADDR_BASE + 179 DG00X_OFFSET_STREAMING_SET, 180 &data, sizeof(data), 0); 181 if (err < 0) 182 break; 183 184 msleep(20); 185 curr--; 186 } 187 188 return err; 189 } 190 191 static int keep_resources(struct snd_dg00x *dg00x, struct amdtp_stream *stream, 192 unsigned int rate) 193 { 194 struct fw_iso_resources *resources; 195 int i; 196 int err; 197 198 // Check sampling rate. 199 for (i = 0; i < SND_DG00X_RATE_COUNT; i++) { 200 if (snd_dg00x_stream_rates[i] == rate) 201 break; 202 } 203 if (i == SND_DG00X_RATE_COUNT) 204 return -EINVAL; 205 206 if (stream == &dg00x->tx_stream) 207 resources = &dg00x->tx_resources; 208 else 209 resources = &dg00x->rx_resources; 210 211 err = amdtp_dot_set_parameters(stream, rate, 212 snd_dg00x_stream_pcm_channels[i]); 213 if (err < 0) 214 return err; 215 216 return fw_iso_resources_allocate(resources, 217 amdtp_stream_get_max_payload(stream), 218 fw_parent_device(dg00x->unit)->max_speed); 219 } 220 221 int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x) 222 { 223 int err; 224 225 /* For out-stream. */ 226 err = fw_iso_resources_init(&dg00x->rx_resources, dg00x->unit); 227 if (err < 0) 228 goto error; 229 err = amdtp_dot_init(&dg00x->rx_stream, dg00x->unit, AMDTP_OUT_STREAM); 230 if (err < 0) 231 goto error; 232 233 /* For in-stream. */ 234 err = fw_iso_resources_init(&dg00x->tx_resources, dg00x->unit); 235 if (err < 0) 236 goto error; 237 err = amdtp_dot_init(&dg00x->tx_stream, dg00x->unit, AMDTP_IN_STREAM); 238 if (err < 0) 239 goto error; 240 241 return 0; 242 error: 243 snd_dg00x_stream_destroy_duplex(dg00x); 244 return err; 245 } 246 247 /* 248 * This function should be called before starting streams or after stopping 249 * streams. 250 */ 251 void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x) 252 { 253 amdtp_stream_destroy(&dg00x->rx_stream); 254 fw_iso_resources_destroy(&dg00x->rx_resources); 255 256 amdtp_stream_destroy(&dg00x->tx_stream); 257 fw_iso_resources_destroy(&dg00x->tx_resources); 258 } 259 260 int snd_dg00x_stream_reserve_duplex(struct snd_dg00x *dg00x, unsigned int rate) 261 { 262 unsigned int curr_rate; 263 int err; 264 265 err = snd_dg00x_stream_get_local_rate(dg00x, &curr_rate); 266 if (err < 0) 267 return err; 268 if (rate == 0) 269 rate = curr_rate; 270 271 if (dg00x->substreams_counter == 0 || curr_rate != rate) { 272 finish_session(dg00x); 273 274 fw_iso_resources_free(&dg00x->tx_resources); 275 fw_iso_resources_free(&dg00x->rx_resources); 276 277 err = snd_dg00x_stream_set_local_rate(dg00x, rate); 278 if (err < 0) 279 return err; 280 281 err = keep_resources(dg00x, &dg00x->rx_stream, rate); 282 if (err < 0) 283 return err; 284 285 err = keep_resources(dg00x, &dg00x->tx_stream, rate); 286 if (err < 0) { 287 fw_iso_resources_free(&dg00x->rx_resources); 288 return err; 289 } 290 } 291 292 return 0; 293 } 294 295 int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x) 296 { 297 unsigned int generation = dg00x->rx_resources.generation; 298 int err = 0; 299 300 if (dg00x->substreams_counter == 0) 301 return 0; 302 303 if (amdtp_streaming_error(&dg00x->tx_stream) || 304 amdtp_streaming_error(&dg00x->rx_stream)) 305 finish_session(dg00x); 306 307 if (generation != fw_parent_device(dg00x->unit)->card->generation) { 308 err = fw_iso_resources_update(&dg00x->tx_resources); 309 if (err < 0) 310 goto error; 311 312 err = fw_iso_resources_update(&dg00x->rx_resources); 313 if (err < 0) 314 goto error; 315 } 316 317 /* 318 * No packets are transmitted without receiving packets, reagardless of 319 * which source of clock is used. 320 */ 321 if (!amdtp_stream_running(&dg00x->rx_stream)) { 322 err = begin_session(dg00x); 323 if (err < 0) 324 goto error; 325 326 err = amdtp_stream_start(&dg00x->rx_stream, 327 dg00x->rx_resources.channel, 328 fw_parent_device(dg00x->unit)->max_speed); 329 if (err < 0) 330 goto error; 331 332 if (!amdtp_stream_wait_callback(&dg00x->rx_stream, 333 CALLBACK_TIMEOUT)) { 334 err = -ETIMEDOUT; 335 goto error; 336 } 337 } 338 339 /* 340 * The value of SYT field in transmitted packets is always 0x0000. Thus, 341 * duplex streams with timestamp synchronization cannot be built. 342 */ 343 if (!amdtp_stream_running(&dg00x->tx_stream)) { 344 err = amdtp_stream_start(&dg00x->tx_stream, 345 dg00x->tx_resources.channel, 346 fw_parent_device(dg00x->unit)->max_speed); 347 if (err < 0) 348 goto error; 349 350 if (!amdtp_stream_wait_callback(&dg00x->tx_stream, 351 CALLBACK_TIMEOUT)) { 352 err = -ETIMEDOUT; 353 goto error; 354 } 355 } 356 357 return 0; 358 error: 359 finish_session(dg00x); 360 361 return err; 362 } 363 364 void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x) 365 { 366 if (dg00x->substreams_counter == 0) { 367 finish_session(dg00x); 368 369 fw_iso_resources_free(&dg00x->tx_resources); 370 fw_iso_resources_free(&dg00x->rx_resources); 371 } 372 } 373 374 void snd_dg00x_stream_update_duplex(struct snd_dg00x *dg00x) 375 { 376 fw_iso_resources_update(&dg00x->tx_resources); 377 fw_iso_resources_update(&dg00x->rx_resources); 378 379 amdtp_stream_update(&dg00x->tx_stream); 380 amdtp_stream_update(&dg00x->rx_stream); 381 } 382 383 void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x) 384 { 385 dg00x->dev_lock_changed = true; 386 wake_up(&dg00x->hwdep_wait); 387 } 388 389 int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x) 390 { 391 int err; 392 393 spin_lock_irq(&dg00x->lock); 394 395 /* user land lock this */ 396 if (dg00x->dev_lock_count < 0) { 397 err = -EBUSY; 398 goto end; 399 } 400 401 /* this is the first time */ 402 if (dg00x->dev_lock_count++ == 0) 403 snd_dg00x_stream_lock_changed(dg00x); 404 err = 0; 405 end: 406 spin_unlock_irq(&dg00x->lock); 407 return err; 408 } 409 410 void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x) 411 { 412 spin_lock_irq(&dg00x->lock); 413 414 if (WARN_ON(dg00x->dev_lock_count <= 0)) 415 goto end; 416 if (--dg00x->dev_lock_count == 0) 417 snd_dg00x_stream_lock_changed(dg00x); 418 end: 419 spin_unlock_irq(&dg00x->lock); 420 } 421