#define WM8960_DISOP 0x40
#define WM8960_DRES_MASK 0x30
+#define WM8960_DSCH_TOUT 600 /* discharge timeout, ms */
+
static bool is_pll_freq_available(unsigned int source, unsigned int target);
static int wm8960_set_pll(struct snd_soc_component *component,
unsigned int freq_in, unsigned int freq_out);
int freq_in;
bool is_stream_in_use[2];
struct wm8960_data pdata;
+ ktime_t dsch_start;
};
#define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
u16 pm2 = snd_soc_component_read(component, WM8960_POWER2);
int ret;
+ ktime_t tout;
switch (level) {
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_STANDBY:
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+ /* ensure discharge is complete */
+ tout = WM8960_DSCH_TOUT - ktime_ms_delta(ktime_get(), wm8960->dsch_start);
+ if (tout > 0)
+ msleep(tout);
+
regcache_sync(wm8960->regmap);
/* Enable anti-pop features */
WM8960_POBCTRL | WM8960_SOFT_ST |
WM8960_BUFDCOPEN | WM8960_BUFIOEN);
- /* Disable VMID and VREF, let them discharge */
+ /* Disable VMID and VREF, mark discharge */
snd_soc_component_write(component, WM8960_POWER1, 0);
- msleep(600);
+ wm8960->dsch_start = ktime_get();
break;
}