return 0;
        val &= mask;
        val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
-       if (info->vol[ch] == val && !codec->in_resume)
+       if (info->vol[ch] == val)
                return 0;
        put_vol_mute(codec, info, nid, ch, direction, idx, val);
        return 1;
 }
 
+#ifdef CONFIG_PM
 /* resume the all amp commands from the cache */
 void snd_hda_codec_resume_amp(struct hda_codec *codec)
 {
                }
        }
 }
+#endif /* CONFIG_PM */
 
 /*
  * AMP control callbacks
        change = codec->spdif_ctls != val;
        codec->spdif_ctls = val;
 
-       if (change || codec->in_resume) {
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-                                   val & 0xff);
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2,
-                                   val >> 8);
+       if (change) {
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_DIGI_CONVERT_1,
+                                         val & 0xff);
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_DIGI_CONVERT_2,
+                                         val >> 8);
        }
 
        mutex_unlock(&codec->spdif_mutex);
        if (ucontrol->value.integer.value[0])
                val |= AC_DIG1_ENABLE;
        change = codec->spdif_ctls != val;
-       if (change || codec->in_resume) {
+       if (change) {
                codec->spdif_ctls = val;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-                                   val & 0xff);
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_DIGI_CONVERT_1,
+                                         val & 0xff);
                /* unmute amp switch (if any) */
                if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
-                   (val & AC_DIG1_ENABLE))
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
-                                           AC_AMP_SET_OUTPUT);
+                   (val & AC_DIG1_ENABLE)) {
+                       snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
+                                                0x80, 0x00);
+                       snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
+                                                0x80, 0x00);
+               }
        }
        mutex_unlock(&codec->spdif_mutex);
        return change;
 
        mutex_lock(&codec->spdif_mutex);
        change = codec->spdif_in_enable != val;
-       if (change || codec->in_resume) {
+       if (change) {
                codec->spdif_in_enable = val;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-                                   val);
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_DIGI_CONVERT_1, val);
        }
        mutex_unlock(&codec->spdif_mutex);
        return change;
        return 0;
 }
 
+#ifdef CONFIG_PM
+/*
+ * command cache
+ */
 
 /* build a 32bit cache key with the widget id and the command parameter */
 #define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
                snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
                                          seq->param);
 }
+#endif /* CONFIG_PM */
 
 /*
  * set power state of the codec
 
        mode = ucontrol->value.enumerated.item[0];
        snd_assert(mode < num_chmodes, return -EINVAL);
-       if (*max_channelsp == chmode[mode].channels && !codec->in_resume)
+       if (*max_channelsp == chmode[mode].channels)
                return 0;
        /* change the current channel setting */
        *max_channelsp = chmode[mode].channels;
        if (chmode[mode].sequence)
-               snd_hda_sequence_write(codec, chmode[mode].sequence);
+               snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
        return 1;
 }
 
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && !codec->in_resume)
+       if (*cur_val == idx)
                return 0;
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
-                           imux->items[idx].index);
+       snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
+                                 imux->items[idx].index);
        *cur_val = idx;
        return 1;
 }
                                    AC_PWRST_D0);
                if (codec->patch_ops.resume)
                        codec->patch_ops.resume(codec);
-       }
-       return 0;
-}
-
-/**
- * snd_hda_resume_ctls - resume controls in the new control list
- * @codec: the HDA codec
- * @knew: the array of struct snd_kcontrol_new
- *
- * This function resumes the mixer controls in the struct snd_kcontrol_new array,
- * originally for snd_hda_add_new_ctls().
- * The array must be terminated with an empty entry as terminator.
- */
-int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
-{
-       struct snd_ctl_elem_value *val;
-
-       val = kmalloc(sizeof(*val), GFP_KERNEL);
-       if (!val)
-               return -ENOMEM;
-       codec->in_resume = 1;
-       for (; knew->name; knew++) {
-               int i, count;
-               count = knew->count ? knew->count : 1;
-               for (i = 0; i < count; i++) {
-                       memset(val, 0, sizeof(*val));
-                       val->id.iface = knew->iface;
-                       val->id.device = knew->device;
-                       val->id.subdevice = knew->subdevice;
-                       strcpy(val->id.name, knew->name);
-                       val->id.index = knew->index ? knew->index : i;
-                       /* Assume that get callback reads only from cache,
-                        * not accessing to the real hardware
-                        */
-                       if (snd_ctl_elem_read(codec->bus->card, val) < 0)
-                               continue;
-                       snd_ctl_elem_write(codec->bus->card, NULL, val);
+               else {
+                       codec->patch_ops.init(codec);
+                       snd_hda_codec_resume_amp(codec);
+                       snd_hda_codec_resume_cache(codec);
                }
        }
-       codec->in_resume = 0;
-       kfree(val);
        return 0;
 }
 
-/**
- * snd_hda_resume_spdif_out - resume the digital out
- * @codec: the HDA codec
- */
-int snd_hda_resume_spdif_out(struct hda_codec *codec)
-{
-       return snd_hda_resume_ctls(codec, dig_mixes);
-}
-
-/**
- * snd_hda_resume_spdif_in - resume the digital in
- * @codec: the HDA codec
- */
-int snd_hda_resume_spdif_in(struct hda_codec *codec)
-{
-       return snd_hda_resume_ctls(codec, dig_in_ctls);
-}
 #endif
 
        /* set by patch */
        struct hda_codec_ops patch_ops;
 
-       /* resume phase - all controls should update even if
-        * the values are not changed
-        */
-       unsigned int in_resume;
-
        /* PCM to create, set by patch_ops.build_pcms callback */
        unsigned int num_pcms;
        struct hda_pcm *pcm_info;
 int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
 
 /* cached write */
+#ifdef CONFIG_PM
 int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
                              int direct, unsigned int verb, unsigned int parm);
 void snd_hda_sequence_write_cache(struct hda_codec *codec,
                                  const struct hda_verb *seq);
 void snd_hda_codec_resume_cache(struct hda_codec *codec);
+#else
+#define snd_hda_codec_write_cache      snd_hda_codec_write
+#define snd_hda_sequence_write_cache   snd_hda_sequence_write
+#endif
 
 /*
  * Mixer
 
        ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
        if (val >= ofs)
                val -= ofs;
-       val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
-       val |= AC_AMP_SET_OUTPUT;
-       return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
+       snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 0, 0xff, val);
+       snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 1, 0xff, val);
+       return 0;
 }
 
 /*
        ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
        if (val >= ofs)
                val -= ofs;
-       val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
-       val |= AC_AMP_SET_INPUT;
-       // awk added - fixed to allow unmuting of indexed amps
-       val |= index << AC_AMP_SET_INDEX_SHIFT;
-       return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
+       snd_hda_codec_amp_update(codec, node->nid, 0, HDA_INPUT, index,
+                                0xff, val);
+       snd_hda_codec_amp_update(codec, node->nid, 1, HDA_INPUT, index,
+                                0xff, val);
+       return 0;
 }
 
 /*
                                   unsigned int index)
 {
        snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index);
-       return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_CONNECT_SEL, index);
+       return snd_hda_codec_write_cache(codec, node->nid, 0,
+                                        AC_VERB_SET_CONNECT_SEL, index);
 }
 
 /*
                        /* unmute the PIN output */
                        unmute_output(codec, node);
                        /* set PIN-Out enable */
-                       snd_hda_codec_write(codec, node->nid, 0,
+                       snd_hda_codec_write_cache(codec, node->nid, 0,
                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
                                            AC_PINCTL_OUT_EN |
                                            ((node->pin_caps & AC_PINCAP_HP_DRV) ?
        /* unmute the PIN external input */
        unmute_input(codec, node, 0); /* index = 0? */
        /* set PIN-In enable */
-       snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
+       snd_hda_codec_write_cache(codec, node->nid, 0,
+                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
 
        return 1; /* found */
 }
 
                           int direction, int index);
 int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
                             int direction, int idx, int mask, int val);
+#ifdef CONFIG_PM
 void snd_hda_codec_resume_amp(struct hda_codec *codec);
+#endif
 
 /* mono switch binding multiple inputs */
 #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
 int snd_hda_add_new_ctls(struct hda_codec *codec,
                         struct snd_kcontrol_new *knew);
 
-/*
- * power management
- */
-#ifdef CONFIG_PM
-int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
-int snd_hda_resume_spdif_out(struct hda_codec *codec);
-int snd_hda_resume_spdif_in(struct hda_codec *codec);
-#endif
-
 /*
  * unsolicited event handler
  */
 
        kfree(codec->spec);
 }
 
-#ifdef CONFIG_PM
-static int ad198x_resume(struct hda_codec *codec)
-{
-       struct ad198x_spec *spec = codec->spec;
-       int i;
-
-       codec->patch_ops.init(codec);
-       for (i = 0; i < spec->num_mixers; i++)
-               snd_hda_resume_ctls(codec, spec->mixers[i]);
-       if (spec->multiout.dig_out_nid)
-               snd_hda_resume_spdif_out(codec);
-       if (spec->dig_in_nid)
-               snd_hda_resume_spdif_in(codec);
-       return 0;
-}
-#endif
-
 static struct hda_codec_ops ad198x_patch_ops = {
        .build_controls = ad198x_build_controls,
        .build_pcms = ad198x_build_pcms,
        .init = ad198x_init,
        .free = ad198x_free,
-#ifdef CONFIG_PM
-       .resume = ad198x_resume,
-#endif
 };
 
 
        eapd = ucontrol->value.integer.value[0];
        if (invert)
                eapd = !eapd;
-       if (eapd == spec->cur_eapd && ! codec->in_resume)
+       if (eapd == spec->cur_eapd)
                return 0;
        spec->cur_eapd = eapd;
-       snd_hda_codec_write(codec, nid,
-                           0, AC_VERB_SET_EAPD_BTLENABLE,
-                           eapd ? 0x02 : 0x00);
+       snd_hda_codec_write_cache(codec, nid,
+                                 0, AC_VERB_SET_EAPD_BTLENABLE,
+                                 eapd ? 0x02 : 0x00);
        return 1;
 }
 
 
        if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
                spec->spdif_route = ucontrol->value.enumerated.item[0];
-               snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
-                                   AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
+               snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
+                                         AC_VERB_SET_CONNECT_SEL,
+                                         spec->spdif_route);
                return 1;
        }
        return 0;
                                         AC_VERB_GET_AMP_GAIN_MUTE,
                                         AC_AMP_GET_INPUT);
                change = sel & 0x80;
-               if (change || codec->in_resume) {
-                       snd_hda_codec_write(codec, 0x1d, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_IN_UNMUTE(0));
-                       snd_hda_codec_write(codec, 0x1d, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_IN_MUTE(1));
+               if (change) {
+                       snd_hda_codec_write_cache(codec, 0x1d, 0,
+                                                 AC_VERB_SET_AMP_GAIN_MUTE,
+                                                 AMP_IN_UNMUTE(0));
+                       snd_hda_codec_write_cache(codec, 0x1d, 0,
+                                                 AC_VERB_SET_AMP_GAIN_MUTE,
+                                                 AMP_IN_MUTE(1));
                }
        } else {
                sel = snd_hda_codec_read(codec, 0x1d, 0,
                                         AC_VERB_GET_AMP_GAIN_MUTE,
                                         AC_AMP_GET_INPUT | 0x01);
                change = sel & 0x80;
-               if (change || codec->in_resume) {
-                       snd_hda_codec_write(codec, 0x1d, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_IN_MUTE(0));
-                       snd_hda_codec_write(codec, 0x1d, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_IN_UNMUTE(1));
+               if (change) {
+                       snd_hda_codec_write_cache(codec, 0x1d, 0,
+                                                 AC_VERB_SET_AMP_GAIN_MUTE,
+                                                 AMP_IN_MUTE(0));
+                       snd_hda_codec_write_cache(codec, 0x1d, 0,
+                                                 AC_VERB_SET_AMP_GAIN_MUTE,
+                                                 AMP_IN_UNMUTE(1));
                }
                sel = snd_hda_codec_read(codec, 0x0b, 0,
                                         AC_VERB_GET_CONNECT_SEL, 0) + 1;
                change |= sel != val;
-               if (change || codec->in_resume)
-                       snd_hda_codec_write(codec, 0x0b, 0,
-                                           AC_VERB_SET_CONNECT_SEL, val - 1);
+               if (change)
+                       snd_hda_codec_write_cache(codec, 0x0b, 0,
+                                                 AC_VERB_SET_CONNECT_SEL,
+                                                 val - 1);
        }
        return change;
 }
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int atihdmi_resume(struct hda_codec *codec)
-{
-       atihdmi_init(codec);
-       snd_hda_resume_spdif_out(codec);
-
-       return 0;
-}
-#endif
-
 /*
  * Digital out
  */
        .build_pcms = atihdmi_build_pcms,
        .init = atihdmi_init,
        .free = atihdmi_free,
-#ifdef CONFIG_PM
-       .resume = atihdmi_resume,
-#endif
 };
 
 static int patch_atihdmi(struct hda_codec *codec)
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int cmi9880_resume(struct hda_codec *codec)
-{
-       struct cmi_spec *spec = codec->spec;
-
-       cmi9880_init(codec);
-       snd_hda_resume_ctls(codec, cmi9880_basic_mixer);
-       if (spec->channel_modes)
-               snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer);
-       if (spec->multiout.dig_out_nid)
-               snd_hda_resume_spdif_out(codec);
-       if (spec->dig_in_nid)
-               snd_hda_resume_spdif_in(codec);
-
-       return 0;
-}
-#endif
-
 /*
  * Analog playback callbacks
  */
        .build_pcms = cmi9880_build_pcms,
        .init = cmi9880_init,
        .free = cmi9880_free,
-#ifdef CONFIG_PM
-       .resume = cmi9880_resume,
-#endif
 };
 
 static int patch_cmi9880(struct hda_codec *codec)
 
        kfree(codec->spec);
 }
 
-#ifdef CONFIG_PM
-static int conexant_resume(struct hda_codec *codec)
-{
-       struct conexant_spec *spec = codec->spec;
-       int i;
-
-       codec->patch_ops.init(codec);
-       for (i = 0; i < spec->num_mixers; i++)
-               snd_hda_resume_ctls(codec, spec->mixers[i]);
-       if (spec->multiout.dig_out_nid)
-               snd_hda_resume_spdif_out(codec);
-       if (spec->dig_in_nid)
-               snd_hda_resume_spdif_in(codec);
-       return 0;
-}
-#endif
-
 static int conexant_build_controls(struct hda_codec *codec)
 {
        struct conexant_spec *spec = codec->spec;
        .build_pcms = conexant_build_pcms,
        .init = conexant_init,
        .free = conexant_free,
-#ifdef CONFIG_PM
-       .resume = conexant_resume,
-#endif
 };
 
 /*
        eapd = ucontrol->value.integer.value[0];
        if (invert)
                eapd = !eapd;
-       if (eapd == spec->cur_eapd && !codec->in_resume)
+       if (eapd == spec->cur_eapd)
                return 0;
        
        spec->cur_eapd = eapd;
-       snd_hda_codec_write(codec, nid,
-                           0, AC_VERB_SET_EAPD_BTLENABLE,
-                           eapd ? 0x02 : 0x00);
+       snd_hda_codec_write_cache(codec, nid,
+                                 0, AC_VERB_SET_EAPD_BTLENABLE,
+                                 eapd ? 0x02 : 0x00);
        return 1;
 }
 
 
        change = pinctl != alc_pin_mode_values[val];
        if (change) {
                /* Set pin mode to that requested */
-               snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                   alc_pin_mode_values[val]);
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                         alc_pin_mode_values[val]);
 
                /* Also enable the retasking pin's input/output as required 
                 * for the requested pin mode.  Enum values of 2 or less are
                 * this turns out to be necessary in the future.
                 */
                if (val <= 2) {
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_OUT_MUTE);
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_IN_UNMUTE(0));
+                       snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
+                                                0x80, 0x80);
+                       snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
+                                                0x80, 0x80);
+                       snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0,
+                                                0x80, 0x00);
+                       snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0,
+                                                0x80, 0x00);
                } else {
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_IN_MUTE(0));
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_AMP_GAIN_MUTE,
-                                           AMP_OUT_UNMUTE);
+                       snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0,
+                                                0x80, 0x80);
+                       snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0,
+                                                0x80, 0x80);
+                       snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
+                                                0x80, 0x00);
+                       snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
+                                                0x80, 0x00);
                }
        }
        return change;
                gpio_data &= ~mask;
        else
                gpio_data |= mask;
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
+       snd_hda_codec_write_cache(codec, nid, 0,
+                                 AC_VERB_SET_GPIO_DATA, gpio_data);
 
        return change;
 }
                ctrl_data &= ~mask;
        else
                ctrl_data |= mask;
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-                           ctrl_data);
+       snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+                                 ctrl_data);
 
        return change;
 }
                spec->unsol_event(codec, res);
 }
 
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int alc_resume(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       int i;
-
-       alc_init(codec);
-       for (i = 0; i < spec->num_mixers; i++)
-               snd_hda_resume_ctls(codec, spec->mixers[i]);
-       if (spec->multiout.dig_out_nid)
-               snd_hda_resume_spdif_out(codec);
-       if (spec->dig_in_nid)
-               snd_hda_resume_spdif_in(codec);
-
-       return 0;
-}
-#endif
-
 /*
  * Analog playback callbacks
  */
        .init = alc_init,
        .free = alc_free,
        .unsol_event = alc_unsol_event,
-#ifdef CONFIG_PM
-       .resume = alc_resume,
-#endif
 };
 
 
                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
        new_ctl = ctls[ucontrol->value.enumerated.item[0]];
        if (old_ctl != new_ctl) {
-               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   (ucontrol->value.enumerated.item[0] >= 3 ?
-                                    0xb080 : 0xb000));
+               int val;
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                         new_ctl);
+               val = ucontrol->value.enumerated.item[0] >= 3 ? 0x80 : 0x00;
+               snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
+                                        0x80, val);
+               snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
+                                        0x80, val);
                return 1;
        }
        return 0;
        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
        if (ucontrol->value.enumerated.item[0] != sel) {
                sel = ucontrol->value.enumerated.item[0] & 3;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
+               snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_CONNECT_SEL, sel);
                return 1;
        }
        return 0;
         present = snd_hda_codec_read(codec, 0x0f, 0,
                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
        if (present) {
-               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
-               snd_hda_codec_write(codec, 0x0f, 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+               snd_hda_codec_write_cache(codec, 0x01, 0,
+                                         AC_VERB_SET_GPIO_DATA, 1);
+               snd_hda_codec_write_cache(codec, 0x0f, 0,
+                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                         PIN_HP);
        } else {
-               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
-               snd_hda_codec_write(codec, 0x0f, 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+               snd_hda_codec_write_cache(codec, 0x01, 0,
+                                         AC_VERB_SET_GPIO_DATA, 0);
+               snd_hda_codec_write_cache(codec, 0x0f, 0,
+                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                         PIN_OUT);
        }
 }
 
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && !codec->in_resume)
+       if (*cur_val == idx)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
-               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   v | (imux->items[i].index << 8));
+               unsigned int v = (i == idx) ? 0x00 : 0x80;
+               snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
+                                        imux->items[i].index,
+                                        0x80, v);
+               snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
+                                        imux->items[i].index,
+                                        0x80, v);
        }
        *cur_val = idx;
        return 1;
                                 0x80, present ? 0x80 : 0);
        snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
                                 0x80, present ? 0x80 : 0);
-       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+       snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+                                 present ? 1 : 3);
 }
 
 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && !codec->in_resume)
+       if (*cur_val == idx)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
-               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   v | (imux->items[i].index << 8));
+               unsigned int v = (i == idx) ? 0x00 : 0x80;
+               snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
+                                        imux->items[i].index,
+                                        0x80, v);
+               snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
+                                        imux->items[i].index,
+                                        0x80, v);
        }
        *cur_val = idx;
        return 1;
                                 0x80, bits);
        snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
                                 0x80, bits);
-       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
-                           present ? 1 : 3);
+       snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+                                 present ? 1 : 3);
 }
 
 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
                                          0x80, valp[0] ? 0 : 0x80);
        change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
                                           0x80, valp[1] ? 0 : 0x80);
-       if (change || codec->in_resume)
-               alc262_fujitsu_automute(codec, codec->in_resume);
+       if (change)
+               alc262_fujitsu_automute(codec, 0);
        return change;
 }
 
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && !codec->in_resume)
+       if (*cur_val == idx)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
-               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   v | (imux->items[i].index << 8));
-                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
-                                   idx );
+               unsigned int v = (i == idx) ? 0x00 : 0x80;
+               snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
+                                        imux->items[i].index, 0x80, v);
+               snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
+                                        imux->items[i].index, 0x80, v);
+                snd_hda_codec_write_cache(codec, nid, 0,
+                                         AC_VERB_SET_CONNECT_SEL,
+                                         idx );
        }
        *cur_val = idx;
        return 1;
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && !codec->in_resume)
+       if (*cur_val == idx)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
-               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   v | (imux->items[i].index << 8));
+               unsigned int v = (i == idx) ? 0x00 : 0x80;
+               snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
+                                        imux->items[i].index, 0x80, v);
+               snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
+                                        imux->items[i].index, 0x80, v);
        }
        *cur_val = idx;
        return 1;
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && !codec->in_resume)
+       if (*cur_val == idx)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
-               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   v | (imux->items[i].index << 8));
+               unsigned int v = (i == idx) ? 0x00 : 0x80;
+               snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
+                                        imux->items[i].index, 0x80, v);
+               snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
+                                        imux->items[i].index, 0x80, v);
        }
        *cur_val = idx;
        return 1;
 
 /* si3054 codec registers (nodes) access macros */
 #define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0))
 #define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val))
+#define SET_REG_CACHE(codec,reg,val) \
+       snd_hda_codec_write_cache(codec,reg,0,SI3054_VERB_WRITE_NODE,val)
 
 
 struct si3054_spec {
        u16 reg  = PRIVATE_REG(kcontrol->private_value);
        u16 mask = PRIVATE_MASK(kcontrol->private_value);
        if (uvalue->value.integer.value[0])
-               SET_REG(codec, reg, (GET_REG(codec, reg)) | mask);
+               SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) | mask);
        else
-               SET_REG(codec, reg, (GET_REG(codec, reg)) & ~mask);
+               SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) & ~mask);
        return 0;
 }
 
        .build_pcms = si3054_build_pcms,
        .init = si3054_init,
        .free = si3054_free,
-#ifdef CONFIG_PM
-       //.suspend = si3054_suspend,
-       .resume = si3054_init,
-#endif
 };
 
 static int patch_si3054(struct hda_codec *codec)
 
 {
        struct sigmatel_spec *spec = codec->spec;
        /* Configure GPIOx as output */
-       snd_hda_codec_write(codec, codec->afg, 0,
-                           AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
+       snd_hda_codec_write_cache(codec, codec->afg, 0,
+                                 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
        /* Configure GPIOx as CMOS */
-       snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
+       snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
        /* Assert GPIOx */
-       snd_hda_codec_write(codec, codec->afg, 0,
-                           AC_VERB_SET_GPIO_DATA, spec->gpio_data);
+       snd_hda_codec_write_cache(codec, codec->afg, 0,
+                                 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
        /* Enable GPIOx */
-       snd_hda_codec_write(codec, codec->afg, 0,
-                           AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
+       snd_hda_codec_write_cache(codec, codec->afg, 0,
+                                 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
 }
 
 /*
 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
 
 {
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+       snd_hda_codec_write_cache(codec, nid, 0,
+                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
 }
 
 #define stac92xx_io_switch_info                snd_ctl_boolean_mono_info
                spec->multiout.num_dacs++;
                if (conn_len > 1) {
                        /* select this DAC in the pin's input mux */
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_CONNECT_SEL, j);
+                       snd_hda_codec_write_cache(codec, nid, 0,
+                                                 AC_VERB_SET_CONNECT_SEL, j);
 
                }
        }
                 * NID lists.  Hopefully this won't get confused.
                 */
                for (i = 0; i < spec->num_muxes; i++) {
-                       snd_hda_codec_write(codec, spec->mux_nids[i], 0,
-                                           AC_VERB_SET_CONNECT_SEL,
-                                           imux->items[0].index);
+                       snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
+                                                 AC_VERB_SET_CONNECT_SEL,
+                                                 imux->items[0].index);
                }
        }
 
        if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
                pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
        
-       snd_hda_codec_write(codec, nid, 0,
+       snd_hda_codec_write_cache(codec, nid, 0,
                        AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pin_ctl | flag);
 }
 {
        unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
                        0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
-       snd_hda_codec_write(codec, nid, 0,
+       snd_hda_codec_write_cache(codec, nid, 0,
                        AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pin_ctl & ~flag);
 }
 #ifdef CONFIG_PM
 static int stac92xx_resume(struct hda_codec *codec)
 {
-       struct sigmatel_spec *spec = codec->spec;
-       int i;
-
        stac92xx_set_config_regs(codec);
-       if (spec->gpio_mask && spec->gpio_data)
-               stac92xx_enable_gpio_mask(codec);
        stac92xx_init(codec);
-       snd_hda_resume_ctls(codec, spec->mixer);
-       for (i = 0; i < spec->num_mixers; i++)
-               snd_hda_resume_ctls(codec, spec->mixers[i]);
-       if (spec->multiout.dig_out_nid)
-               snd_hda_resume_spdif_out(codec);
-       if (spec->dig_in_nid)
-               snd_hda_resume_spdif_in(codec);
-
+       snd_hda_codec_resume_amp(codec);
+       snd_hda_codec_resume_cache(codec);
        return 0;
 }
 #endif
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int via_resume(struct hda_codec *codec)
-{
-       struct via_spec *spec = codec->spec;
-       int i;
-
-       via_init(codec);
-       for (i = 0; i < spec->num_mixers; i++)
-               snd_hda_resume_ctls(codec, spec->mixers[i]);
-       if (spec->multiout.dig_out_nid)
-               snd_hda_resume_spdif_out(codec);
-       if (spec->dig_in_nid)
-               snd_hda_resume_spdif_in(codec);
-
-       return 0;
-}
-#endif
-
 /*
  */
 static struct hda_codec_ops via_patch_ops = {
        .build_pcms = via_build_pcms,
        .init = via_init,
        .free = via_free,
-#ifdef CONFIG_PM
-       .resume = via_resume,
-#endif
 };
 
 /* fill in the dac_nids table from the parsed pin configuration */