Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a68d5a54 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - introduce snd_hda_codec_update_cache()



Add a new helper, snd_hda_codec_update_cache(), for reducing the unneeded
verbs.  This function checks the cached value and skips if it's identical
with the given one.  Otherwise it works like snd_hda_codec_write_cache().

The alc269 code uses this function as an example.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ad35879a
Loading
Loading
Loading
Loading
+56 −12
Original line number Diff line number Diff line
@@ -1209,8 +1209,7 @@ static void free_hda_cache(struct hda_cache_rec *cache)
}

/* query the hash.  allocate an entry if not found. */
static struct hda_cache_head  *get_alloc_hash(struct hda_cache_rec *cache,
					      u32 key)
static struct hda_cache_head  *get_hash(struct hda_cache_rec *cache, u32 key)
{
	u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
	u16 cur = cache->hash[idx];
@@ -1222,7 +1221,16 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
			return info;
		cur = info->next;
	}
	return NULL;
}

/* query the hash.  allocate an entry if not found. */
static struct hda_cache_head  *get_alloc_hash(struct hda_cache_rec *cache,
					      u32 key)
{
	struct hda_cache_head *info = get_hash(cache, key);
	if (!info) {
		u16 idx, cur;
		/* add a new hash entry */
		info = snd_array_new(&cache->buf);
		if (!info)
@@ -1230,9 +1238,10 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
		cur = snd_array_index(&cache->buf, info);
		info->key = key;
		info->val = 0;
		idx = key % (u16)ARRAY_SIZE(cache->hash);
		info->next = cache->hash[idx];
		cache->hash[idx] = cur;

	}
	return info;
}

@@ -2721,6 +2730,41 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
}
EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);

/**
 * snd_hda_codec_update_cache - check cache and write the cmd only when needed
 * @codec: the HDA codec
 * @nid: NID to send the command
 * @direct: direct flag
 * @verb: the verb to send
 * @parm: the parameter for the verb
 *
 * This function works like snd_hda_codec_write_cache(), but it doesn't send
 * command if the parameter is already identical with the cached value.
 * If not, it sends the command and refreshes the cache.
 *
 * Returns 0 if successful, or a negative error code.
 */
int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
			       int direct, unsigned int verb, unsigned int parm)
{
	struct hda_cache_head *c;
	u32 key;

	/* parm may contain the verb stuff for get/set amp */
	verb = verb | (parm >> 8);
	parm &= 0xff;
	key = build_cmd_cache_key(nid, verb);
	mutex_lock(&codec->bus->cmd_mutex);
	c = get_hash(&codec->cmd_cache, key);
	if (c && c->val == parm) {
		mutex_unlock(&codec->bus->cmd_mutex);
		return 0;
	}
	mutex_unlock(&codec->bus->cmd_mutex);
	return snd_hda_codec_write_cache(codec, nid, direct, verb, parm);
}
EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache);

/**
 * snd_hda_codec_resume_cache - Resume the all commands from the cache
 * @codec: HD-audio codec
+3 −0
Original line number Diff line number Diff line
@@ -885,9 +885,12 @@ 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);
int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
			      int direct, unsigned int verb, unsigned int parm);
void snd_hda_codec_resume_cache(struct hda_codec *codec);
#else
#define snd_hda_codec_write_cache	snd_hda_codec_write
#define snd_hda_codec_update_cache	snd_hda_codec_write
#define snd_hda_sequence_write_cache	snd_hda_sequence_write
#endif

+3 −2
Original line number Diff line number Diff line
@@ -14012,8 +14012,9 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
		else
			pinval = 0x20;
		/* mic2 vref pin is used for mute LED control */
		snd_hda_codec_write(codec, 0x19, 0,
				    AC_VERB_SET_PIN_WIDGET_CONTROL, pinval);
		snd_hda_codec_update_cache(codec, 0x19, 0,
					   AC_VERB_SET_PIN_WIDGET_CONTROL,
					   pinval);
	}
	return alc_check_power_status(codec, nid);
}