summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c71
-rw-r--r--sound/pci/hda/hda_local.h4
2 files changed, 56 insertions, 19 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 2f890af..0037147 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1765,7 +1765,7 @@ EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps);
*/
static struct hda_amp_info *
update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int index)
+ int direction, int index, bool init_only)
{
struct hda_amp_info *info;
unsigned int parm, val = 0;
@@ -1791,7 +1791,8 @@ update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch,
}
info->vol[ch] = val;
info->head.val |= INFO_AMP_VOL(ch);
- }
+ } else if (init_only)
+ return NULL;
return info;
}
@@ -1832,7 +1833,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
unsigned int val = 0;
mutex_lock(&codec->hash_mutex);
- info = update_amp_hash(codec, nid, ch, direction, index);
+ info = update_amp_hash(codec, nid, ch, direction, index, false);
if (info)
val = info->vol[ch];
mutex_unlock(&codec->hash_mutex);
@@ -1840,21 +1841,9 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
}
EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
-/**
- * snd_hda_codec_amp_update - update the AMP value
- * @codec: HD-audio codec
- * @nid: NID to read the AMP value
- * @ch: channel (left=0 or right=1)
- * @direction: #HDA_INPUT or #HDA_OUTPUT
- * @idx: the index value (only for input direction)
- * @mask: bit mask to set
- * @val: the bits value to set
- *
- * Update the AMP value with a bit mask.
- * Returns 0 if the value is unchanged, 1 if changed.
- */
-int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int idx, int mask, int val)
+static int codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
+ int direction, int idx, int mask, int val,
+ bool init_only)
{
struct hda_amp_info *info;
@@ -1863,7 +1852,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
val &= mask;
mutex_lock(&codec->hash_mutex);
- info = update_amp_hash(codec, nid, ch, direction, idx);
+ info = update_amp_hash(codec, nid, ch, direction, idx, init_only);
if (!info) {
mutex_unlock(&codec->hash_mutex);
return 0;
@@ -1881,6 +1870,25 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
put_vol_mute(codec, info, nid, ch, direction, idx, val);
return 1;
}
+
+/**
+ * snd_hda_codec_amp_update - update the AMP value
+ * @codec: HD-audio codec
+ * @nid: NID to read the AMP value
+ * @ch: channel (left=0 or right=1)
+ * @direction: #HDA_INPUT or #HDA_OUTPUT
+ * @idx: the index value (only for input direction)
+ * @mask: bit mask to set
+ * @val: the bits value to set
+ *
+ * Update the AMP value with a bit mask.
+ * Returns 0 if the value is unchanged, 1 if changed.
+ */
+int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
+ int direction, int idx, int mask, int val)
+{
+ return codec_amp_update(codec, nid, ch, direction, idx, mask, val, false);
+}
EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
/**
@@ -1909,6 +1917,31 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
}
EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
+/* Works like snd_hda_codec_amp_update() but it writes the value only at
+ * the first access. If the amp was already initialized / updated beforehand,
+ * this does nothing.
+ */
+int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
+ int dir, int idx, int mask, int val)
+{
+ return codec_amp_update(codec, nid, ch, dir, idx, mask, val, true);
+}
+EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init);
+
+int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid,
+ int dir, int idx, int mask, int val)
+{
+ int ch, ret = 0;
+
+ if (snd_BUG_ON(mask & ~0xff))
+ mask &= 0xff;
+ for (ch = 0; ch < 2; ch++)
+ ret |= snd_hda_codec_amp_init(codec, nid, ch, dir,
+ idx, mask, val);
+ return ret;
+}
+EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init_stereo);
+
/**
* snd_hda_codec_resume_amp - Resume all AMP commands from the cache
* @codec: HD-audio codec
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index f765296..e38519b 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -133,6 +133,10 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int idx, int mask, int val);
int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
int dir, int idx, int mask, int val);
+int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
+ int direction, int idx, int mask, int val);
+int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid,
+ int dir, int idx, int mask, int val);
void snd_hda_codec_resume_amp(struct hda_codec *codec);
void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,