+static int wm5102_spk_ev(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+ struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
+
+ if (arizona->rev < 1)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (!wm5102->spk_ena) {
+ snd_soc_write(codec, 0x4f5, 0x25a);
+ wm5102->spk_ena_pending = true;
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if (wm5102->spk_ena_pending) {
+ msleep(75);
+ snd_soc_write(codec, 0x4f5, 0xda);
+ wm5102->spk_ena_pending = false;
+ wm5102->spk_ena++;
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ wm5102->spk_ena--;
+ if (!wm5102->spk_ena)
+ snd_soc_write(codec, 0x4f5, 0x25a);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (!wm5102->spk_ena)
+ snd_soc_write(codec, 0x4f5, 0x0da);
+ break;
+ }
+
+ return 0;
+}
+
+