Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * tascam-stream.c - a part of driver for TASCAM FireWire series
0004  *
0005  * Copyright (c) 2015 Takashi Sakamoto
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                 &reg, 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         // In intermediate state after changing clock status.
0034         msleep(50);
0035     }
0036 
0037     // Still in the intermediate state.
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         /* Base rate. */
0059         if ((rate % 44100) == 0) {
0060             data |= 0x00000100;
0061             /* Multiplier. */
0062             if (rate / 44100 == 2)
0063                 data |= 0x00008000;
0064         } else if ((rate % 48000) == 0) {
0065             data |= 0x00000200;
0066             /* Multiplier. */
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                  &reg, 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                   &reg, 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     /* Check base rate. */
0109     if ((data & 0x0f) == 0x01)
0110         *rate = 44100;
0111     else if ((data & 0x0f) == 0x02)
0112         *rate = 48000;
0113     else
0114         return -EAGAIN;
0115 
0116     /* Check multiplier. */
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                  &reg, 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                   &reg, 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     // Set an option for unknown purpose.
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                  &reg, 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                &reg, 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                &reg, sizeof(reg), 0);
0206 
0207     // Unregister channels.
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                &reg, 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                &reg, 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                &reg, sizeof(reg), 0);
0220 }
0221 
0222 static int begin_session(struct snd_tscm *tscm)
0223 {
0224     __be32 reg;
0225     int err;
0226 
0227     // Register the isochronous channel for transmitting stream.
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                  &reg, sizeof(reg), 0);
0232     if (err < 0)
0233         return err;
0234 
0235     // Unknown.
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                  &reg, sizeof(reg), 0);
0240     if (err < 0)
0241         return err;
0242 
0243     // Register the isochronous channel for receiving stream.
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                  &reg, 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                  &reg, 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                  &reg, sizeof(reg), 0);
0262     if (err < 0)
0263         return err;
0264 
0265     // Set an option for unknown purpose.
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                  &reg, sizeof(reg), 0);
0270     if (err < 0)
0271         return err;
0272 
0273     // Start multiplexing PCM samples on packets.
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                   &reg, 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 // At bus reset, streaming is stopped and some registers are clear.
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 // This function should be called before starting streams or after stopping
0377 // streams.
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         // MEMO: Just after starting packet streaming, it transfers packets without any
0485         // event. Enough after receiving the sequence of packets, it multiplexes events into
0486         // the packet. However, just after changing sampling transfer frequency, it stops
0487         // multiplexing during packet transmission. Enough after, it restarts multiplexing
0488         // again. The device ignores presentation time expressed by the value of syt field
0489         // of CIP header in received packets. The sequence of the number of data blocks per
0490         // packet is important for media clock recovery.
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     /* user land lock this */
0535     if (tscm->dev_lock_count < 0) {
0536         err = -EBUSY;
0537         goto end;
0538     }
0539 
0540     /* this is the first time */
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 }