unsigned int hifi_fmt;
 
        int dai_func;
+       struct delayed_work charge_work;
 };
 
 #define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
        return 0;
 }
 
+static void wm8753_charge_work(struct work_struct *work)
+{
+       struct wm8753_priv *wm8753 =
+               container_of(work, struct wm8753_priv, charge_work.work);
+
+       /* Set to 500k */
+       regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
+}
+
 static int wm8753_set_bias_level(struct snd_soc_codec *codec,
                                 enum snd_soc_bias_level level)
 {
+       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
        u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
 
        switch (level) {
                snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
                break;
        case SND_SOC_BIAS_PREPARE:
-               /* set vmid to 5k for quick power up */
-               snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+               /* Wait until fully charged */
+               flush_delayed_work(&wm8753->charge_work);
                break;
        case SND_SOC_BIAS_STANDBY:
-               /* mute dac and set vmid to 500k, enable VREF */
-               snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+                       /* set vmid to 5k for quick power up */
+                       snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+                       schedule_delayed_work(&wm8753->charge_work,
+                               msecs_to_jiffies(caps_charge));
+               } else {
+                       /* mute dac and set vmid to 500k, enable VREF */
+                       snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+               }
                break;
        case SND_SOC_BIAS_OFF:
+               cancel_delayed_work_sync(&wm8753->charge_work);
                snd_soc_write(codec, WM8753_PWR1, 0x0001);
                break;
        }
 },
 };
 
-static void wm8753_work(struct work_struct *work)
-{
-       struct snd_soc_dapm_context *dapm =
-               container_of(work, struct snd_soc_dapm_context,
-                            delayed_work.work);
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       wm8753_set_bias_level(codec, dapm->bias_level);
-}
-
 static int wm8753_suspend(struct snd_soc_codec *codec)
 {
        wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
        regcache_sync(wm8753->regmap);
 
        wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-       /* charge wm8753 caps */
-       if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
-               wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
-               codec->dapm.bias_level = SND_SOC_BIAS_ON;
-               queue_delayed_work(system_power_efficient_wq,
-                                  &codec->dapm.delayed_work,
-                                  msecs_to_jiffies(caps_charge));
-       }
-
        return 0;
 }
 
        struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
+       INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
 
        ret = wm8753_reset(codec);
        if (ret < 0) {
        wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
        wm8753->dai_func = 0;
 
-       /* charge output caps */
-       wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
-       schedule_delayed_work(&codec->dapm.delayed_work,
-                             msecs_to_jiffies(caps_charge));
-
        /* set the update bits */
        snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
        snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
 /* power down chip */
 static int wm8753_remove(struct snd_soc_codec *codec)
 {
-       flush_delayed_work(&codec->dapm.delayed_work);
        wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
        return 0;