diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-03-18 06:29:56 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-03-18 07:58:47 -0400 |
commit | e914b25e370a3a55a839ff507ed779f54431ace5 (patch) | |
tree | 73779f18794bd94de2974cf3bd4530f21c4cbd8e /sound/pci | |
parent | 7504b6cd220a3dd8104abe3d0f985c6957dc3e17 (diff) |
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: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_beep.c | 37 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.h | 1 |
2 files changed, 27 insertions, 11 deletions
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 0849aac449f2..35bf5316ccc6 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -39,13 +39,23 @@ static void snd_hda_generate_beep(struct work_struct *work) | |||
39 | struct hda_beep *beep = | 39 | struct hda_beep *beep = |
40 | container_of(work, struct hda_beep, beep_work); | 40 | container_of(work, struct hda_beep, beep_work); |
41 | struct hda_codec *codec = beep->codec; | 41 | struct hda_codec *codec = beep->codec; |
42 | int tone; | ||
42 | 43 | ||
43 | if (!beep->enabled) | 44 | if (!beep->enabled) |
44 | return; | 45 | return; |
45 | 46 | ||
47 | tone = beep->tone; | ||
48 | if (tone && !beep->playing) { | ||
49 | snd_hda_power_up(codec); | ||
50 | beep->playing = 1; | ||
51 | } | ||
46 | /* generate tone */ | 52 | /* generate tone */ |
47 | snd_hda_codec_write(codec, beep->nid, 0, | 53 | snd_hda_codec_write(codec, beep->nid, 0, |
48 | AC_VERB_SET_BEEP_CONTROL, beep->tone); | 54 | AC_VERB_SET_BEEP_CONTROL, tone); |
55 | if (!tone && beep->playing) { | ||
56 | beep->playing = 0; | ||
57 | snd_hda_power_down(codec); | ||
58 | } | ||
49 | } | 59 | } |
50 | 60 | ||
51 | /* (non-standard) Linear beep tone calculation for IDT/STAC codecs | 61 | /* (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, | |||
115 | return 0; | 125 | return 0; |
116 | } | 126 | } |
117 | 127 | ||
128 | static void turn_off_beep(struct hda_beep *beep) | ||
129 | { | ||
130 | cancel_work_sync(&beep->beep_work); | ||
131 | if (beep->playing) { | ||
132 | /* turn off beep */ | ||
133 | snd_hda_codec_write(beep->codec, beep->nid, 0, | ||
134 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
135 | beep->playing = 0; | ||
136 | snd_hda_power_down(beep->codec); | ||
137 | } | ||
138 | } | ||
139 | |||
118 | static void snd_hda_do_detach(struct hda_beep *beep) | 140 | static void snd_hda_do_detach(struct hda_beep *beep) |
119 | { | 141 | { |
120 | input_unregister_device(beep->dev); | 142 | input_unregister_device(beep->dev); |
121 | beep->dev = NULL; | 143 | beep->dev = NULL; |
122 | cancel_work_sync(&beep->beep_work); | 144 | turn_off_beep(beep); |
123 | /* turn off beep for sure */ | ||
124 | snd_hda_codec_write(beep->codec, beep->nid, 0, | ||
125 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
126 | } | 145 | } |
127 | 146 | ||
128 | static int snd_hda_do_attach(struct hda_beep *beep) | 147 | 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) | |||
170 | enable = !!enable; | 189 | enable = !!enable; |
171 | if (beep->enabled != enable) { | 190 | if (beep->enabled != enable) { |
172 | beep->enabled = enable; | 191 | beep->enabled = enable; |
173 | if (!enable) { | 192 | if (!enable) |
174 | cancel_work_sync(&beep->beep_work); | 193 | turn_off_beep(beep); |
175 | /* turn off beep */ | ||
176 | snd_hda_codec_write(beep->codec, beep->nid, 0, | ||
177 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
178 | } | ||
179 | return 1; | 194 | return 1; |
180 | } | 195 | } |
181 | return 0; | 196 | return 0; |
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 4dc6933bc655..cb88464676b6 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -36,6 +36,7 @@ struct hda_beep { | |||
36 | hda_nid_t nid; | 36 | hda_nid_t nid; |
37 | unsigned int enabled:1; | 37 | unsigned int enabled:1; |
38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
39 | unsigned int playing:1; | ||
39 | struct work_struct beep_work; /* scheduled task for beep event */ | 40 | struct work_struct beep_work; /* scheduled task for beep event */ |
40 | struct mutex mutex; | 41 | struct mutex mutex; |
41 | }; | 42 | }; |