diff options
Diffstat (limited to 'sound/firewire')
-rw-r--r-- | sound/firewire/dice/dice-pcm.c | 35 | ||||
-rw-r--r-- | sound/firewire/dice/dice-stream.c | 35 | ||||
-rw-r--r-- | sound/firewire/dice/dice-transaction.c | 5 | ||||
-rw-r--r-- | sound/firewire/dice/dice.h | 2 |
4 files changed, 58 insertions, 19 deletions
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c index b9ce0264a2d9..062b7a3b7fd0 100644 --- a/sound/firewire/dice/dice-pcm.c +++ b/sound/firewire/dice/dice-pcm.c @@ -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: diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index e60b84d7a0f6..20765a05d294 100644 --- a/sound/firewire/dice/dice-stream.c +++ b/sound/firewire/dice/dice-stream.c @@ -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; } diff --git a/sound/firewire/dice/dice-transaction.c b/sound/firewire/dice/dice-transaction.c index 1fe304c0a044..aee746187665 100644 --- a/sound/firewire/dice/dice-transaction.c +++ b/sound/firewire/dice/dice-transaction.c @@ -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) { diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h index a62ee22da5cc..f30326e22288 100644 --- a/sound/firewire/dice/dice.h +++ b/sound/firewire/dice/dice.h @@ -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); |