Loading sound/pci/hda/hda_codec.c +56 −12 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -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) Loading @@ -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; } Loading Loading @@ -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 Loading sound/pci/hda/hda_codec.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading sound/pci/hda/patch_realtek.c +39 −0 Original line number Diff line number Diff line Loading @@ -3467,6 +3467,10 @@ static int alc_init(struct hda_codec *codec) if (spec->init_hook) spec->init_hook(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (codec->patch_ops.check_power_status) codec->patch_ops.check_power_status(codec, 0x01); #endif return 0; } Loading Loading @@ -3827,6 +3831,10 @@ static int alc_resume(struct hda_codec *codec) codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (codec->patch_ops.check_power_status) codec->patch_ops.check_power_status(codec, 0x01); #endif return 0; } #endif Loading Loading @@ -13983,6 +13991,35 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { /* NID is set in alc_build_pcms */ }; #ifdef CONFIG_SND_HDA_POWER_SAVE static int alc269_mic2_for_mute_led(struct hda_codec *codec) { switch (codec->subsystem_id) { case 0x103c1586: return 1; } return 0; } static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) { /* update mute-LED according to the speaker mute state */ if (nid == 0x01 || nid == 0x14) { int pinval; if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE) pinval = 0x24; else pinval = 0x20; /* mic2 vref pin is used for mute LED control */ snd_hda_codec_update_cache(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinval); } return alc_check_power_status(codec, nid); } #endif /* CONFIG_SND_HDA_POWER_SAVE */ /* * BIOS auto configuration */ Loading Loading @@ -14330,6 +14367,8 @@ static int patch_alc269(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc269_loopbacks; if (alc269_mic2_for_mute_led(codec)) codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; #endif return 0; Loading Loading
sound/pci/hda/hda_codec.c +56 −12 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -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) Loading @@ -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; } Loading Loading @@ -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 Loading
sound/pci/hda/hda_codec.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
sound/pci/hda/patch_realtek.c +39 −0 Original line number Diff line number Diff line Loading @@ -3467,6 +3467,10 @@ static int alc_init(struct hda_codec *codec) if (spec->init_hook) spec->init_hook(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (codec->patch_ops.check_power_status) codec->patch_ops.check_power_status(codec, 0x01); #endif return 0; } Loading Loading @@ -3827,6 +3831,10 @@ static int alc_resume(struct hda_codec *codec) codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (codec->patch_ops.check_power_status) codec->patch_ops.check_power_status(codec, 0x01); #endif return 0; } #endif Loading Loading @@ -13983,6 +13991,35 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { /* NID is set in alc_build_pcms */ }; #ifdef CONFIG_SND_HDA_POWER_SAVE static int alc269_mic2_for_mute_led(struct hda_codec *codec) { switch (codec->subsystem_id) { case 0x103c1586: return 1; } return 0; } static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) { /* update mute-LED according to the speaker mute state */ if (nid == 0x01 || nid == 0x14) { int pinval; if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE) pinval = 0x24; else pinval = 0x20; /* mic2 vref pin is used for mute LED control */ snd_hda_codec_update_cache(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinval); } return alc_check_power_status(codec, nid); } #endif /* CONFIG_SND_HDA_POWER_SAVE */ /* * BIOS auto configuration */ Loading Loading @@ -14330,6 +14367,8 @@ static int patch_alc269(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc269_loopbacks; if (alc269_mic2_for_mute_led(codec)) codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; #endif return 0; Loading