1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * tascam-stream.c - a part of driver for TASCAM FireWire series 4 * 5 * Copyright (c) 2015 Takashi Sakamoto 6 */ 7 8 #include <linux/delay.h> 9 #include "tascam.h" 10 11 #define CLOCK_STATUS_MASK 0xffff0000 12 #define CLOCK_CONFIG_MASK 0x0000ffff 13 14 #define CALLBACK_TIMEOUT 500 15 16 static int get_clock(struct snd_tscm *tscm, u32 *data) 17 { 18 int trial = 0; 19 __be32 reg; 20 int err; 21 22 while (trial++ < 5) { 23 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST, 24 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS, 25 ®, sizeof(reg), 0); 26 if (err < 0) 27 return err; 28 29 *data = be32_to_cpu(reg); 30 if (*data & CLOCK_STATUS_MASK) 31 break; 32 33 // In intermediate state after changing clock status. 34 msleep(50); 35 } 36 37 // Still in the intermediate state. 38 if (trial >= 5) 39 return -EAGAIN; 40 41 return 0; 42 } 43 44 static int set_clock(struct snd_tscm *tscm, unsigned int rate, 45 enum snd_tscm_clock clock) 46 { 47 u32 data; 48 __be32 reg; 49 int err; 50 51 err = get_clock(tscm, &data); 52 if (err < 0) 53 return err; 54 data &= CLOCK_CONFIG_MASK; 55 56 if (rate > 0) { 57 data &= 0x000000ff; 58 /* Base rate. */ 59 if ((rate % 44100) == 0) { 60 data |= 0x00000100; 61 /* Multiplier. */ 62 if (rate / 44100 == 2) 63 data |= 0x00008000; 64 } else if ((rate % 48000) == 0) { 65 data |= 0x00000200; 66 /* Multiplier. */ 67 if (rate / 48000 == 2) 68 data |= 0x00008000; 69 } else { 70 return -EAGAIN; 71 } 72 } 73 74 if (clock != INT_MAX) { 75 data &= 0x0000ff00; 76 data |= clock + 1; 77 } 78 79 reg = cpu_to_be32(data); 80 81 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 82 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS, 83 ®, sizeof(reg), 0); 84 if (err < 0) 85 return err; 86 87 if (data & 0x00008000) 88 reg = cpu_to_be32(0x0000001a); 89 else 90 reg = cpu_to_be32(0x0000000d); 91 92 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 93 TSCM_ADDR_BASE + TSCM_OFFSET_MULTIPLEX_MODE, 94 ®, sizeof(reg), 0); 95 } 96 97 int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate) 98 { 99 u32 data; 100 int err; 101 102 err = get_clock(tscm, &data); 103 if (err < 0) 104 return err; 105 106 data = (data & 0xff000000) >> 24; 107 108 /* Check base rate. */ 109 if ((data & 0x0f) == 0x01) 110 *rate = 44100; 111 else if ((data & 0x0f) == 0x02) 112 *rate = 48000; 113 else 114 return -EAGAIN; 115 116 /* Check multiplier. */ 117 if ((data & 0xf0) == 0x80) 118 *rate *= 2; 119 else if ((data & 0xf0) != 0x00) 120 return -EAGAIN; 121 122 return err; 123 } 124 125 int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock) 126 { 127 u32 data; 128 int err; 129 130 err = get_clock(tscm, &data); 131 if (err < 0) 132 return err; 133 134 *clock = ((data & 0x00ff0000) >> 16) - 1; 135 if (*clock < 0 || *clock > SND_TSCM_CLOCK_ADAT) 136 return -EIO; 137 138 return 0; 139 } 140 141 static int enable_data_channels(struct snd_tscm *tscm) 142 { 143 __be32 reg; 144 u32 data; 145 unsigned int i; 146 int err; 147 148 data = 0; 149 for (i = 0; i < tscm->spec->pcm_capture_analog_channels; ++i) 150 data |= BIT(i); 151 if (tscm->spec->has_adat) 152 data |= 0x0000ff00; 153 if (tscm->spec->has_spdif) 154 data |= 0x00030000; 155 156 reg = cpu_to_be32(data); 157 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 158 TSCM_ADDR_BASE + TSCM_OFFSET_TX_PCM_CHANNELS, 159 ®, sizeof(reg), 0); 160 if (err < 0) 161 return err; 162 163 data = 0; 164 for (i = 0; i < tscm->spec->pcm_playback_analog_channels; ++i) 165 data |= BIT(i); 166 if (tscm->spec->has_adat) 167 data |= 0x0000ff00; 168 if (tscm->spec->has_spdif) 169 data |= 0x00030000; 170 171 reg = cpu_to_be32(data); 172 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 173 TSCM_ADDR_BASE + TSCM_OFFSET_RX_PCM_CHANNELS, 174 ®, sizeof(reg), 0); 175 } 176 177 static int set_stream_formats(struct snd_tscm *tscm, unsigned int rate) 178 { 179 __be32 reg; 180 int err; 181 182 // Set an option for unknown purpose. 183 reg = cpu_to_be32(0x00200000); 184 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 185 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION, 186 ®, sizeof(reg), 0); 187 if (err < 0) 188 return err; 189 190 return enable_data_channels(tscm); 191 } 192 193 static void finish_session(struct snd_tscm *tscm) 194 { 195 __be32 reg; 196 197 reg = 0; 198 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 199 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING, 200 ®, sizeof(reg), 0); 201 202 reg = 0; 203 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 204 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON, 205 ®, sizeof(reg), 0); 206 207 // Unregister channels. 208 reg = cpu_to_be32(0x00000000); 209 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 210 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH, 211 ®, sizeof(reg), 0); 212 reg = cpu_to_be32(0x00000000); 213 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 214 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN, 215 ®, sizeof(reg), 0); 216 reg = cpu_to_be32(0x00000000); 217 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 218 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH, 219 ®, sizeof(reg), 0); 220 } 221 222 static int begin_session(struct snd_tscm *tscm) 223 { 224 __be32 reg; 225 int err; 226 227 // Register the isochronous channel for transmitting stream. 228 reg = cpu_to_be32(tscm->tx_resources.channel); 229 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 230 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH, 231 ®, sizeof(reg), 0); 232 if (err < 0) 233 return err; 234 235 // Unknown. 236 reg = cpu_to_be32(0x00000002); 237 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 238 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN, 239 ®, sizeof(reg), 0); 240 if (err < 0) 241 return err; 242 243 // Register the isochronous channel for receiving stream. 244 reg = cpu_to_be32(tscm->rx_resources.channel); 245 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 246 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH, 247 ®, sizeof(reg), 0); 248 if (err < 0) 249 return err; 250 251 reg = cpu_to_be32(0x00000001); 252 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 253 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING, 254 ®, sizeof(reg), 0); 255 if (err < 0) 256 return err; 257 258 reg = cpu_to_be32(0x00000001); 259 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 260 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON, 261 ®, sizeof(reg), 0); 262 if (err < 0) 263 return err; 264 265 // Set an option for unknown purpose. 266 reg = cpu_to_be32(0x00002000); 267 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, 268 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION, 269 ®, sizeof(reg), 0); 270 if (err < 0) 271 return err; 272 273 // Start multiplexing PCM samples on packets. 274 reg = cpu_to_be32(0x00000001); 275 return snd_fw_transaction(tscm->unit, 276 TCODE_WRITE_QUADLET_REQUEST, 277 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_ON, 278 ®, sizeof(reg), 0); 279 } 280 281 static int keep_resources(struct snd_tscm *tscm, unsigned int rate, 282 struct amdtp_stream *stream) 283 { 284 struct fw_iso_resources *resources; 285 int err; 286 287 if (stream == &tscm->tx_stream) 288 resources = &tscm->tx_resources; 289 else 290 resources = &tscm->rx_resources; 291 292 err = amdtp_tscm_set_parameters(stream, rate); 293 if (err < 0) 294 return err; 295 296 return fw_iso_resources_allocate(resources, 297 amdtp_stream_get_max_payload(stream), 298 fw_parent_device(tscm->unit)->max_speed); 299 } 300 301 static int init_stream(struct snd_tscm *tscm, struct amdtp_stream *s) 302 { 303 struct fw_iso_resources *resources; 304 enum amdtp_stream_direction dir; 305 unsigned int pcm_channels; 306 int err; 307 308 if (s == &tscm->tx_stream) { 309 resources = &tscm->tx_resources; 310 dir = AMDTP_IN_STREAM; 311 pcm_channels = tscm->spec->pcm_capture_analog_channels; 312 } else { 313 resources = &tscm->rx_resources; 314 dir = AMDTP_OUT_STREAM; 315 pcm_channels = tscm->spec->pcm_playback_analog_channels; 316 } 317 318 if (tscm->spec->has_adat) 319 pcm_channels += 8; 320 if (tscm->spec->has_spdif) 321 pcm_channels += 2; 322 323 err = fw_iso_resources_init(resources, tscm->unit); 324 if (err < 0) 325 return err; 326 327 err = amdtp_tscm_init(s, tscm->unit, dir, pcm_channels); 328 if (err < 0) 329 fw_iso_resources_free(resources); 330 331 return err; 332 } 333 334 static void destroy_stream(struct snd_tscm *tscm, struct amdtp_stream *s) 335 { 336 amdtp_stream_destroy(s); 337 338 if (s == &tscm->tx_stream) 339 fw_iso_resources_destroy(&tscm->tx_resources); 340 else 341 fw_iso_resources_destroy(&tscm->rx_resources); 342 } 343 344 int snd_tscm_stream_init_duplex(struct snd_tscm *tscm) 345 { 346 int err; 347 348 err = init_stream(tscm, &tscm->tx_stream); 349 if (err < 0) 350 return err; 351 352 err = init_stream(tscm, &tscm->rx_stream); 353 if (err < 0) { 354 destroy_stream(tscm, &tscm->tx_stream); 355 return err; 356 } 357 358 err = amdtp_domain_init(&tscm->domain); 359 if (err < 0) { 360 destroy_stream(tscm, &tscm->tx_stream); 361 destroy_stream(tscm, &tscm->rx_stream); 362 } 363 364 return err; 365 } 366 367 // At bus reset, streaming is stopped and some registers are clear. 368 void snd_tscm_stream_update_duplex(struct snd_tscm *tscm) 369 { 370 amdtp_domain_stop(&tscm->domain); 371 372 amdtp_stream_pcm_abort(&tscm->tx_stream); 373 amdtp_stream_pcm_abort(&tscm->rx_stream); 374 } 375 376 // This function should be called before starting streams or after stopping 377 // streams. 378 void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm) 379 { 380 amdtp_domain_destroy(&tscm->domain); 381 382 destroy_stream(tscm, &tscm->rx_stream); 383 destroy_stream(tscm, &tscm->tx_stream); 384 } 385 386 int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate) 387 { 388 unsigned int curr_rate; 389 int err; 390 391 err = snd_tscm_stream_get_rate(tscm, &curr_rate); 392 if (err < 0) 393 return err; 394 395 if (tscm->substreams_counter == 0 || rate != curr_rate) { 396 amdtp_domain_stop(&tscm->domain); 397 398 finish_session(tscm); 399 400 fw_iso_resources_free(&tscm->tx_resources); 401 fw_iso_resources_free(&tscm->rx_resources); 402 403 err = set_clock(tscm, rate, INT_MAX); 404 if (err < 0) 405 return err; 406 407 err = keep_resources(tscm, rate, &tscm->tx_stream); 408 if (err < 0) 409 return err; 410 411 err = keep_resources(tscm, rate, &tscm->rx_stream); 412 if (err < 0) { 413 fw_iso_resources_free(&tscm->tx_resources); 414 return err; 415 } 416 } 417 418 return 0; 419 } 420 421 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate) 422 { 423 unsigned int generation = tscm->rx_resources.generation; 424 int err; 425 426 if (tscm->substreams_counter == 0) 427 return 0; 428 429 if (amdtp_streaming_error(&tscm->rx_stream) || 430 amdtp_streaming_error(&tscm->tx_stream)) { 431 amdtp_domain_stop(&tscm->domain); 432 finish_session(tscm); 433 } 434 435 if (generation != fw_parent_device(tscm->unit)->card->generation) { 436 err = fw_iso_resources_update(&tscm->tx_resources); 437 if (err < 0) 438 goto error; 439 440 err = fw_iso_resources_update(&tscm->rx_resources); 441 if (err < 0) 442 goto error; 443 } 444 445 if (!amdtp_stream_running(&tscm->rx_stream)) { 446 int spd = fw_parent_device(tscm->unit)->max_speed; 447 448 err = set_stream_formats(tscm, rate); 449 if (err < 0) 450 goto error; 451 452 err = begin_session(tscm); 453 if (err < 0) 454 goto error; 455 456 err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream, 457 tscm->rx_resources.channel, spd); 458 if (err < 0) 459 goto error; 460 461 err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream, 462 tscm->tx_resources.channel, spd); 463 if (err < 0) 464 goto error; 465 466 err = amdtp_domain_start(&tscm->domain); 467 if (err < 0) 468 return err; 469 470 if (!amdtp_stream_wait_callback(&tscm->rx_stream, 471 CALLBACK_TIMEOUT) || 472 !amdtp_stream_wait_callback(&tscm->tx_stream, 473 CALLBACK_TIMEOUT)) { 474 err = -ETIMEDOUT; 475 goto error; 476 } 477 } 478 479 return 0; 480 error: 481 amdtp_domain_stop(&tscm->domain); 482 finish_session(tscm); 483 484 return err; 485 } 486 487 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm) 488 { 489 if (tscm->substreams_counter == 0) { 490 amdtp_domain_stop(&tscm->domain); 491 finish_session(tscm); 492 493 fw_iso_resources_free(&tscm->tx_resources); 494 fw_iso_resources_free(&tscm->rx_resources); 495 } 496 } 497 498 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm) 499 { 500 tscm->dev_lock_changed = true; 501 wake_up(&tscm->hwdep_wait); 502 } 503 504 int snd_tscm_stream_lock_try(struct snd_tscm *tscm) 505 { 506 int err; 507 508 spin_lock_irq(&tscm->lock); 509 510 /* user land lock this */ 511 if (tscm->dev_lock_count < 0) { 512 err = -EBUSY; 513 goto end; 514 } 515 516 /* this is the first time */ 517 if (tscm->dev_lock_count++ == 0) 518 snd_tscm_stream_lock_changed(tscm); 519 err = 0; 520 end: 521 spin_unlock_irq(&tscm->lock); 522 return err; 523 } 524 525 void snd_tscm_stream_lock_release(struct snd_tscm *tscm) 526 { 527 spin_lock_irq(&tscm->lock); 528 529 if (WARN_ON(tscm->dev_lock_count <= 0)) 530 goto end; 531 if (--tscm->dev_lock_count == 0) 532 snd_tscm_stream_lock_changed(tscm); 533 end: 534 spin_unlock_irq(&tscm->lock); 535 } 536