|
@@ -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
|