Commit 41319eb5 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

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 fbeac84d ("ALSA: dice: old firmware optimization for Dice notification")
 * commit aec045b8 ("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: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20210601081753.9191-2-o-takashi@sakamocchi.jpSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent dfacca39
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "dice.h" #include "dice.h"
#define READY_TIMEOUT_MS 200 #define READY_TIMEOUT_MS 200
#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC) #define NOTIFICATION_TIMEOUT_MS 100
struct reg_params { struct reg_params {
unsigned int count; unsigned int count;
...@@ -57,13 +57,9 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate, ...@@ -57,13 +57,9 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
return -EINVAL; return -EINVAL;
} }
/* static int select_clock(struct snd_dice *dice, unsigned int rate)
* 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)
{ {
__be32 reg, nominal; __be32 reg;
u32 data; u32 data;
int i; int i;
int err; int err;
...@@ -94,19 +90,8 @@ static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate) ...@@ -94,19 +90,8 @@ static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate)
return err; return err;
if (wait_for_completion_timeout(&dice->clock_accepted, if (wait_for_completion_timeout(&dice->clock_accepted,
msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { 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 -ETIMEDOUT;
}
return 0; return 0;
} }
...@@ -304,7 +289,7 @@ int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate, ...@@ -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 // Just after owning the unit (GLOBAL_OWNER), the unit can
// return invalid stream formats. Selecting clock parameters // return invalid stream formats. Selecting clock parameters
// have an effect for the unit to refine it. // have an effect for the unit to refine it.
err = ensure_phase_lock(dice, rate); err = select_clock(dice, rate);
if (err < 0) if (err < 0)
return err; return err;
...@@ -646,7 +631,7 @@ int snd_dice_stream_detect_current_formats(struct snd_dice *dice) ...@@ -646,7 +631,7 @@ int snd_dice_stream_detect_current_formats(struct snd_dice *dice)
* invalid stream formats. Selecting clock parameters have an effect * invalid stream formats. Selecting clock parameters have an effect
* for the unit to refine it. * for the unit to refine it.
*/ */
err = ensure_phase_lock(dice, rate); err = select_clock(dice, rate);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -155,7 +155,7 @@ static void dice_notification(struct fw_card *card, struct fw_request *request, ...@@ -155,7 +155,7 @@ static void dice_notification(struct fw_card *card, struct fw_request *request,
fw_send_response(card, request, RCODE_COMPLETE); fw_send_response(card, request, RCODE_COMPLETE);
if (bits & NOTIFY_LOCK_CHG) if (bits & NOTIFY_CLOCK_ACCEPTED)
complete(&dice->clock_accepted); complete(&dice->clock_accepted);
wake_up(&dice->hwdep_wait); wake_up(&dice->hwdep_wait);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment