diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2016-02-11 20:18:38 +0900 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-02-12 09:52:49 +0100 |
commit | fbeac84dbe9e72d58b1377a0d1bc8a58f40ce31a (patch) | |
tree | 0bfc1bf94a6b72c9ff5289e30020c7e20227aeb8 /sound | |
parent | aec045b80d79bdc2cdd9b0003ff85b0470107e18 (diff) | |
download | op-kernel-dev-fbeac84dbe9e72d58b1377a0d1bc8a58f40ce31a.zip op-kernel-dev-fbeac84dbe9e72d58b1377a0d1bc8a58f40ce31a.tar.gz |
ALSA: dice: old firmware optimization for Dice notification
As long as I tested, Dice-based models produced by TC Electronic with
factory-configured settings transfer no notification within
ensure_phase_lock(). On the other hand, with upgraded firmwares, it
starts to transfer the notification. This seems to be a quirk of earlier
firmwares.
This commit ensures phase lock by reading a register after waiting for
the notification. Even if it's timed-out, ensure_phase_lock() return
success as long as the register has expected clock status.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/firewire/dice/dice-stream.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index e4938b0..a64b3cc 100644 --- a/sound/firewire/dice/dice-stream.c +++ b/sound/firewire/dice/dice-stream.c @@ -31,7 +31,7 @@ const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = { */ static int ensure_phase_lock(struct snd_dice *dice) { - __be32 reg; + __be32 reg, nominal; int err; err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT, @@ -48,8 +48,19 @@ static int ensure_phase_lock(struct snd_dice *dice) return err; if (wait_for_completion_timeout(&dice->clock_accepted, - msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) - return -ETIMEDOUT; + msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { + /* + * Old versions of Dice firmware transfer no notification when + * the same clock status as current one is set. In this case, + * just check current clock status. + */ + err = snd_dice_transaction_read_global(dice, GLOBAL_STATUS, + &nominal, sizeof(nominal)); + if (err < 0) + return err; + if (!(be32_to_cpu(nominal) & STATUS_SOURCE_LOCKED)) + return -ETIMEDOUT; + } return 0; } |