aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-08-10 11:09:26 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:58:43 -0400
commit82beb8fd365afe3891b277c46425083f13e23c56 (patch)
treea564d7228b59170aa490d4fc9284b5fa4442adb0 /sound/pci/hda
parentb3ac56364126f78cae94eb2a75b72d9ea85aca9d (diff)
[ALSA] hda-codec - optimize resume using caches
So far, the driver looked the table of snd_kcontrol_new used for creating mixer elements and forces to call each of its put callbacks in PM resume code. This is too ugly and hackish. Now, the resume is simplified using the codec amp and command register caches. The driver simply restores the values that have been written in the cache table. With this simplification, most codec support codes don't require any special resume callback. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_codec.c115
-rw-r--r--sound/pci/hda/hda_codec.h10
-rw-r--r--sound/pci/hda/hda_generic.c24
-rw-r--r--sound/pci/hda/hda_local.h11
-rw-r--r--sound/pci/hda/patch_analog.c68
-rw-r--r--sound/pci/hda/patch_atihdmi.c16
-rw-r--r--sound/pci/hda/patch_cmedia.c24
-rw-r--r--sound/pci/hda/patch_conexant.c28
-rw-r--r--sound/pci/hda/patch_realtek.c167
-rw-r--r--sound/pci/hda/patch_si3054.c10
-rw-r--r--sound/pci/hda/patch_sigmatel.c46
-rw-r--r--sound/pci/hda/patch_via.c24
12 files changed, 195 insertions, 348 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 6652a531980d..1d31da47bc9b 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -836,12 +836,13 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
836 return 0; 836 return 0;
837 val &= mask; 837 val &= mask;
838 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; 838 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
839 if (info->vol[ch] == val && !codec->in_resume) 839 if (info->vol[ch] == val)
840 return 0; 840 return 0;
841 put_vol_mute(codec, info, nid, ch, direction, idx, val); 841 put_vol_mute(codec, info, nid, ch, direction, idx, val);
842 return 1; 842 return 1;
843} 843}
844 844
845#ifdef CONFIG_PM
845/* resume the all amp commands from the cache */ 846/* resume the all amp commands from the cache */
846void snd_hda_codec_resume_amp(struct hda_codec *codec) 847void snd_hda_codec_resume_amp(struct hda_codec *codec)
847{ 848{
@@ -865,6 +866,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
865 } 866 }
866 } 867 }
867} 868}
869#endif /* CONFIG_PM */
868 870
869/* 871/*
870 * AMP control callbacks 872 * AMP control callbacks
@@ -1272,11 +1274,13 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
1272 change = codec->spdif_ctls != val; 1274 change = codec->spdif_ctls != val;
1273 codec->spdif_ctls = val; 1275 codec->spdif_ctls = val;
1274 1276
1275 if (change || codec->in_resume) { 1277 if (change) {
1276 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 1278 snd_hda_codec_write_cache(codec, nid, 0,
1277 val & 0xff); 1279 AC_VERB_SET_DIGI_CONVERT_1,
1278 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, 1280 val & 0xff);
1279 val >> 8); 1281 snd_hda_codec_write_cache(codec, nid, 0,
1282 AC_VERB_SET_DIGI_CONVERT_2,
1283 val >> 8);
1280 } 1284 }
1281 1285
1282 mutex_unlock(&codec->spdif_mutex); 1286 mutex_unlock(&codec->spdif_mutex);
@@ -1307,17 +1311,19 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
1307 if (ucontrol->value.integer.value[0]) 1311 if (ucontrol->value.integer.value[0])
1308 val |= AC_DIG1_ENABLE; 1312 val |= AC_DIG1_ENABLE;
1309 change = codec->spdif_ctls != val; 1313 change = codec->spdif_ctls != val;
1310 if (change || codec->in_resume) { 1314 if (change) {
1311 codec->spdif_ctls = val; 1315 codec->spdif_ctls = val;
1312 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 1316 snd_hda_codec_write_cache(codec, nid, 0,
1313 val & 0xff); 1317 AC_VERB_SET_DIGI_CONVERT_1,
1318 val & 0xff);
1314 /* unmute amp switch (if any) */ 1319 /* unmute amp switch (if any) */
1315 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && 1320 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
1316 (val & AC_DIG1_ENABLE)) 1321 (val & AC_DIG1_ENABLE)) {
1317 snd_hda_codec_write(codec, nid, 0, 1322 snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
1318 AC_VERB_SET_AMP_GAIN_MUTE, 1323 0x80, 0x00);
1319 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | 1324 snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
1320 AC_AMP_SET_OUTPUT); 1325 0x80, 0x00);
1326 }
1321 } 1327 }
1322 mutex_unlock(&codec->spdif_mutex); 1328 mutex_unlock(&codec->spdif_mutex);
1323 return change; 1329 return change;
@@ -1409,10 +1415,10 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
1409 1415
1410 mutex_lock(&codec->spdif_mutex); 1416 mutex_lock(&codec->spdif_mutex);
1411 change = codec->spdif_in_enable != val; 1417 change = codec->spdif_in_enable != val;
1412 if (change || codec->in_resume) { 1418 if (change) {
1413 codec->spdif_in_enable = val; 1419 codec->spdif_in_enable = val;
1414 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 1420 snd_hda_codec_write_cache(codec, nid, 0,
1415 val); 1421 AC_VERB_SET_DIGI_CONVERT_1, val);
1416 } 1422 }
1417 mutex_unlock(&codec->spdif_mutex); 1423 mutex_unlock(&codec->spdif_mutex);
1418 return change; 1424 return change;
@@ -1482,6 +1488,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1482 return 0; 1488 return 0;
1483} 1489}
1484 1490
1491#ifdef CONFIG_PM
1492/*
1493 * command cache
1494 */
1485 1495
1486/* build a 32bit cache key with the widget id and the command parameter */ 1496/* build a 32bit cache key with the widget id and the command parameter */
1487#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid) 1497#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
@@ -1548,6 +1558,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
1548 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, 1558 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
1549 seq->param); 1559 seq->param);
1550} 1560}
1561#endif /* CONFIG_PM */
1551 1562
1552/* 1563/*
1553 * set power state of the codec 1564 * set power state of the codec
@@ -2122,12 +2133,12 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
2122 2133
2123 mode = ucontrol->value.enumerated.item[0]; 2134 mode = ucontrol->value.enumerated.item[0];
2124 snd_assert(mode < num_chmodes, return -EINVAL); 2135 snd_assert(mode < num_chmodes, return -EINVAL);
2125 if (*max_channelsp == chmode[mode].channels && !codec->in_resume) 2136 if (*max_channelsp == chmode[mode].channels)
2126 return 0; 2137 return 0;
2127 /* change the current channel setting */ 2138 /* change the current channel setting */
2128 *max_channelsp = chmode[mode].channels; 2139 *max_channelsp = chmode[mode].channels;
2129 if (chmode[mode].sequence) 2140 if (chmode[mode].sequence)
2130 snd_hda_sequence_write(codec, chmode[mode].sequence); 2141 snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
2131 return 1; 2142 return 1;
2132} 2143}
2133 2144
@@ -2160,10 +2171,10 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
2160 idx = ucontrol->value.enumerated.item[0]; 2171 idx = ucontrol->value.enumerated.item[0];
2161 if (idx >= imux->num_items) 2172 if (idx >= imux->num_items)
2162 idx = imux->num_items - 1; 2173 idx = imux->num_items - 1;
2163 if (*cur_val == idx && !codec->in_resume) 2174 if (*cur_val == idx)
2164 return 0; 2175 return 0;
2165 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, 2176 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
2166 imux->items[idx].index); 2177 imux->items[idx].index);
2167 *cur_val = idx; 2178 *cur_val = idx;
2168 return 1; 2179 return 1;
2169} 2180}
@@ -2608,65 +2619,13 @@ int snd_hda_resume(struct hda_bus *bus)
2608 AC_PWRST_D0); 2619 AC_PWRST_D0);
2609 if (codec->patch_ops.resume) 2620 if (codec->patch_ops.resume)
2610 codec->patch_ops.resume(codec); 2621 codec->patch_ops.resume(codec);
2611 } 2622 else {
2612 return 0; 2623 codec->patch_ops.init(codec);
2613} 2624 snd_hda_codec_resume_amp(codec);
2614 2625 snd_hda_codec_resume_cache(codec);
2615/**
2616 * snd_hda_resume_ctls - resume controls in the new control list
2617 * @codec: the HDA codec
2618 * @knew: the array of struct snd_kcontrol_new
2619 *
2620 * This function resumes the mixer controls in the struct snd_kcontrol_new array,
2621 * originally for snd_hda_add_new_ctls().
2622 * The array must be terminated with an empty entry as terminator.
2623 */
2624int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2625{
2626 struct snd_ctl_elem_value *val;
2627
2628 val = kmalloc(sizeof(*val), GFP_KERNEL);
2629 if (!val)
2630 return -ENOMEM;
2631 codec->in_resume = 1;
2632 for (; knew->name; knew++) {
2633 int i, count;
2634 count = knew->count ? knew->count : 1;
2635 for (i = 0; i < count; i++) {
2636 memset(val, 0, sizeof(*val));
2637 val->id.iface = knew->iface;
2638 val->id.device = knew->device;
2639 val->id.subdevice = knew->subdevice;
2640 strcpy(val->id.name, knew->name);
2641 val->id.index = knew->index ? knew->index : i;
2642 /* Assume that get callback reads only from cache,
2643 * not accessing to the real hardware
2644 */
2645 if (snd_ctl_elem_read(codec->bus->card, val) < 0)
2646 continue;
2647 snd_ctl_elem_write(codec->bus->card, NULL, val);
2648 } 2626 }
2649 } 2627 }
2650 codec->in_resume = 0;
2651 kfree(val);
2652 return 0; 2628 return 0;
2653} 2629}
2654 2630
2655/**
2656 * snd_hda_resume_spdif_out - resume the digital out
2657 * @codec: the HDA codec
2658 */
2659int snd_hda_resume_spdif_out(struct hda_codec *codec)
2660{
2661 return snd_hda_resume_ctls(codec, dig_mixes);
2662}
2663
2664/**
2665 * snd_hda_resume_spdif_in - resume the digital in
2666 * @codec: the HDA codec
2667 */
2668int snd_hda_resume_spdif_in(struct hda_codec *codec)
2669{
2670 return snd_hda_resume_ctls(codec, dig_in_ctls);
2671}
2672#endif 2631#endif
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index ef94c9122c6d..92938d2a52e2 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -552,11 +552,6 @@ struct hda_codec {
552 /* set by patch */ 552 /* set by patch */
553 struct hda_codec_ops patch_ops; 553 struct hda_codec_ops patch_ops;
554 554
555 /* resume phase - all controls should update even if
556 * the values are not changed
557 */
558 unsigned int in_resume;
559
560 /* PCM to create, set by patch_ops.build_pcms callback */ 555 /* PCM to create, set by patch_ops.build_pcms callback */
561 unsigned int num_pcms; 556 unsigned int num_pcms;
562 struct hda_pcm *pcm_info; 557 struct hda_pcm *pcm_info;
@@ -622,11 +617,16 @@ void snd_hda_sequence_write(struct hda_codec *codec,
622int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); 617int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
623 618
624/* cached write */ 619/* cached write */
620#ifdef CONFIG_PM
625int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 621int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
626 int direct, unsigned int verb, unsigned int parm); 622 int direct, unsigned int verb, unsigned int parm);
627void snd_hda_sequence_write_cache(struct hda_codec *codec, 623void snd_hda_sequence_write_cache(struct hda_codec *codec,
628 const struct hda_verb *seq); 624 const struct hda_verb *seq);
629void snd_hda_codec_resume_cache(struct hda_codec *codec); 625void snd_hda_codec_resume_cache(struct hda_codec *codec);
626#else
627#define snd_hda_codec_write_cache snd_hda_codec_write
628#define snd_hda_sequence_write_cache snd_hda_sequence_write
629#endif
630 630
631/* 631/*
632 * Mixer 632 * Mixer
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 000287f7da43..d5f1180115ce 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -218,9 +218,9 @@ static int unmute_output(struct hda_codec *codec, struct hda_gnode *node)
218 ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; 218 ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
219 if (val >= ofs) 219 if (val >= ofs)
220 val -= ofs; 220 val -= ofs;
221 val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT; 221 snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 0, 0xff, val);
222 val |= AC_AMP_SET_OUTPUT; 222 snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 1, 0xff, val);
223 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); 223 return 0;
224} 224}
225 225
226/* 226/*
@@ -234,11 +234,11 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne
234 ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; 234 ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
235 if (val >= ofs) 235 if (val >= ofs)
236 val -= ofs; 236 val -= ofs;
237 val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT; 237 snd_hda_codec_amp_update(codec, node->nid, 0, HDA_INPUT, index,
238 val |= AC_AMP_SET_INPUT; 238 0xff, val);
239 // awk added - fixed to allow unmuting of indexed amps 239 snd_hda_codec_amp_update(codec, node->nid, 1, HDA_INPUT, index,
240 val |= index << AC_AMP_SET_INDEX_SHIFT; 240 0xff, val);
241 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); 241 return 0;
242} 242}
243 243
244/* 244/*
@@ -248,7 +248,8 @@ static int select_input_connection(struct hda_codec *codec, struct hda_gnode *no
248 unsigned int index) 248 unsigned int index)
249{ 249{
250 snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index); 250 snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index);
251 return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_CONNECT_SEL, index); 251 return snd_hda_codec_write_cache(codec, node->nid, 0,
252 AC_VERB_SET_CONNECT_SEL, index);
252} 253}
253 254
254/* 255/*
@@ -379,7 +380,7 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
379 /* unmute the PIN output */ 380 /* unmute the PIN output */
380 unmute_output(codec, node); 381 unmute_output(codec, node);
381 /* set PIN-Out enable */ 382 /* set PIN-Out enable */
382 snd_hda_codec_write(codec, node->nid, 0, 383 snd_hda_codec_write_cache(codec, node->nid, 0,
383 AC_VERB_SET_PIN_WIDGET_CONTROL, 384 AC_VERB_SET_PIN_WIDGET_CONTROL,
384 AC_PINCTL_OUT_EN | 385 AC_PINCTL_OUT_EN |
385 ((node->pin_caps & AC_PINCAP_HP_DRV) ? 386 ((node->pin_caps & AC_PINCAP_HP_DRV) ?
@@ -570,7 +571,8 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
570 /* unmute the PIN external input */ 571 /* unmute the PIN external input */
571 unmute_input(codec, node, 0); /* index = 0? */ 572 unmute_input(codec, node, 0); /* index = 0? */
572 /* set PIN-In enable */ 573 /* set PIN-In enable */
573 snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); 574 snd_hda_codec_write_cache(codec, node->nid, 0,
575 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
574 576
575 return 1; /* found */ 577 return 1; /* found */
576} 578}
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 51208974c2da..8dec32cfdf54 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -84,7 +84,9 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
84 int direction, int index); 84 int direction, int index);
85int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, 85int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
86 int direction, int idx, int mask, int val); 86 int direction, int idx, int mask, int val);
87#ifdef CONFIG_PM
87void snd_hda_codec_resume_amp(struct hda_codec *codec); 88void snd_hda_codec_resume_amp(struct hda_codec *codec);
89#endif
88 90
89/* mono switch binding multiple inputs */ 91/* mono switch binding multiple inputs */
90#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ 92#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
@@ -257,15 +259,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
257 struct snd_kcontrol_new *knew); 259 struct snd_kcontrol_new *knew);
258 260
259/* 261/*
260 * power management
261 */
262#ifdef CONFIG_PM
263int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
264int snd_hda_resume_spdif_out(struct hda_codec *codec);
265int snd_hda_resume_spdif_in(struct hda_codec *codec);
266#endif
267
268/*
269 * unsolicited event handler 262 * unsolicited event handler
270 */ 263 */
271 264
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index cc2e944cc59f..f20ddd85db22 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -318,31 +318,11 @@ static void ad198x_free(struct hda_codec *codec)
318 kfree(codec->spec); 318 kfree(codec->spec);
319} 319}
320 320
321#ifdef CONFIG_PM
322static int ad198x_resume(struct hda_codec *codec)
323{
324 struct ad198x_spec *spec = codec->spec;
325 int i;
326
327 codec->patch_ops.init(codec);
328 for (i = 0; i < spec->num_mixers; i++)
329 snd_hda_resume_ctls(codec, spec->mixers[i]);
330 if (spec->multiout.dig_out_nid)
331 snd_hda_resume_spdif_out(codec);
332 if (spec->dig_in_nid)
333 snd_hda_resume_spdif_in(codec);
334 return 0;
335}
336#endif
337
338static struct hda_codec_ops ad198x_patch_ops = { 321static struct hda_codec_ops ad198x_patch_ops = {
339 .build_controls = ad198x_build_controls, 322 .build_controls = ad198x_build_controls,
340 .build_pcms = ad198x_build_pcms, 323 .build_pcms = ad198x_build_pcms,
341 .init = ad198x_init, 324 .init = ad198x_init,
342 .free = ad198x_free, 325 .free = ad198x_free,
343#ifdef CONFIG_PM
344 .resume = ad198x_resume,
345#endif
346}; 326};
347 327
348 328
@@ -376,12 +356,12 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
376 eapd = ucontrol->value.integer.value[0]; 356 eapd = ucontrol->value.integer.value[0];
377 if (invert) 357 if (invert)
378 eapd = !eapd; 358 eapd = !eapd;
379 if (eapd == spec->cur_eapd && ! codec->in_resume) 359 if (eapd == spec->cur_eapd)
380 return 0; 360 return 0;
381 spec->cur_eapd = eapd; 361 spec->cur_eapd = eapd;
382 snd_hda_codec_write(codec, nid, 362 snd_hda_codec_write_cache(codec, nid,
383 0, AC_VERB_SET_EAPD_BTLENABLE, 363 0, AC_VERB_SET_EAPD_BTLENABLE,
384 eapd ? 0x02 : 0x00); 364 eapd ? 0x02 : 0x00);
385 return 1; 365 return 1;
386} 366}
387 367
@@ -882,8 +862,9 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
882 862
883 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { 863 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
884 spec->spdif_route = ucontrol->value.enumerated.item[0]; 864 spec->spdif_route = ucontrol->value.enumerated.item[0];
885 snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0, 865 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
886 AC_VERB_SET_CONNECT_SEL, spec->spdif_route); 866 AC_VERB_SET_CONNECT_SEL,
867 spec->spdif_route);
887 return 1; 868 return 1;
888 } 869 }
889 return 0; 870 return 0;
@@ -1824,33 +1805,34 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
1824 AC_VERB_GET_AMP_GAIN_MUTE, 1805 AC_VERB_GET_AMP_GAIN_MUTE,
1825 AC_AMP_GET_INPUT); 1806 AC_AMP_GET_INPUT);
1826 change = sel & 0x80; 1807 change = sel & 0x80;
1827 if (change || codec->in_resume) { 1808 if (change) {
1828 snd_hda_codec_write(codec, 0x1d, 0, 1809 snd_hda_codec_write_cache(codec, 0x1d, 0,
1829 AC_VERB_SET_AMP_GAIN_MUTE, 1810 AC_VERB_SET_AMP_GAIN_MUTE,
1830 AMP_IN_UNMUTE(0)); 1811 AMP_IN_UNMUTE(0));
1831 snd_hda_codec_write(codec, 0x1d, 0, 1812 snd_hda_codec_write_cache(codec, 0x1d, 0,
1832 AC_VERB_SET_AMP_GAIN_MUTE, 1813 AC_VERB_SET_AMP_GAIN_MUTE,
1833 AMP_IN_MUTE(1)); 1814 AMP_IN_MUTE(1));
1834 } 1815 }
1835 } else { 1816 } else {
1836 sel = snd_hda_codec_read(codec, 0x1d, 0, 1817 sel = snd_hda_codec_read(codec, 0x1d, 0,
1837 AC_VERB_GET_AMP_GAIN_MUTE, 1818 AC_VERB_GET_AMP_GAIN_MUTE,
1838 AC_AMP_GET_INPUT | 0x01); 1819 AC_AMP_GET_INPUT | 0x01);
1839 change = sel & 0x80; 1820 change = sel & 0x80;
1840 if (change || codec->in_resume) { 1821 if (change) {
1841 snd_hda_codec_write(codec, 0x1d, 0, 1822 snd_hda_codec_write_cache(codec, 0x1d, 0,
1842 AC_VERB_SET_AMP_GAIN_MUTE, 1823 AC_VERB_SET_AMP_GAIN_MUTE,
1843 AMP_IN_MUTE(0)); 1824 AMP_IN_MUTE(0));
1844 snd_hda_codec_write(codec, 0x1d, 0, 1825 snd_hda_codec_write_cache(codec, 0x1d, 0,
1845 AC_VERB_SET_AMP_GAIN_MUTE, 1826 AC_VERB_SET_AMP_GAIN_MUTE,
1846 AMP_IN_UNMUTE(1)); 1827 AMP_IN_UNMUTE(1));
1847 } 1828 }
1848 sel = snd_hda_codec_read(codec, 0x0b, 0, 1829 sel = snd_hda_codec_read(codec, 0x0b, 0,
1849 AC_VERB_GET_CONNECT_SEL, 0) + 1; 1830 AC_VERB_GET_CONNECT_SEL, 0) + 1;
1850 change |= sel != val; 1831 change |= sel != val;
1851 if (change || codec->in_resume) 1832 if (change)
1852 snd_hda_codec_write(codec, 0x0b, 0, 1833 snd_hda_codec_write_cache(codec, 0x0b, 0,
1853 AC_VERB_SET_CONNECT_SEL, val - 1); 1834 AC_VERB_SET_CONNECT_SEL,
1835 val - 1);
1854 } 1836 }
1855 return change; 1837 return change;
1856} 1838}
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 72d3ab9751ac..fbb8969dc559 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -62,19 +62,6 @@ static int atihdmi_init(struct hda_codec *codec)
62 return 0; 62 return 0;
63} 63}
64 64
65#ifdef CONFIG_PM
66/*
67 * resume
68 */
69static int atihdmi_resume(struct hda_codec *codec)
70{
71 atihdmi_init(codec);
72 snd_hda_resume_spdif_out(codec);
73
74 return 0;
75}
76#endif
77
78/* 65/*
79 * Digital out 66 * Digital out
80 */ 67 */
@@ -141,9 +128,6 @@ static struct hda_codec_ops atihdmi_patch_ops = {
141 .build_pcms = atihdmi_build_pcms, 128 .build_pcms = atihdmi_build_pcms,
142 .init = atihdmi_init, 129 .init = atihdmi_init,
143 .free = atihdmi_free, 130 .free = atihdmi_free,
144#ifdef CONFIG_PM
145 .resume = atihdmi_resume,
146#endif
147}; 131};
148 132
149static int patch_atihdmi(struct hda_codec *codec) 133static int patch_atihdmi(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 3c722e667bc8..2468f3171222 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -427,27 +427,6 @@ static int cmi9880_init(struct hda_codec *codec)
427 return 0; 427 return 0;
428} 428}
429 429
430#ifdef CONFIG_PM
431/*
432 * resume
433 */
434static int cmi9880_resume(struct hda_codec *codec)
435{
436 struct cmi_spec *spec = codec->spec;
437
438 cmi9880_init(codec);
439 snd_hda_resume_ctls(codec, cmi9880_basic_mixer);
440 if (spec->channel_modes)
441 snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer);
442 if (spec->multiout.dig_out_nid)
443 snd_hda_resume_spdif_out(codec);
444 if (spec->dig_in_nid)
445 snd_hda_resume_spdif_in(codec);
446
447 return 0;
448}
449#endif
450
451/* 430/*
452 * Analog playback callbacks 431 * Analog playback callbacks
453 */ 432 */
@@ -635,9 +614,6 @@ static struct hda_codec_ops cmi9880_patch_ops = {
635 .build_pcms = cmi9880_build_pcms, 614 .build_pcms = cmi9880_build_pcms,
636 .init = cmi9880_init, 615 .init = cmi9880_init,
637 .free = cmi9880_free, 616 .free = cmi9880_free,
638#ifdef CONFIG_PM
639 .resume = cmi9880_resume,
640#endif
641}; 617};
642 618
643static int patch_cmi9880(struct hda_codec *codec) 619static int patch_cmi9880(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 26034315197f..f1b6d0eda140 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -311,23 +311,6 @@ static void conexant_free(struct hda_codec *codec)
311 kfree(codec->spec); 311 kfree(codec->spec);
312} 312}
313 313
314#ifdef CONFIG_PM
315static int conexant_resume(struct hda_codec *codec)
316{
317 struct conexant_spec *spec = codec->spec;
318 int i;
319
320 codec->patch_ops.init(codec);
321 for (i = 0; i < spec->num_mixers; i++)
322 snd_hda_resume_ctls(codec, spec->mixers[i]);
323 if (spec->multiout.dig_out_nid)
324 snd_hda_resume_spdif_out(codec);
325 if (spec->dig_in_nid)
326 snd_hda_resume_spdif_in(codec);
327 return 0;
328}
329#endif
330
331static int conexant_build_controls(struct hda_codec *codec) 314static int conexant_build_controls(struct hda_codec *codec)
332{ 315{
333 struct conexant_spec *spec = codec->spec; 316 struct conexant_spec *spec = codec->spec;
@@ -358,9 +341,6 @@ static struct hda_codec_ops conexant_patch_ops = {
358 .build_pcms = conexant_build_pcms, 341 .build_pcms = conexant_build_pcms,
359 .init = conexant_init, 342 .init = conexant_init,
360 .free = conexant_free, 343 .free = conexant_free,
361#ifdef CONFIG_PM
362 .resume = conexant_resume,
363#endif
364}; 344};
365 345
366/* 346/*
@@ -396,13 +376,13 @@ static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
396 eapd = ucontrol->value.integer.value[0]; 376 eapd = ucontrol->value.integer.value[0];
397 if (invert) 377 if (invert)
398 eapd = !eapd; 378 eapd = !eapd;
399 if (eapd == spec->cur_eapd && !codec->in_resume) 379 if (eapd == spec->cur_eapd)
400 return 0; 380 return 0;
401 381
402 spec->cur_eapd = eapd; 382 spec->cur_eapd = eapd;
403 snd_hda_codec_write(codec, nid, 383 snd_hda_codec_write_cache(codec, nid,
404 0, AC_VERB_SET_EAPD_BTLENABLE, 384 0, AC_VERB_SET_EAPD_BTLENABLE,
405 eapd ? 0x02 : 0x00); 385 eapd ? 0x02 : 0x00);
406 return 1; 386 return 1;
407} 387}
408 388
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 39c08bb670d1..63011133e3fb 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -442,8 +442,9 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
442 change = pinctl != alc_pin_mode_values[val]; 442 change = pinctl != alc_pin_mode_values[val];
443 if (change) { 443 if (change) {
444 /* Set pin mode to that requested */ 444 /* Set pin mode to that requested */
445 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, 445 snd_hda_codec_write_cache(codec, nid, 0,
446 alc_pin_mode_values[val]); 446 AC_VERB_SET_PIN_WIDGET_CONTROL,
447 alc_pin_mode_values[val]);
447 448
448 /* Also enable the retasking pin's input/output as required 449 /* Also enable the retasking pin's input/output as required
449 * for the requested pin mode. Enum values of 2 or less are 450 * for the requested pin mode. Enum values of 2 or less are
@@ -456,19 +457,23 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
456 * this turns out to be necessary in the future. 457 * this turns out to be necessary in the future.
457 */ 458 */
458 if (val <= 2) { 459 if (val <= 2) {
459 snd_hda_codec_write(codec, nid, 0, 460 snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
460 AC_VERB_SET_AMP_GAIN_MUTE, 461 0x80, 0x80);
461 AMP_OUT_MUTE); 462 snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
462 snd_hda_codec_write(codec, nid, 0, 463 0x80, 0x80);
463 AC_VERB_SET_AMP_GAIN_MUTE, 464 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0,
464 AMP_IN_UNMUTE(0)); 465 0x80, 0x00);
466 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0,
467 0x80, 0x00);
465 } else { 468 } else {
466 snd_hda_codec_write(codec, nid, 0, 469 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0,
467 AC_VERB_SET_AMP_GAIN_MUTE, 470 0x80, 0x80);
468 AMP_IN_MUTE(0)); 471 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0,
469 snd_hda_codec_write(codec, nid, 0, 472 0x80, 0x80);
470 AC_VERB_SET_AMP_GAIN_MUTE, 473 snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
471 AMP_OUT_UNMUTE); 474 0x80, 0x00);
475 snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
476 0x80, 0x00);
472 } 477 }
473 } 478 }
474 return change; 479 return change;
@@ -520,7 +525,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
520 gpio_data &= ~mask; 525 gpio_data &= ~mask;
521 else 526 else
522 gpio_data |= mask; 527 gpio_data |= mask;
523 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); 528 snd_hda_codec_write_cache(codec, nid, 0,
529 AC_VERB_SET_GPIO_DATA, gpio_data);
524 530
525 return change; 531 return change;
526} 532}
@@ -573,8 +579,8 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
573 ctrl_data &= ~mask; 579 ctrl_data &= ~mask;
574 else 580 else
575 ctrl_data |= mask; 581 ctrl_data |= mask;
576 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 582 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
577 ctrl_data); 583 ctrl_data);
578 584
579 return change; 585 return change;
580} 586}
@@ -2026,27 +2032,6 @@ static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2026 spec->unsol_event(codec, res); 2032 spec->unsol_event(codec, res);
2027} 2033}
2028 2034
2029#ifdef CONFIG_PM
2030/*
2031 * resume
2032 */
2033static int alc_resume(struct hda_codec *codec)
2034{
2035 struct alc_spec *spec = codec->spec;
2036 int i;
2037
2038 alc_init(codec);
2039 for (i = 0; i < spec->num_mixers; i++)
2040 snd_hda_resume_ctls(codec, spec->mixers[i]);
2041 if (spec->multiout.dig_out_nid)
2042 snd_hda_resume_spdif_out(codec);
2043 if (spec->dig_in_nid)
2044 snd_hda_resume_spdif_in(codec);
2045
2046 return 0;
2047}
2048#endif
2049
2050/* 2035/*
2051 * Analog playback callbacks 2036 * Analog playback callbacks
2052 */ 2037 */
@@ -2278,9 +2263,6 @@ static struct hda_codec_ops alc_patch_ops = {
2278 .init = alc_init, 2263 .init = alc_init,
2279 .free = alc_free, 2264 .free = alc_free,
2280 .unsol_event = alc_unsol_event, 2265 .unsol_event = alc_unsol_event,
2281#ifdef CONFIG_PM
2282 .resume = alc_resume,
2283#endif
2284}; 2266};
2285 2267
2286 2268
@@ -2377,11 +2359,15 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2377 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 2359 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2378 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 2360 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2379 if (old_ctl != new_ctl) { 2361 if (old_ctl != new_ctl) {
2380 snd_hda_codec_write(codec, nid, 0, 2362 int val;
2381 AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); 2363 snd_hda_codec_write_cache(codec, nid, 0,
2382 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2364 AC_VERB_SET_PIN_WIDGET_CONTROL,
2383 (ucontrol->value.enumerated.item[0] >= 3 ? 2365 new_ctl);
2384 0xb080 : 0xb000)); 2366 val = ucontrol->value.enumerated.item[0] >= 3 ? 0x80 : 0x00;
2367 snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
2368 0x80, val);
2369 snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
2370 0x80, val);
2385 return 1; 2371 return 1;
2386 } 2372 }
2387 return 0; 2373 return 0;
@@ -2424,7 +2410,8 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2424 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 2410 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2425 if (ucontrol->value.enumerated.item[0] != sel) { 2411 if (ucontrol->value.enumerated.item[0] != sel) {
2426 sel = ucontrol->value.enumerated.item[0] & 3; 2412 sel = ucontrol->value.enumerated.item[0] & 3;
2427 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel); 2413 snd_hda_codec_write_cache(codec, nid, 0,
2414 AC_VERB_SET_CONNECT_SEL, sel);
2428 return 1; 2415 return 1;
2429 } 2416 }
2430 return 0; 2417 return 0;
@@ -4054,13 +4041,17 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec)
4054 present = snd_hda_codec_read(codec, 0x0f, 0, 4041 present = snd_hda_codec_read(codec, 0x0f, 0,
4055 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 4042 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4056 if (present) { 4043 if (present) {
4057 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); 4044 snd_hda_codec_write_cache(codec, 0x01, 0,
4058 snd_hda_codec_write(codec, 0x0f, 0, 4045 AC_VERB_SET_GPIO_DATA, 1);
4059 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 4046 snd_hda_codec_write_cache(codec, 0x0f, 0,
4047 AC_VERB_SET_PIN_WIDGET_CONTROL,
4048 PIN_HP);
4060 } else { 4049 } else {
4061 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 4050 snd_hda_codec_write_cache(codec, 0x01, 0,
4062 snd_hda_codec_write(codec, 0x0f, 0, 4051 AC_VERB_SET_GPIO_DATA, 0);
4063 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 4052 snd_hda_codec_write_cache(codec, 0x0f, 0,
4053 AC_VERB_SET_PIN_WIDGET_CONTROL,
4054 PIN_OUT);
4064 } 4055 }
4065} 4056}
4066 4057
@@ -4797,12 +4788,16 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4797 idx = ucontrol->value.enumerated.item[0]; 4788 idx = ucontrol->value.enumerated.item[0];
4798 if (idx >= imux->num_items) 4789 if (idx >= imux->num_items)
4799 idx = imux->num_items - 1; 4790 idx = imux->num_items - 1;
4800 if (*cur_val == idx && !codec->in_resume) 4791 if (*cur_val == idx)
4801 return 0; 4792 return 0;
4802 for (i = 0; i < imux->num_items; i++) { 4793 for (i = 0; i < imux->num_items; i++) {
4803 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 4794 unsigned int v = (i == idx) ? 0x00 : 0x80;
4804 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4795 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
4805 v | (imux->items[i].index << 8)); 4796 imux->items[i].index,
4797 0x80, v);
4798 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
4799 imux->items[i].index,
4800 0x80, v);
4806 } 4801 }
4807 *cur_val = idx; 4802 *cur_val = idx;
4808 return 1; 4803 return 1;
@@ -5187,7 +5182,8 @@ static void alc882_targa_automute(struct hda_codec *codec)
5187 0x80, present ? 0x80 : 0); 5182 0x80, present ? 0x80 : 0);
5188 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 5183 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5189 0x80, present ? 0x80 : 0); 5184 0x80, present ? 0x80 : 0);
5190 snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); 5185 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5186 present ? 1 : 3);
5191} 5187}
5192 5188
5193static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 5189static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -5777,12 +5773,16 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5777 idx = ucontrol->value.enumerated.item[0]; 5773 idx = ucontrol->value.enumerated.item[0];
5778 if (idx >= imux->num_items) 5774 if (idx >= imux->num_items)
5779 idx = imux->num_items - 1; 5775 idx = imux->num_items - 1;
5780 if (*cur_val == idx && !codec->in_resume) 5776 if (*cur_val == idx)
5781 return 0; 5777 return 0;
5782 for (i = 0; i < imux->num_items; i++) { 5778 for (i = 0; i < imux->num_items; i++) {
5783 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 5779 unsigned int v = (i == idx) ? 0x00 : 0x80;
5784 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5780 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
5785 v | (imux->items[i].index << 8)); 5781 imux->items[i].index,
5782 0x80, v);
5783 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
5784 imux->items[i].index,
5785 0x80, v);
5786 } 5786 }
5787 *cur_val = idx; 5787 *cur_val = idx;
5788 return 1; 5788 return 1;
@@ -6509,8 +6509,8 @@ static void alc883_tagra_automute(struct hda_codec *codec)
6509 0x80, bits); 6509 0x80, bits);
6510 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 6510 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6511 0x80, bits); 6511 0x80, bits);
6512 snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6512 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6513 present ? 1 : 3); 6513 present ? 1 : 3);
6514} 6514}
6515 6515
6516static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 6516static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -7510,8 +7510,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7510 0x80, valp[0] ? 0 : 0x80); 7510 0x80, valp[0] ? 0 : 0x80);
7511 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 7511 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7512 0x80, valp[1] ? 0 : 0x80); 7512 0x80, valp[1] ? 0 : 0x80);
7513 if (change || codec->in_resume) 7513 if (change)
7514 alc262_fujitsu_automute(codec, codec->in_resume); 7514 alc262_fujitsu_automute(codec, 0);
7515 return change; 7515 return change;
7516} 7516}
7517 7517
@@ -8328,14 +8328,17 @@ static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8328 idx = ucontrol->value.enumerated.item[0]; 8328 idx = ucontrol->value.enumerated.item[0];
8329 if (idx >= imux->num_items) 8329 if (idx >= imux->num_items)
8330 idx = imux->num_items - 1; 8330 idx = imux->num_items - 1;
8331 if (*cur_val == idx && !codec->in_resume) 8331 if (*cur_val == idx)
8332 return 0; 8332 return 0;
8333 for (i = 0; i < imux->num_items; i++) { 8333 for (i = 0; i < imux->num_items; i++) {
8334 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 8334 unsigned int v = (i == idx) ? 0x00 : 0x80;
8335 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 8335 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
8336 v | (imux->items[i].index << 8)); 8336 imux->items[i].index, 0x80, v);
8337 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, 8337 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
8338 idx ); 8338 imux->items[i].index, 0x80, v);
8339 snd_hda_codec_write_cache(codec, nid, 0,
8340 AC_VERB_SET_CONNECT_SEL,
8341 idx );
8339 } 8342 }
8340 *cur_val = idx; 8343 *cur_val = idx;
8341 return 1; 8344 return 1;
@@ -9916,12 +9919,14 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9916 idx = ucontrol->value.enumerated.item[0]; 9919 idx = ucontrol->value.enumerated.item[0];
9917 if (idx >= imux->num_items) 9920 if (idx >= imux->num_items)
9918 idx = imux->num_items - 1; 9921 idx = imux->num_items - 1;
9919 if (*cur_val == idx && !codec->in_resume) 9922 if (*cur_val == idx)
9920 return 0; 9923 return 0;
9921 for (i = 0; i < imux->num_items; i++) { 9924 for (i = 0; i < imux->num_items; i++) {
9922 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 9925 unsigned int v = (i == idx) ? 0x00 : 0x80;
9923 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 9926 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
9924 v | (imux->items[i].index << 8)); 9927 imux->items[i].index, 0x80, v);
9928 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
9929 imux->items[i].index, 0x80, v);
9925 } 9930 }
9926 *cur_val = idx; 9931 *cur_val = idx;
9927 return 1; 9932 return 1;
@@ -10847,12 +10852,14 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10847 idx = ucontrol->value.enumerated.item[0]; 10852 idx = ucontrol->value.enumerated.item[0];
10848 if (idx >= imux->num_items) 10853 if (idx >= imux->num_items)
10849 idx = imux->num_items - 1; 10854 idx = imux->num_items - 1;
10850 if (*cur_val == idx && !codec->in_resume) 10855 if (*cur_val == idx)
10851 return 0; 10856 return 0;
10852 for (i = 0; i < imux->num_items; i++) { 10857 for (i = 0; i < imux->num_items; i++) {
10853 unsigned int v = (i == idx) ? 0x7000 : 0x7080; 10858 unsigned int v = (i == idx) ? 0x00 : 0x80;
10854 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 10859 snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT,
10855 v | (imux->items[i].index << 8)); 10860 imux->items[i].index, 0x80, v);
10861 snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT,
10862 imux->items[i].index, 0x80, v);
10856 } 10863 }
10857 *cur_val = idx; 10864 *cur_val = idx;
10858 return 1; 10865 return 1;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 9838eac9ab59..2a4b9609aa5c 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -78,6 +78,8 @@
78/* si3054 codec registers (nodes) access macros */ 78/* si3054 codec registers (nodes) access macros */
79#define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0)) 79#define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0))
80#define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val)) 80#define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val))
81#define SET_REG_CACHE(codec,reg,val) \
82 snd_hda_codec_write_cache(codec,reg,0,SI3054_VERB_WRITE_NODE,val)
81 83
82 84
83struct si3054_spec { 85struct si3054_spec {
@@ -113,9 +115,9 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
113 u16 reg = PRIVATE_REG(kcontrol->private_value); 115 u16 reg = PRIVATE_REG(kcontrol->private_value);
114 u16 mask = PRIVATE_MASK(kcontrol->private_value); 116 u16 mask = PRIVATE_MASK(kcontrol->private_value);
115 if (uvalue->value.integer.value[0]) 117 if (uvalue->value.integer.value[0])
116 SET_REG(codec, reg, (GET_REG(codec, reg)) | mask); 118 SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) | mask);
117 else 119 else
118 SET_REG(codec, reg, (GET_REG(codec, reg)) & ~mask); 120 SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) & ~mask);
119 return 0; 121 return 0;
120} 122}
121 123
@@ -267,10 +269,6 @@ static struct hda_codec_ops si3054_patch_ops = {
267 .build_pcms = si3054_build_pcms, 269 .build_pcms = si3054_build_pcms,
268 .init = si3054_init, 270 .init = si3054_init,
269 .free = si3054_free, 271 .free = si3054_free,
270#ifdef CONFIG_PM
271 //.suspend = si3054_suspend,
272 .resume = si3054_init,
273#endif
274}; 272};
275 273
276static int patch_si3054(struct hda_codec *codec) 274static int patch_si3054(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 87a36e9d6546..145a5f3c0632 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -874,16 +874,16 @@ static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
874{ 874{
875 struct sigmatel_spec *spec = codec->spec; 875 struct sigmatel_spec *spec = codec->spec;
876 /* Configure GPIOx as output */ 876 /* Configure GPIOx as output */
877 snd_hda_codec_write(codec, codec->afg, 0, 877 snd_hda_codec_write_cache(codec, codec->afg, 0,
878 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask); 878 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
879 /* Configure GPIOx as CMOS */ 879 /* Configure GPIOx as CMOS */
880 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); 880 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
881 /* Assert GPIOx */ 881 /* Assert GPIOx */
882 snd_hda_codec_write(codec, codec->afg, 0, 882 snd_hda_codec_write_cache(codec, codec->afg, 0,
883 AC_VERB_SET_GPIO_DATA, spec->gpio_data); 883 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
884 /* Enable GPIOx */ 884 /* Enable GPIOx */
885 snd_hda_codec_write(codec, codec->afg, 0, 885 snd_hda_codec_write_cache(codec, codec->afg, 0,
886 AC_VERB_SET_GPIO_MASK, spec->gpio_mask); 886 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
887} 887}
888 888
889/* 889/*
@@ -1082,7 +1082,8 @@ static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
1082static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) 1082static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
1083 1083
1084{ 1084{
1085 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 1085 snd_hda_codec_write_cache(codec, nid, 0,
1086 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
1086} 1087}
1087 1088
1088#define stac92xx_io_switch_info snd_ctl_boolean_mono_info 1089#define stac92xx_io_switch_info snd_ctl_boolean_mono_info
@@ -1291,8 +1292,8 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1291 spec->multiout.num_dacs++; 1292 spec->multiout.num_dacs++;
1292 if (conn_len > 1) { 1293 if (conn_len > 1) {
1293 /* select this DAC in the pin's input mux */ 1294 /* select this DAC in the pin's input mux */
1294 snd_hda_codec_write(codec, nid, 0, 1295 snd_hda_codec_write_cache(codec, nid, 0,
1295 AC_VERB_SET_CONNECT_SEL, j); 1296 AC_VERB_SET_CONNECT_SEL, j);
1296 1297
1297 } 1298 }
1298 } 1299 }
@@ -1545,9 +1546,9 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
1545 * NID lists. Hopefully this won't get confused. 1546 * NID lists. Hopefully this won't get confused.
1546 */ 1547 */
1547 for (i = 0; i < spec->num_muxes; i++) { 1548 for (i = 0; i < spec->num_muxes; i++) {
1548 snd_hda_codec_write(codec, spec->mux_nids[i], 0, 1549 snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
1549 AC_VERB_SET_CONNECT_SEL, 1550 AC_VERB_SET_CONNECT_SEL,
1550 imux->items[0].index); 1551 imux->items[0].index);
1551 } 1552 }
1552 } 1553 }
1553 1554
@@ -1879,7 +1880,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
1879 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) 1880 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
1880 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 1881 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1881 1882
1882 snd_hda_codec_write(codec, nid, 0, 1883 snd_hda_codec_write_cache(codec, nid, 0,
1883 AC_VERB_SET_PIN_WIDGET_CONTROL, 1884 AC_VERB_SET_PIN_WIDGET_CONTROL,
1884 pin_ctl | flag); 1885 pin_ctl | flag);
1885} 1886}
@@ -1889,7 +1890,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
1889{ 1890{
1890 unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 1891 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
1891 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); 1892 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
1892 snd_hda_codec_write(codec, nid, 0, 1893 snd_hda_codec_write_cache(codec, nid, 0,
1893 AC_VERB_SET_PIN_WIDGET_CONTROL, 1894 AC_VERB_SET_PIN_WIDGET_CONTROL,
1894 pin_ctl & ~flag); 1895 pin_ctl & ~flag);
1895} 1896}
@@ -1948,21 +1949,10 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
1948#ifdef CONFIG_PM 1949#ifdef CONFIG_PM
1949static int stac92xx_resume(struct hda_codec *codec) 1950static int stac92xx_resume(struct hda_codec *codec)
1950{ 1951{
1951 struct sigmatel_spec *spec = codec->spec;
1952 int i;
1953
1954 stac92xx_set_config_regs(codec); 1952 stac92xx_set_config_regs(codec);
1955 if (spec->gpio_mask && spec->gpio_data)
1956 stac92xx_enable_gpio_mask(codec);
1957 stac92xx_init(codec); 1953 stac92xx_init(codec);
1958 snd_hda_resume_ctls(codec, spec->mixer); 1954 snd_hda_codec_resume_amp(codec);
1959 for (i = 0; i < spec->num_mixers; i++) 1955 snd_hda_codec_resume_cache(codec);
1960 snd_hda_resume_ctls(codec, spec->mixers[i]);
1961 if (spec->multiout.dig_out_nid)
1962 snd_hda_resume_spdif_out(codec);
1963 if (spec->dig_in_nid)
1964 snd_hda_resume_spdif_in(codec);
1965
1966 return 0; 1956 return 0;
1967} 1957}
1968#endif 1958#endif
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ba32d1e52cb8..6c734f07e5b5 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -543,27 +543,6 @@ static int via_init(struct hda_codec *codec)
543 return 0; 543 return 0;
544} 544}
545 545
546#ifdef CONFIG_PM
547/*
548 * resume
549 */
550static int via_resume(struct hda_codec *codec)
551{
552 struct via_spec *spec = codec->spec;
553 int i;
554
555 via_init(codec);
556 for (i = 0; i < spec->num_mixers; i++)
557 snd_hda_resume_ctls(codec, spec->mixers[i]);
558 if (spec->multiout.dig_out_nid)
559 snd_hda_resume_spdif_out(codec);
560 if (spec->dig_in_nid)
561 snd_hda_resume_spdif_in(codec);
562
563 return 0;
564}
565#endif
566
567/* 546/*
568 */ 547 */
569static struct hda_codec_ops via_patch_ops = { 548static struct hda_codec_ops via_patch_ops = {
@@ -571,9 +550,6 @@ static struct hda_codec_ops via_patch_ops = {
571 .build_pcms = via_build_pcms, 550 .build_pcms = via_build_pcms,
572 .init = via_init, 551 .init = via_init,
573 .free = via_free, 552 .free = via_free,
574#ifdef CONFIG_PM
575 .resume = via_resume,
576#endif
577}; 553};
578 554
579/* fill in the dac_nids table from the parsed pin configuration */ 555/* fill in the dac_nids table from the parsed pin configuration */