diff options
-rw-r--r-- | sound/pci/hda/hda_beep.c | 42 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.h | 3 |
2 files changed, 29 insertions, 16 deletions
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 0e986537d570..74db40edb336 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -164,20 +164,21 @@ static void snd_hda_do_register(struct work_struct *work) | |||
164 | { | 164 | { |
165 | struct hda_beep *beep = | 165 | struct hda_beep *beep = |
166 | container_of(work, struct hda_beep, register_work); | 166 | container_of(work, struct hda_beep, register_work); |
167 | int request; | ||
168 | 167 | ||
169 | mutex_lock(&beep->mutex); | 168 | mutex_lock(&beep->mutex); |
170 | request = beep->request_enable; | 169 | if (beep->enabled && !beep->dev) |
171 | if (beep->enabled != request) { | 170 | snd_hda_do_attach(beep); |
172 | if (!request) { | 171 | mutex_unlock(&beep->mutex); |
173 | snd_hda_do_detach(beep); | 172 | } |
174 | } else { | 173 | |
175 | if (snd_hda_do_attach(beep) < 0) | 174 | static void snd_hda_do_unregister(struct work_struct *work) |
176 | goto __out; | 175 | { |
177 | } | 176 | struct hda_beep *beep = |
178 | beep->enabled = request; | 177 | container_of(work, struct hda_beep, unregister_work.work); |
179 | } | 178 | |
180 | __out: | 179 | mutex_lock(&beep->mutex); |
180 | if (!beep->enabled && beep->dev) | ||
181 | snd_hda_do_detach(beep); | ||
181 | mutex_unlock(&beep->mutex); | 182 | mutex_unlock(&beep->mutex); |
182 | } | 183 | } |
183 | 184 | ||
@@ -185,9 +186,19 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | |||
185 | { | 186 | { |
186 | struct hda_beep *beep = codec->beep; | 187 | struct hda_beep *beep = codec->beep; |
187 | enable = !!enable; | 188 | enable = !!enable; |
188 | if (beep && beep->enabled != enable) { | 189 | if (beep == NULL) |
189 | beep->request_enable = enable; | 190 | return 0; |
190 | schedule_work(&beep->register_work); | 191 | if (beep->enabled != enable) { |
192 | beep->enabled = enable; | ||
193 | if (enable) { | ||
194 | cancel_delayed_work(&beep->unregister_work); | ||
195 | schedule_work(&beep->register_work); | ||
196 | } else { | ||
197 | /* turn off beep */ | ||
198 | snd_hda_codec_write_cache(beep->codec, beep->nid, 0, | ||
199 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
200 | schedule_delayed_work(&beep->unregister_work, HZ); | ||
201 | } | ||
191 | return 1; | 202 | return 1; |
192 | } | 203 | } |
193 | return 0; | 204 | return 0; |
@@ -215,6 +226,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
215 | codec->beep = beep; | 226 | codec->beep = beep; |
216 | 227 | ||
217 | INIT_WORK(&beep->register_work, &snd_hda_do_register); | 228 | INIT_WORK(&beep->register_work, &snd_hda_do_register); |
229 | INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister); | ||
218 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); | 230 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); |
219 | mutex_init(&beep->mutex); | 231 | mutex_init(&beep->mutex); |
220 | 232 | ||
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 68465f679d8c..53eba8d8414d 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -34,7 +34,8 @@ struct hda_beep { | |||
34 | unsigned int enabled:1; | 34 | unsigned int enabled:1; |
35 | unsigned int request_enable:1; | 35 | unsigned int request_enable:1; |
36 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 36 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
37 | struct work_struct register_work; /* scheduled task for beep event */ | 37 | struct work_struct register_work; /* registration work */ |
38 | struct delayed_work unregister_work; /* unregistration work */ | ||
38 | struct work_struct beep_work; /* scheduled task for beep event */ | 39 | struct work_struct beep_work; /* scheduled task for beep event */ |
39 | struct mutex mutex; | 40 | struct mutex mutex; |
40 | }; | 41 | }; |