Commit 4c8d695c authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda: beep: Simplify keep-power-at-enable behavior

The recent fix for IDT codecs to keep the power up while the beep is
enabled can be better integrated into the beep helper code.
This patch cleans up the code with refactoring.

Fixes: 414d38ba ("ALSA: hda/sigmatel: Keep power up while beep is enabled")
Link: https://lore.kernel.org/r/20220906092306.26183-1-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 6392dcd1
...@@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, ...@@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
return 0; return 0;
} }
static void turn_on_beep(struct hda_beep *beep)
{
if (beep->keep_power_at_enable)
snd_hda_power_up_pm(beep->codec);
}
static void turn_off_beep(struct hda_beep *beep) static void turn_off_beep(struct hda_beep *beep)
{ {
cancel_work_sync(&beep->beep_work); cancel_work_sync(&beep->beep_work);
...@@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep) ...@@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep)
/* turn off beep */ /* turn off beep */
generate_tone(beep, 0); generate_tone(beep, 0);
} }
if (beep->keep_power_at_enable)
snd_hda_power_down_pm(beep->codec);
} }
/** /**
...@@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) ...@@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
enable = !!enable; enable = !!enable;
if (beep->enabled != enable) { if (beep->enabled != enable) {
beep->enabled = enable; beep->enabled = enable;
if (!enable) if (enable)
turn_on_beep(beep);
else
turn_off_beep(beep); turn_off_beep(beep);
return 1; return 1;
} }
...@@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device) ...@@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device)
input_unregister_device(beep->dev); input_unregister_device(beep->dev);
else else
input_free_device(beep->dev); input_free_device(beep->dev);
turn_off_beep(beep); if (beep->enabled)
turn_off_beep(beep);
return 0; return 0;
} }
......
...@@ -25,6 +25,7 @@ struct hda_beep { ...@@ -25,6 +25,7 @@ struct hda_beep {
unsigned int enabled:1; unsigned int enabled:1;
unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
unsigned int playing:1; unsigned int playing:1;
unsigned int keep_power_at_enable:1; /* set by driver */
struct work_struct beep_work; /* scheduled task for beep event */ struct work_struct beep_work; /* scheduled task for beep event */
struct mutex mutex; struct mutex mutex;
void (*power_hook)(struct hda_beep *beep, bool on); void (*power_hook)(struct hda_beep *beep, bool on);
......
...@@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec) ...@@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec)
if (codec->beep) { if (codec->beep) {
/* IDT/STAC codecs have linear beep tone parameter */ /* IDT/STAC codecs have linear beep tone parameter */
codec->beep->linear_tone = spec->linear_tone_beep; codec->beep->linear_tone = spec->linear_tone_beep;
/* keep power up while beep is enabled */
codec->beep->keep_power_at_enable = 1;
/* if no beep switch is available, make its own one */ /* if no beep switch is available, make its own one */
caps = query_amp_caps(codec, nid, HDA_OUTPUT); caps = query_amp_caps(codec, nid, HDA_OUTPUT);
if (!(caps & AC_AMPCAP_MUTE)) { if (!(caps & AC_AMPCAP_MUTE)) {
...@@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec) ...@@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec)
return 0; return 0;
} }
static int stac_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
#ifdef CONFIG_SND_HDA_INPUT_BEEP
struct sigmatel_spec *spec = codec->spec;
#endif
int ret = snd_hda_gen_check_power_status(codec, nid);
#ifdef CONFIG_SND_HDA_INPUT_BEEP
if (nid == spec->gen.beep_nid && codec->beep) {
if (codec->beep->enabled != spec->beep_power_on) {
spec->beep_power_on = codec->beep->enabled;
if (spec->beep_power_on)
snd_hda_power_up_pm(codec);
else
snd_hda_power_down_pm(codec);
}
ret |= spec->beep_power_on;
}
#endif
return ret;
}
#else #else
#define stac_suspend NULL #define stac_suspend NULL
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
...@@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = { ...@@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = {
.unsol_event = snd_hda_jack_unsol_event, .unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = stac_suspend, .suspend = stac_suspend,
.check_power_status = stac_check_power_status,
#endif #endif
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment