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

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

ALSA: hda - Fix power-saving during playing beep sound



While playing the digital beep tone, the codec shouldn't be turned
off.  This patch adds proper snd_hda_power_up()/down() calls at each
time when the beep is played or off.

Also, this fixes automatically an unnecessary codec power-up at
detaching the beep device when the beep isn't being played.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 7504b6cd
Loading
Loading
Loading
Loading
+26 −11
Original line number Diff line number Diff line
@@ -39,13 +39,23 @@ static void snd_hda_generate_beep(struct work_struct *work)
	struct hda_beep *beep =
		container_of(work, struct hda_beep, beep_work);
	struct hda_codec *codec = beep->codec;
	int tone;

	if (!beep->enabled)
		return;

	tone = beep->tone;
	if (tone && !beep->playing) {
		snd_hda_power_up(codec);
		beep->playing = 1;
	}
	/* generate tone */
	snd_hda_codec_write(codec, beep->nid, 0,
			AC_VERB_SET_BEEP_CONTROL, beep->tone);
			    AC_VERB_SET_BEEP_CONTROL, tone);
	if (!tone && beep->playing) {
		beep->playing = 0;
		snd_hda_power_down(codec);
	}
}

/* (non-standard) Linear beep tone calculation for IDT/STAC codecs 
@@ -115,14 +125,23 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
	return 0;
}

static void snd_hda_do_detach(struct hda_beep *beep)
static void turn_off_beep(struct hda_beep *beep)
{
	input_unregister_device(beep->dev);
	beep->dev = NULL;
	cancel_work_sync(&beep->beep_work);
	/* turn off beep for sure */
	if (beep->playing) {
		/* turn off beep */
		snd_hda_codec_write(beep->codec, beep->nid, 0,
				    AC_VERB_SET_BEEP_CONTROL, 0);
		beep->playing = 0;
		snd_hda_power_down(beep->codec);
	}
}

static void snd_hda_do_detach(struct hda_beep *beep)
{
	input_unregister_device(beep->dev);
	beep->dev = NULL;
	turn_off_beep(beep);
}

static int snd_hda_do_attach(struct hda_beep *beep)
@@ -170,12 +189,8 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
	enable = !!enable;
	if (beep->enabled != enable) {
		beep->enabled = enable;
		if (!enable) {
			cancel_work_sync(&beep->beep_work);
			/* turn off beep */
			snd_hda_codec_write(beep->codec, beep->nid, 0,
						  AC_VERB_SET_BEEP_CONTROL, 0);
		}
		if (!enable)
			turn_off_beep(beep);
		return 1;
	}
	return 0;
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct hda_beep {
	hda_nid_t nid;
	unsigned int enabled:1;
	unsigned int linear_tone:1;	/* linear tone for IDT/STAC codec */
	unsigned int playing:1;
	struct work_struct beep_work; /* scheduled task for beep event */
	struct mutex mutex;
};