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 fbeac84dbe ("ALSA: dice: old firmware optimization for Dice notification")
 * commit aec045b80d ("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>
This commit is contained in:
Takashi Sakamoto 2021-06-01 17:17:51 +09:00 committed by Takashi Iwai
parent dfacca3986
commit 41319eb56e
2 changed files with 8 additions and 23 deletions

View file

@ -9,7 +9,7 @@
#include "dice.h"
#define READY_TIMEOUT_MS 200
#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
#define NOTIFICATION_TIMEOUT_MS 100
struct reg_params {
unsigned int count;
@ -57,13 +57,9 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
return -EINVAL;
}
/*
* This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE
* to GLOBAL_STATUS. Especially, just after powering on, these are different.
*/
static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate)
static int select_clock(struct snd_dice *dice, unsigned int rate)
{
__be32 reg, nominal;
__be32 reg;
u32 data;
int i;
int err;
@ -94,19 +90,8 @@ static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate)
return err;
if (wait_for_completion_timeout(&dice->clock_accepted,
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;
}
msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
return -ETIMEDOUT;
return 0;
}
@ -304,7 +289,7 @@ int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate,
// Just after owning the unit (GLOBAL_OWNER), the unit can
// return invalid stream formats. Selecting clock parameters
// have an effect for the unit to refine it.
err = ensure_phase_lock(dice, rate);
err = select_clock(dice, rate);
if (err < 0)
return err;
@ -646,7 +631,7 @@ int snd_dice_stream_detect_current_formats(struct snd_dice *dice)
* invalid stream formats. Selecting clock parameters have an effect
* for the unit to refine it.
*/
err = ensure_phase_lock(dice, rate);
err = select_clock(dice, rate);
if (err < 0)
return err;

View file

@ -155,7 +155,7 @@ static void dice_notification(struct fw_card *card, struct fw_request *request,
fw_send_response(card, request, RCODE_COMPLETE);
if (bits & NOTIFY_LOCK_CHG)
if (bits & NOTIFY_CLOCK_ACCEPTED)
complete(&dice->clock_accepted);
wake_up(&dice->hwdep_wait);
}