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);
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:
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)
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;
}
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)
{
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);