Skip to content

Commit 6cd23b2

Browse files
committed
ALSA: hda/generic: Add a helper to mute speakers at suspend/shutdown
Some devices indicate click noises at suspend or shutdown when the speakers are unmuted. This patch adds a helper, snd_hda_gen_shutup_speakers(), to work around it. The new function is supposed to be called at suspend or shutdown by the codec driver, and it mutes the speakers. The mute status isn't cached, hence the original mute state will be restored at resume again. Link: https://patch.msgid.link/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent e60dc98 commit 6cd23b2

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

sound/pci/hda/hda_generic.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4955,6 +4955,69 @@ void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on)
49554955
}
49564956
EXPORT_SYMBOL_GPL(snd_hda_gen_stream_pm);
49574957

4958+
/* forcibly mute the speaker output without caching; return true if updated */
4959+
static bool force_mute_output_path(struct hda_codec *codec, hda_nid_t nid)
4960+
{
4961+
if (!nid)
4962+
return false;
4963+
if (!nid_has_mute(codec, nid, HDA_OUTPUT))
4964+
return false; /* no mute, skip */
4965+
if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4966+
snd_hda_codec_amp_read(codec, nid, 1, HDA_OUTPUT, 0) &
4967+
HDA_AMP_MUTE)
4968+
return false; /* both channels already muted, skip */
4969+
4970+
/* direct amp update without caching */
4971+
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4972+
AC_AMP_SET_OUTPUT | AC_AMP_SET_LEFT |
4973+
AC_AMP_SET_RIGHT | HDA_AMP_MUTE);
4974+
return true;
4975+
}
4976+
4977+
/**
4978+
* snd_hda_gen_shutup_speakers - Forcibly mute the speaker outputs
4979+
* @codec: the HDA codec
4980+
*
4981+
* Forcibly mute the speaker outputs, to be called at suspend or shutdown.
4982+
*
4983+
* The mute state done by this function isn't cached, hence the original state
4984+
* will be restored at resume.
4985+
*
4986+
* Return true if the mute state has been changed.
4987+
*/
4988+
bool snd_hda_gen_shutup_speakers(struct hda_codec *codec)
4989+
{
4990+
struct hda_gen_spec *spec = codec->spec;
4991+
const int *paths;
4992+
const struct nid_path *path;
4993+
int i, p, num_paths;
4994+
bool updated = false;
4995+
4996+
/* if already powered off, do nothing */
4997+
if (!snd_hdac_is_power_on(&codec->core))
4998+
return false;
4999+
5000+
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
5001+
paths = spec->out_paths;
5002+
num_paths = spec->autocfg.line_outs;
5003+
} else {
5004+
paths = spec->speaker_paths;
5005+
num_paths = spec->autocfg.speaker_outs;
5006+
}
5007+
5008+
for (i = 0; i < num_paths; i++) {
5009+
path = snd_hda_get_path_from_idx(codec, paths[i]);
5010+
if (!path)
5011+
continue;
5012+
for (p = 0; p < path->depth; p++)
5013+
if (force_mute_output_path(codec, path->path[p]))
5014+
updated = true;
5015+
}
5016+
5017+
return updated;
5018+
}
5019+
EXPORT_SYMBOL_GPL(snd_hda_gen_shutup_speakers);
5020+
49585021
/**
49595022
* snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and
49605023
* set up the hda_gen_spec

sound/pci/hda/hda_generic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,5 +353,6 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,
353353
int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
354354
int (*callback)(struct led_classdev *,
355355
enum led_brightness));
356+
bool snd_hda_gen_shutup_speakers(struct hda_codec *codec);
356357

357358
#endif /* __SOUND_HDA_GENERIC_H */

0 commit comments

Comments
 (0)