aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 6652a531980..1d31da47bc9 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,
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)
{
@@ -865,6 +866,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
}
}
}
+#endif /* CONFIG_PM */
/*
* AMP control callbacks
@@ -1272,11 +1274,13 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
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);
@@ -1307,17 +1311,19 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
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;
@@ -1409,10 +1415,10 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
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;
@@ -1482,6 +1488,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
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)
@@ -1548,6 +1558,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
seq->param);
}
+#endif /* CONFIG_PM */
/*
* set power state of the codec
@@ -2122,12 +2133,12 @@ int snd_hda_ch_mode_put(struct hda_codec *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;
}
@@ -2160,10 +2171,10 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
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;
}
@@ -2608,65 +2619,13 @@ int snd_hda_resume(struct hda_bus *bus)
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
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index ef94c9122c6..92938d2a52e 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -552,11 +552,6 @@ struct hda_codec {
/* 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;
@@ -622,11 +617,16 @@ void snd_hda_sequence_write(struct hda_codec *codec,
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
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 000287f7da4..d5f1180115c 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)
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;
}
/*
@@ -234,11 +234,11 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne
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;
}
/*
@@ -248,7 +248,8 @@ static int select_input_connection(struct hda_codec *codec, struct hda_gnode *no
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);
}
/*
@@ -379,7 +380,7 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
/* 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) ?
@@ -570,7 +571,8 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
/* 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 */
}
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 51208974c2d..8dec32cfdf5 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,
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) \
@@ -257,15 +259,6 @@ 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
*/
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index cc2e944cc59..f20ddd85db2 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)
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
};
@@ -376,12 +356,12 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
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;
}
@@ -882,8 +862,9 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
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;
@@ -1824,33 +1805,34 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
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;
}
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 72d3ab9751a..fbb8969dc55 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)
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
*/
@@ -141,9 +128,6 @@ static struct hda_codec_ops atihdmi_patch_ops = {
.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)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 3c722e667bc..2468f317122 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)
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
*/
@@ -635,9 +614,6 @@ static struct hda_codec_ops cmi9880_patch_ops = {
.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)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 26034315197..f1b6d0eda14 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)
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;
@@ -358,9 +341,6 @@ static struct hda_codec_ops conexant_patch_ops = {
.build_pcms = conexant_build_pcms,
.init = conexant_init,
.free = conexant_free,
-#ifdef CONFIG_PM
- .resume = conexant_resume,
-#endif
};
/*
@@ -396,13 +376,13 @@ static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
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;
}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 39c08bb670d..63011133e3f 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,
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
@@ -456,19 +457,23 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
* 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;
@@ -520,7 +525,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
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;
}
@@ -573,8 +579,8 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
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;
}
@@ -2026,27 +2032,6 @@ static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
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
*/
@@ -2278,9 +2263,6 @@ static struct hda_codec_ops alc_patch_ops = {
.init = alc_init,
.free = alc_free,
.unsol_event = alc_unsol_event,
-#ifdef CONFIG_PM
- .resume = alc_resume,
-#endif
};
@@ -2377,11 +2359,15 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
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;
@@ -2424,7 +2410,8 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
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;
@@ -4054,13 +4041,17 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec)
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);
}
}
@@ -4797,12 +4788,16 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
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;
@@ -5187,7 +5182,8 @@ static void alc882_targa_automute(struct hda_codec *codec)
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)
@@ -5777,12 +5773,16 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
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;
@@ -6509,8 +6509,8 @@ static void alc883_tagra_automute(struct hda_codec *codec)
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)
@@ -7510,8 +7510,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
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;
}
@@ -8328,14 +8328,17 @@ static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
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;
@@ -9916,12 +9919,14 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
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;
@@ -10847,12 +10852,14 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
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;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 9838eac9ab5..2a4b9609aa5 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -78,6 +78,8 @@
/* 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 {
@@ -113,9 +115,9 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
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;
}
@@ -267,10 +269,6 @@ static struct hda_codec_ops si3054_patch_ops = {
.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)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 87a36e9d654..145a5f3c063 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)
{
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);
}
/*
@@ -1082,7 +1082,8 @@ static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
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
@@ -1291,8 +1292,8 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
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);
}
}
@@ -1545,9 +1546,9 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
* 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);
}
}
@@ -1879,7 +1880,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
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);
}
@@ -1889,7 +1890,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
{
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);
}
@@ -1948,21 +1949,10 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
#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
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ba32d1e52cb..6c734f07e5b 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)
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 = {
@@ -571,9 +550,6 @@ 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 */