ALSA: dice: Support for non SYT-Match sampling clock source mode
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 8 Dec 2014 15:10:37 +0000 (00:10 +0900)
committerTakashi Iwai <tiwai@suse.de>
Wed, 10 Dec 2014 09:45:28 +0000 (10:45 +0100)
This commit allows this driver to handle devices with non SYT-Match
sampling clock source.

When sampling clock source is SYT-Match mode, devices handle
'presentation timestamp' in received packets and generates sampling clock
according to the information. In this case, driver is synchronization master
and must transfer correct value in SYT field of each packets in outgoing
stream, then the outgoing stream is a master stream.

On the other hand, non SYT-Match mode, devices do this. So drivers must pick
up the value in SYT field of incoming packets and use the value for outgoing
stream. Currently firewire-lib module achieve this work.

Furthermore, without SYT-Match and internal clock source, the sampling rate
should be fixed for the other devices connected to the handled device. This
commit add a restriction of sampling rate at this situation.

With these implementations, this driver has no need to set clock source.
This commit remove set function.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Acked-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/dice/dice-pcm.c
sound/firewire/dice/dice-stream.c
sound/firewire/dice/dice-transaction.c
sound/firewire/dice/dice.h

index b9ce0264a2d96db45d55036a02d268e15ed920a5..062b7a3b7fd0cd66e7caf7dedb536a77d7822afb 100644 (file)
@@ -140,6 +140,8 @@ end:
 static int pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_dice *dice = substream->private_data;
+       unsigned int source, rate;
+       bool internal;
        int err;
 
        err = snd_dice_stream_lock_try(dice);
@@ -149,6 +151,39 @@ static int pcm_open(struct snd_pcm_substream *substream)
        err = init_hw_info(dice, substream);
        if (err < 0)
                goto err_locked;
+
+       err = snd_dice_transaction_get_clock_source(dice, &source);
+       if (err < 0)
+               goto err_locked;
+       switch (source) {
+       case CLOCK_SOURCE_AES1:
+       case CLOCK_SOURCE_AES2:
+       case CLOCK_SOURCE_AES3:
+       case CLOCK_SOURCE_AES4:
+       case CLOCK_SOURCE_AES_ANY:
+       case CLOCK_SOURCE_ADAT:
+       case CLOCK_SOURCE_TDIF:
+       case CLOCK_SOURCE_WC:
+               internal = false;
+               break;
+       default:
+               internal = true;
+               break;
+       }
+
+       /*
+        * When source of clock is not internal, available sampling rate is
+        * limited at current sampling rate.
+        */
+       if (!internal) {
+               err = snd_dice_transaction_get_rate(dice, &rate);
+               if (err < 0)
+                       goto err_locked;
+               substream->runtime->hw.rate_min = rate;
+               substream->runtime->hw.rate_max = rate;
+       }
+
+       snd_pcm_set_sync(substream);
 end:
        return err;
 err_locked:
index e60b84d7a0f6bcab6fbfbbdd720747c97345d656..20765a05d294f78fdf5c17e223badbab23924d52 100644 (file)
@@ -161,9 +161,29 @@ end:
 
 static int get_sync_mode(struct snd_dice *dice, enum cip_flags *sync_mode)
 {
-       /* Currently, clock source is fixed at SYT-Match mode. */
-       *sync_mode = 0;
-       return 0;
+       u32 source;
+       int err;
+
+       err = snd_dice_transaction_get_clock_source(dice, &source);
+       if (err < 0)
+               goto end;
+
+       switch (source) {
+       /* So-called 'SYT Match' modes, sync_to_syt value of packets received */
+       case CLOCK_SOURCE_ARX4: /* in 4th stream */
+       case CLOCK_SOURCE_ARX3: /* in 3rd stream */
+       case CLOCK_SOURCE_ARX2: /* in 2nd stream */
+               err = -ENOSYS;
+               break;
+       case CLOCK_SOURCE_ARX1: /* in 1st stream, which this driver uses */
+               *sync_mode = 0;
+               break;
+       default:
+               *sync_mode = CIP_SYNC_TO_DEVICE;
+               break;
+       }
+end:
+       return err;
 }
 
 int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
@@ -310,15 +330,6 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
                goto end;
 
        err = init_stream(dice, &dice->rx_stream);
-       if (err < 0)
-               goto end;
-
-       /* Currently, clock source is fixed at SYT-Match mode. */
-       err = snd_dice_transaction_set_clock_source(dice, CLOCK_SOURCE_ARX1);
-       if (err < 0) {
-               destroy_stream(dice, &dice->rx_stream);
-               destroy_stream(dice, &dice->tx_stream);
-       }
 end:
        return err;
 }
index 1fe304c0a0444d8c9c46fdbff00bdf77d87b1c97..aee746187665850c9f43e9c18123f708696356c1 100644 (file)
@@ -137,11 +137,6 @@ int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
 
        return err;
 }
-int snd_dice_transaction_set_clock_source(struct snd_dice *dice,
-                                         unsigned int source)
-{
-       return set_clock_info(dice, UINT_MAX, source);
-}
 
 int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate)
 {
index a62ee22da5cc0adc40ebc20d44fa78def0785602..f30326e222880784c0dbef11e41f6e9cad176f8a 100644 (file)
@@ -152,8 +152,6 @@ static inline int snd_dice_transaction_read_sync(struct snd_dice *dice,
                                         buf, len);
 }
 
-int snd_dice_transaction_set_clock_source(struct snd_dice *dice,
-                                         unsigned int source);
 int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
                                          unsigned int *source);
 int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate);