Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: dice: wait just for NOTIFY_CLOCK_ACCEPTED after GLOBAL_CLOCK_SELECT operation

NOTIFY_CLOCK_ACCEPTED notification is always generated as a result of
GLOBAL_CLOCK_SELECT operation, however NOTIFY_LOCK_CHG notification
doesn't, as long as the selected clock is already configured. In the case,
ALSA dice driver waits so long. It's inconvenient for some devices to lock
to the sequence of value in syt field of CIP header in rx packets.

This commit wait just for NOTIFY_CLOCK_ACCEPTED notification by reverting
changes partially done by two commits below:

* commit fbeac84dbe9e ("ALSA: dice: old firmware optimization for Dice notification")
* commit aec045b80d79 ("ALSA: dice: change notification mask to detect lock status change")

I note that the successful lock to the sequence of value in syt field of
CIP header in rx packets results in NOTIFY_EXT_STATUS notification, then
EXT_STATUS_ARX1_LOCKED bit stands in GLOBAL_EXTENDED_STATUS register.
The notification can occur enough after receiving the batch of rx packets.
When the sequence doesn't include value in syt field of CIP header in rx
packets adequate to the device, the notification occurs again and the bit
is off.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20210601081753.9191-2-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Sakamoto and committed by
Takashi Iwai
41319eb5 dfacca39

+8 -23
+7 -22
sound/firewire/dice/dice-stream.c
··· 9 9 #include "dice.h" 10 10 11 11 #define READY_TIMEOUT_MS 200 12 - #define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC) 12 + #define NOTIFICATION_TIMEOUT_MS 100 13 13 14 14 struct reg_params { 15 15 unsigned int count; ··· 57 57 return -EINVAL; 58 58 } 59 59 60 - /* 61 - * This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE 62 - * to GLOBAL_STATUS. Especially, just after powering on, these are different. 63 - */ 64 - static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate) 60 + static int select_clock(struct snd_dice *dice, unsigned int rate) 65 61 { 66 - __be32 reg, nominal; 62 + __be32 reg; 67 63 u32 data; 68 64 int i; 69 65 int err; ··· 90 94 return err; 91 95 92 96 if (wait_for_completion_timeout(&dice->clock_accepted, 93 - msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { 94 - /* 95 - * Old versions of Dice firmware transfer no notification when 96 - * the same clock status as current one is set. In this case, 97 - * just check current clock status. 98 - */ 99 - err = snd_dice_transaction_read_global(dice, GLOBAL_STATUS, 100 - &nominal, sizeof(nominal)); 101 - if (err < 0) 102 - return err; 103 - if (!(be32_to_cpu(nominal) & STATUS_SOURCE_LOCKED)) 104 - return -ETIMEDOUT; 105 - } 97 + msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) 98 + return -ETIMEDOUT; 106 99 107 100 return 0; 108 101 } ··· 289 304 // Just after owning the unit (GLOBAL_OWNER), the unit can 290 305 // return invalid stream formats. Selecting clock parameters 291 306 // have an effect for the unit to refine it. 292 - err = ensure_phase_lock(dice, rate); 307 + err = select_clock(dice, rate); 293 308 if (err < 0) 294 309 return err; 295 310 ··· 631 646 * invalid stream formats. Selecting clock parameters have an effect 632 647 * for the unit to refine it. 633 648 */ 634 - err = ensure_phase_lock(dice, rate); 649 + err = select_clock(dice, rate); 635 650 if (err < 0) 636 651 return err; 637 652
+1 -1
sound/firewire/dice/dice-transaction.c
··· 155 155 156 156 fw_send_response(card, request, RCODE_COMPLETE); 157 157 158 - if (bits & NOTIFY_LOCK_CHG) 158 + if (bits & NOTIFY_CLOCK_ACCEPTED) 159 159 complete(&dice->clock_accepted); 160 160 wake_up(&dice->hwdep_wait); 161 161 }