0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009 #include "tascam.h"
0010
0011 #define CLOCK_STATUS_MASK 0xffff0000
0012 #define CLOCK_CONFIG_MASK 0x0000ffff
0013
0014 #define READY_TIMEOUT_MS 4000
0015
0016 static int get_clock(struct snd_tscm *tscm, u32 *data)
0017 {
0018 int trial = 0;
0019 __be32 reg;
0020 int err;
0021
0022 while (trial++ < 5) {
0023 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
0024 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
0025 ®, sizeof(reg), 0);
0026 if (err < 0)
0027 return err;
0028
0029 *data = be32_to_cpu(reg);
0030 if (*data & CLOCK_STATUS_MASK)
0031 break;
0032
0033
0034 msleep(50);
0035 }
0036
0037
0038 if (trial >= 5)
0039 return -EAGAIN;
0040
0041 return 0;
0042 }
0043
0044 static int set_clock(struct snd_tscm *tscm, unsigned int rate,
0045 enum snd_tscm_clock clock)
0046 {
0047 u32 data;
0048 __be32 reg;
0049 int err;
0050
0051 err = get_clock(tscm, &data);
0052 if (err < 0)
0053 return err;
0054 data &= CLOCK_CONFIG_MASK;
0055
0056 if (rate > 0) {
0057 data &= 0x000000ff;
0058
0059 if ((rate % 44100) == 0) {
0060 data |= 0x00000100;
0061
0062 if (rate / 44100 == 2)
0063 data |= 0x00008000;
0064 } else if ((rate % 48000) == 0) {
0065 data |= 0x00000200;
0066
0067 if (rate / 48000 == 2)
0068 data |= 0x00008000;
0069 } else {
0070 return -EAGAIN;
0071 }
0072 }
0073
0074 if (clock != INT_MAX) {
0075 data &= 0x0000ff00;
0076 data |= clock + 1;
0077 }
0078
0079 reg = cpu_to_be32(data);
0080
0081 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0082 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
0083 ®, sizeof(reg), 0);
0084 if (err < 0)
0085 return err;
0086
0087 if (data & 0x00008000)
0088 reg = cpu_to_be32(0x0000001a);
0089 else
0090 reg = cpu_to_be32(0x0000000d);
0091
0092 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0093 TSCM_ADDR_BASE + TSCM_OFFSET_MULTIPLEX_MODE,
0094 ®, sizeof(reg), 0);
0095 }
0096
0097 int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate)
0098 {
0099 u32 data;
0100 int err;
0101
0102 err = get_clock(tscm, &data);
0103 if (err < 0)
0104 return err;
0105
0106 data = (data & 0xff000000) >> 24;
0107
0108
0109 if ((data & 0x0f) == 0x01)
0110 *rate = 44100;
0111 else if ((data & 0x0f) == 0x02)
0112 *rate = 48000;
0113 else
0114 return -EAGAIN;
0115
0116
0117 if ((data & 0xf0) == 0x80)
0118 *rate *= 2;
0119 else if ((data & 0xf0) != 0x00)
0120 return -EAGAIN;
0121
0122 return err;
0123 }
0124
0125 int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock)
0126 {
0127 u32 data;
0128 int err;
0129
0130 err = get_clock(tscm, &data);
0131 if (err < 0)
0132 return err;
0133
0134 *clock = ((data & 0x00ff0000) >> 16) - 1;
0135 if (*clock < 0 || *clock > SND_TSCM_CLOCK_ADAT)
0136 return -EIO;
0137
0138 return 0;
0139 }
0140
0141 static int enable_data_channels(struct snd_tscm *tscm)
0142 {
0143 __be32 reg;
0144 u32 data;
0145 unsigned int i;
0146 int err;
0147
0148 data = 0;
0149 for (i = 0; i < tscm->spec->pcm_capture_analog_channels; ++i)
0150 data |= BIT(i);
0151 if (tscm->spec->has_adat)
0152 data |= 0x0000ff00;
0153 if (tscm->spec->has_spdif)
0154 data |= 0x00030000;
0155
0156 reg = cpu_to_be32(data);
0157 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0158 TSCM_ADDR_BASE + TSCM_OFFSET_TX_PCM_CHANNELS,
0159 ®, sizeof(reg), 0);
0160 if (err < 0)
0161 return err;
0162
0163 data = 0;
0164 for (i = 0; i < tscm->spec->pcm_playback_analog_channels; ++i)
0165 data |= BIT(i);
0166 if (tscm->spec->has_adat)
0167 data |= 0x0000ff00;
0168 if (tscm->spec->has_spdif)
0169 data |= 0x00030000;
0170
0171 reg = cpu_to_be32(data);
0172 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0173 TSCM_ADDR_BASE + TSCM_OFFSET_RX_PCM_CHANNELS,
0174 ®, sizeof(reg), 0);
0175 }
0176
0177 static int set_stream_formats(struct snd_tscm *tscm, unsigned int rate)
0178 {
0179 __be32 reg;
0180 int err;
0181
0182
0183 reg = cpu_to_be32(0x00200000);
0184 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0185 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION,
0186 ®, sizeof(reg), 0);
0187 if (err < 0)
0188 return err;
0189
0190 return enable_data_channels(tscm);
0191 }
0192
0193 static void finish_session(struct snd_tscm *tscm)
0194 {
0195 __be32 reg;
0196
0197 reg = 0;
0198 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0199 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
0200 ®, sizeof(reg), 0);
0201
0202 reg = 0;
0203 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0204 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON,
0205 ®, sizeof(reg), 0);
0206
0207
0208 reg = cpu_to_be32(0x00000000);
0209 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0210 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH,
0211 ®, sizeof(reg), 0);
0212 reg = cpu_to_be32(0x00000000);
0213 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0214 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN,
0215 ®, sizeof(reg), 0);
0216 reg = cpu_to_be32(0x00000000);
0217 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0218 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH,
0219 ®, sizeof(reg), 0);
0220 }
0221
0222 static int begin_session(struct snd_tscm *tscm)
0223 {
0224 __be32 reg;
0225 int err;
0226
0227
0228 reg = cpu_to_be32(tscm->tx_resources.channel);
0229 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0230 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH,
0231 ®, sizeof(reg), 0);
0232 if (err < 0)
0233 return err;
0234
0235
0236 reg = cpu_to_be32(0x00000002);
0237 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0238 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN,
0239 ®, sizeof(reg), 0);
0240 if (err < 0)
0241 return err;
0242
0243
0244 reg = cpu_to_be32(tscm->rx_resources.channel);
0245 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0246 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH,
0247 ®, sizeof(reg), 0);
0248 if (err < 0)
0249 return err;
0250
0251 reg = cpu_to_be32(0x00000001);
0252 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0253 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
0254 ®, sizeof(reg), 0);
0255 if (err < 0)
0256 return err;
0257
0258 reg = cpu_to_be32(0x00000001);
0259 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0260 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON,
0261 ®, sizeof(reg), 0);
0262 if (err < 0)
0263 return err;
0264
0265
0266 reg = cpu_to_be32(0x00002000);
0267 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
0268 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION,
0269 ®, sizeof(reg), 0);
0270 if (err < 0)
0271 return err;
0272
0273
0274 reg = cpu_to_be32(0x00000001);
0275 return snd_fw_transaction(tscm->unit,
0276 TCODE_WRITE_QUADLET_REQUEST,
0277 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_ON,
0278 ®, sizeof(reg), 0);
0279 }
0280
0281 static int keep_resources(struct snd_tscm *tscm, unsigned int rate,
0282 struct amdtp_stream *stream)
0283 {
0284 struct fw_iso_resources *resources;
0285 int err;
0286
0287 if (stream == &tscm->tx_stream)
0288 resources = &tscm->tx_resources;
0289 else
0290 resources = &tscm->rx_resources;
0291
0292 err = amdtp_tscm_set_parameters(stream, rate);
0293 if (err < 0)
0294 return err;
0295
0296 return fw_iso_resources_allocate(resources,
0297 amdtp_stream_get_max_payload(stream),
0298 fw_parent_device(tscm->unit)->max_speed);
0299 }
0300
0301 static int init_stream(struct snd_tscm *tscm, struct amdtp_stream *s)
0302 {
0303 struct fw_iso_resources *resources;
0304 enum amdtp_stream_direction dir;
0305 unsigned int pcm_channels;
0306 int err;
0307
0308 if (s == &tscm->tx_stream) {
0309 resources = &tscm->tx_resources;
0310 dir = AMDTP_IN_STREAM;
0311 pcm_channels = tscm->spec->pcm_capture_analog_channels;
0312 } else {
0313 resources = &tscm->rx_resources;
0314 dir = AMDTP_OUT_STREAM;
0315 pcm_channels = tscm->spec->pcm_playback_analog_channels;
0316 }
0317
0318 if (tscm->spec->has_adat)
0319 pcm_channels += 8;
0320 if (tscm->spec->has_spdif)
0321 pcm_channels += 2;
0322
0323 err = fw_iso_resources_init(resources, tscm->unit);
0324 if (err < 0)
0325 return err;
0326
0327 err = amdtp_tscm_init(s, tscm->unit, dir, pcm_channels);
0328 if (err < 0)
0329 fw_iso_resources_free(resources);
0330
0331 return err;
0332 }
0333
0334 static void destroy_stream(struct snd_tscm *tscm, struct amdtp_stream *s)
0335 {
0336 amdtp_stream_destroy(s);
0337
0338 if (s == &tscm->tx_stream)
0339 fw_iso_resources_destroy(&tscm->tx_resources);
0340 else
0341 fw_iso_resources_destroy(&tscm->rx_resources);
0342 }
0343
0344 int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
0345 {
0346 int err;
0347
0348 err = init_stream(tscm, &tscm->tx_stream);
0349 if (err < 0)
0350 return err;
0351
0352 err = init_stream(tscm, &tscm->rx_stream);
0353 if (err < 0) {
0354 destroy_stream(tscm, &tscm->tx_stream);
0355 return err;
0356 }
0357
0358 err = amdtp_domain_init(&tscm->domain);
0359 if (err < 0) {
0360 destroy_stream(tscm, &tscm->tx_stream);
0361 destroy_stream(tscm, &tscm->rx_stream);
0362 }
0363
0364 return err;
0365 }
0366
0367
0368 void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
0369 {
0370 amdtp_domain_stop(&tscm->domain);
0371
0372 amdtp_stream_pcm_abort(&tscm->tx_stream);
0373 amdtp_stream_pcm_abort(&tscm->rx_stream);
0374 }
0375
0376
0377
0378 void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
0379 {
0380 amdtp_domain_destroy(&tscm->domain);
0381
0382 destroy_stream(tscm, &tscm->rx_stream);
0383 destroy_stream(tscm, &tscm->tx_stream);
0384 }
0385
0386 int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate,
0387 unsigned int frames_per_period,
0388 unsigned int frames_per_buffer)
0389 {
0390 unsigned int curr_rate;
0391 int err;
0392
0393 err = snd_tscm_stream_get_rate(tscm, &curr_rate);
0394 if (err < 0)
0395 return err;
0396
0397 if (tscm->substreams_counter == 0 || rate != curr_rate) {
0398 amdtp_domain_stop(&tscm->domain);
0399
0400 finish_session(tscm);
0401
0402 fw_iso_resources_free(&tscm->tx_resources);
0403 fw_iso_resources_free(&tscm->rx_resources);
0404
0405 err = set_clock(tscm, rate, INT_MAX);
0406 if (err < 0)
0407 return err;
0408
0409 err = keep_resources(tscm, rate, &tscm->tx_stream);
0410 if (err < 0)
0411 return err;
0412
0413 err = keep_resources(tscm, rate, &tscm->rx_stream);
0414 if (err < 0) {
0415 fw_iso_resources_free(&tscm->tx_resources);
0416 return err;
0417 }
0418
0419 err = amdtp_domain_set_events_per_period(&tscm->domain,
0420 frames_per_period, frames_per_buffer);
0421 if (err < 0) {
0422 fw_iso_resources_free(&tscm->tx_resources);
0423 fw_iso_resources_free(&tscm->rx_resources);
0424 return err;
0425 }
0426
0427 tscm->need_long_tx_init_skip = (rate != curr_rate);
0428 }
0429
0430 return 0;
0431 }
0432
0433 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
0434 {
0435 unsigned int generation = tscm->rx_resources.generation;
0436 int err;
0437
0438 if (tscm->substreams_counter == 0)
0439 return 0;
0440
0441 if (amdtp_streaming_error(&tscm->rx_stream) ||
0442 amdtp_streaming_error(&tscm->tx_stream)) {
0443 amdtp_domain_stop(&tscm->domain);
0444 finish_session(tscm);
0445 }
0446
0447 if (generation != fw_parent_device(tscm->unit)->card->generation) {
0448 err = fw_iso_resources_update(&tscm->tx_resources);
0449 if (err < 0)
0450 goto error;
0451
0452 err = fw_iso_resources_update(&tscm->rx_resources);
0453 if (err < 0)
0454 goto error;
0455 }
0456
0457 if (!amdtp_stream_running(&tscm->rx_stream)) {
0458 int spd = fw_parent_device(tscm->unit)->max_speed;
0459 unsigned int tx_init_skip_cycles;
0460
0461 err = set_stream_formats(tscm, rate);
0462 if (err < 0)
0463 goto error;
0464
0465 err = begin_session(tscm);
0466 if (err < 0)
0467 goto error;
0468
0469 err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
0470 tscm->rx_resources.channel, spd);
0471 if (err < 0)
0472 goto error;
0473
0474 err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
0475 tscm->tx_resources.channel, spd);
0476 if (err < 0)
0477 goto error;
0478
0479 if (tscm->need_long_tx_init_skip)
0480 tx_init_skip_cycles = 16000;
0481 else
0482 tx_init_skip_cycles = 0;
0483
0484
0485
0486
0487
0488
0489
0490
0491 err = amdtp_domain_start(&tscm->domain, tx_init_skip_cycles, true, true);
0492 if (err < 0)
0493 return err;
0494
0495 if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) {
0496 err = -ETIMEDOUT;
0497 goto error;
0498 }
0499 }
0500
0501 return 0;
0502 error:
0503 amdtp_domain_stop(&tscm->domain);
0504 finish_session(tscm);
0505
0506 return err;
0507 }
0508
0509 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
0510 {
0511 if (tscm->substreams_counter == 0) {
0512 amdtp_domain_stop(&tscm->domain);
0513 finish_session(tscm);
0514
0515 fw_iso_resources_free(&tscm->tx_resources);
0516 fw_iso_resources_free(&tscm->rx_resources);
0517
0518 tscm->need_long_tx_init_skip = false;
0519 }
0520 }
0521
0522 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
0523 {
0524 tscm->dev_lock_changed = true;
0525 wake_up(&tscm->hwdep_wait);
0526 }
0527
0528 int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
0529 {
0530 int err;
0531
0532 spin_lock_irq(&tscm->lock);
0533
0534
0535 if (tscm->dev_lock_count < 0) {
0536 err = -EBUSY;
0537 goto end;
0538 }
0539
0540
0541 if (tscm->dev_lock_count++ == 0)
0542 snd_tscm_stream_lock_changed(tscm);
0543 err = 0;
0544 end:
0545 spin_unlock_irq(&tscm->lock);
0546 return err;
0547 }
0548
0549 void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
0550 {
0551 spin_lock_irq(&tscm->lock);
0552
0553 if (WARN_ON(tscm->dev_lock_count <= 0))
0554 goto end;
0555 if (--tscm->dev_lock_count == 0)
0556 snd_tscm_stream_lock_changed(tscm);
0557 end:
0558 spin_unlock_irq(&tscm->lock);
0559 }