From fbeac84dbe9e72d58b1377a0d1bc8a58f40ce31a Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Thu, 11 Feb 2016 20:18:38 +0900 Subject: [PATCH 8/8] 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 Signed-off-by: Takashi Iwai --- sound/firewire/dice/dice-stream.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c index e4938b0cddbe..a64b3cc76bf1 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; } -- 2.4.10