+static int stac92xx_pre_resume(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+
+ /* sync mute LED */
+ if (spec->gpio_led) {
+ if (spec->gpio_led <= 8) {
+ stac_gpio_set(codec, spec->gpio_mask,
+ spec->gpio_dir, spec->gpio_data);
+ } else {
+ stac_vrefout_set(codec,
+ spec->gpio_led, spec->vref_led);
+ }
+ }
+ return 0;
+}
+
+static int stac92xx_post_suspend(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ if (spec->gpio_led > 8) {
+ /* with vref-out pin used for mute led control
+ * codec AFG is prevented from D3 state, but on
+ * system suspend it can (and should) be used
+ */
+ snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+ }
+ return 0;
+}
+
+static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state)
+{
+ unsigned int afg_power_state = power_state;
+ struct sigmatel_spec *spec = codec->spec;
+
+ if (power_state == AC_PWRST_D3) {
+ if (spec->gpio_led > 8) {
+ /* with vref-out pin used for mute led control
+ * codec AFG is prevented from D3 state
+ */
+ afg_power_state = AC_PWRST_D1;
+ }
+ /* this delay seems necessary to avoid click noise at power-down */
+ msleep(100);
+ }
+ snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+ afg_power_state);
+ snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
+}
+