*/
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;
}
info->vol[ch] = val;
info->head.val |= INFO_AMP_VOL(ch);
- }
+ } else if (init_only)
+ return NULL;
return info;
}
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);
}
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;
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;
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);
/**
}
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