Ported ACPI CA (from the nice guys at Intel) to ReactOS (ACPI bus driver).
[reactos.git] / reactos / drivers / bus / acpi / events / evxfevnt.c
1 /******************************************************************************
2 *
3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4 * $Revision: 1.1 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26
27 #include "acpi.h"
28 #include "achware.h"
29 #include "acnamesp.h"
30 #include "acevents.h"
31 #include "amlcode.h"
32 #include "acinterp.h"
33
34 #define _COMPONENT ACPI_EVENTS
35 MODULE_NAME ("evxfevnt")
36
37
38 /**************************************************************************
39 *
40 * FUNCTION: Acpi_enable
41 *
42 * PARAMETERS: None
43 *
44 * RETURN: Status
45 *
46 * DESCRIPTION: Transfers the system into ACPI mode.
47 *
48 *************************************************************************/
49
50 ACPI_STATUS
51 acpi_enable (void)
52 {
53 ACPI_STATUS status;
54
55
56 /* Make sure we've got ACPI tables */
57
58 if (!acpi_gbl_DSDT) {
59 return (AE_NO_ACPI_TABLES);
60 }
61
62 /* Make sure the BIOS supports ACPI mode */
63
64 if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) {
65 return (AE_ERROR);
66 }
67
68 /* Transition to ACPI mode */
69
70 status = acpi_hw_set_mode (SYS_MODE_ACPI);
71 if (ACPI_FAILURE (status)) {
72 return (status);
73 }
74
75 return (status);
76 }
77
78
79 /**************************************************************************
80 *
81 * FUNCTION: Acpi_disable
82 *
83 * PARAMETERS: None
84 *
85 * RETURN: Status
86 *
87 * DESCRIPTION: Returns the system to original ACPI/legacy mode, and
88 * uninstalls the SCI interrupt handler.
89 *
90 *************************************************************************/
91
92 ACPI_STATUS
93 acpi_disable (void)
94 {
95 ACPI_STATUS status;
96
97
98 /* Restore original mode */
99
100 status = acpi_hw_set_mode (acpi_gbl_original_mode);
101 if (ACPI_FAILURE (status)) {
102 return (status);
103 }
104
105 /* Unload the SCI interrupt handler */
106
107 acpi_ev_remove_sci_handler ();
108 acpi_ev_restore_acpi_state ();
109
110 return (status);
111 }
112
113
114 /******************************************************************************
115 *
116 * FUNCTION: Acpi_enable_event
117 *
118 * PARAMETERS: Event - The fixed event or GPE to be enabled
119 * Type - The type of event
120 *
121 * RETURN: Status
122 *
123 * DESCRIPTION: Enable an ACPI event (fixed and general purpose)
124 *
125 ******************************************************************************/
126
127 ACPI_STATUS
128 acpi_enable_event (
129 u32 event,
130 u32 type)
131 {
132 ACPI_STATUS status = AE_OK;
133 u32 register_id;
134
135
136 /* The Type must be either Fixed Acpi_event or GPE */
137
138 switch (type) {
139
140 case ACPI_EVENT_FIXED:
141
142 /* Decode the Fixed Acpi_event */
143
144 switch (event) {
145 case ACPI_EVENT_PMTIMER:
146 register_id = TMR_EN;
147 break;
148
149 case ACPI_EVENT_GLOBAL:
150 register_id = GBL_EN;
151 break;
152
153 case ACPI_EVENT_POWER_BUTTON:
154 register_id = PWRBTN_EN;
155 break;
156
157 case ACPI_EVENT_SLEEP_BUTTON:
158 register_id = SLPBTN_EN;
159 break;
160
161 case ACPI_EVENT_RTC:
162 register_id = RTC_EN;
163 break;
164
165 default:
166 return (AE_BAD_PARAMETER);
167 break;
168 }
169
170 /*
171 * Enable the requested fixed event (by writing a one to the
172 * enable register bit)
173 */
174
175 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
176
177 if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
178 return (AE_NO_HARDWARE_RESPONSE);
179 }
180
181 break;
182
183
184 case ACPI_EVENT_GPE:
185
186 /* Ensure that we have a valid GPE number */
187
188 if ((event >= NUM_GPE) ||
189 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
190 return (AE_BAD_PARAMETER);
191 }
192
193
194 /* Enable the requested GPE number */
195
196 acpi_hw_enable_gpe (event);
197 break;
198
199
200 default:
201
202 status = AE_BAD_PARAMETER;
203 }
204
205
206 return (status);
207 }
208
209
210 /******************************************************************************
211 *
212 * FUNCTION: Acpi_disable_event
213 *
214 * PARAMETERS: Event - The fixed event or GPE to be enabled
215 * Type - The type of event
216 *
217 * RETURN: Status
218 *
219 * DESCRIPTION: Disable an ACPI event (fixed and general purpose)
220 *
221 ******************************************************************************/
222
223 ACPI_STATUS
224 acpi_disable_event (
225 u32 event,
226 u32 type)
227 {
228 ACPI_STATUS status = AE_OK;
229 u32 register_id;
230
231
232 /* The Type must be either Fixed Acpi_event or GPE */
233
234 switch (type) {
235
236 case ACPI_EVENT_FIXED:
237
238 /* Decode the Fixed Acpi_event */
239
240 switch (event) {
241 case ACPI_EVENT_PMTIMER:
242 register_id = TMR_EN;
243 break;
244
245 case ACPI_EVENT_GLOBAL:
246 register_id = GBL_EN;
247 break;
248
249 case ACPI_EVENT_POWER_BUTTON:
250 register_id = PWRBTN_EN;
251 break;
252
253 case ACPI_EVENT_SLEEP_BUTTON:
254 register_id = SLPBTN_EN;
255 break;
256
257 case ACPI_EVENT_RTC:
258 register_id = RTC_EN;
259 break;
260
261 default:
262 return (AE_BAD_PARAMETER);
263 break;
264 }
265
266 /*
267 * Disable the requested fixed event (by writing a zero to the
268 * enable register bit)
269 */
270
271 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0);
272
273 if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
274 return (AE_NO_HARDWARE_RESPONSE);
275 }
276
277 break;
278
279
280 case ACPI_EVENT_GPE:
281
282 /* Ensure that we have a valid GPE number */
283
284 if ((event >= NUM_GPE) ||
285 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
286 return (AE_BAD_PARAMETER);
287 }
288
289 /* Disable the requested GPE number */
290
291 acpi_hw_disable_gpe (event);
292 break;
293
294
295 default:
296 status = AE_BAD_PARAMETER;
297 }
298
299 return (status);
300 }
301
302
303 /******************************************************************************
304 *
305 * FUNCTION: Acpi_clear_event
306 *
307 * PARAMETERS: Event - The fixed event or GPE to be cleared
308 * Type - The type of event
309 *
310 * RETURN: Status
311 *
312 * DESCRIPTION: Clear an ACPI event (fixed and general purpose)
313 *
314 ******************************************************************************/
315
316 ACPI_STATUS
317 acpi_clear_event (
318 u32 event,
319 u32 type)
320 {
321 ACPI_STATUS status = AE_OK;
322 u32 register_id;
323
324
325 /* The Type must be either Fixed Acpi_event or GPE */
326
327 switch (type) {
328
329 case ACPI_EVENT_FIXED:
330
331 /* Decode the Fixed Acpi_event */
332
333 switch (event) {
334 case ACPI_EVENT_PMTIMER:
335 register_id = TMR_STS;
336 break;
337
338 case ACPI_EVENT_GLOBAL:
339 register_id = GBL_STS;
340 break;
341
342 case ACPI_EVENT_POWER_BUTTON:
343 register_id = PWRBTN_STS;
344 break;
345
346 case ACPI_EVENT_SLEEP_BUTTON:
347 register_id = SLPBTN_STS;
348 break;
349
350 case ACPI_EVENT_RTC:
351 register_id = RTC_STS;
352 break;
353
354 default:
355 return (AE_BAD_PARAMETER);
356 break;
357 }
358
359 /*
360 * Clear the requested fixed event (By writing a one to the
361 * status register bit)
362 */
363
364 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
365 break;
366
367
368 case ACPI_EVENT_GPE:
369
370 /* Ensure that we have a valid GPE number */
371
372 if ((event >= NUM_GPE) ||
373 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
374 return (AE_BAD_PARAMETER);
375 }
376
377
378 acpi_hw_clear_gpe (event);
379 break;
380
381
382 default:
383
384 status = AE_BAD_PARAMETER;
385 }
386
387 return (status);
388 }
389
390
391 /******************************************************************************
392 *
393 * FUNCTION: Acpi_get_event_status
394 *
395 * PARAMETERS: Event - The fixed event or GPE
396 * Type - The type of event
397 * Status - Where the current status of the event will
398 * be returned
399 *
400 * RETURN: Status
401 *
402 * DESCRIPTION: Obtains and returns the current status of the event
403 *
404 ******************************************************************************/
405
406
407 ACPI_STATUS
408 acpi_get_event_status (
409 u32 event,
410 u32 type,
411 ACPI_EVENT_STATUS *event_status)
412 {
413 ACPI_STATUS status = AE_OK;
414 u32 register_id;
415
416
417 if (!event_status) {
418 return (AE_BAD_PARAMETER);
419 }
420
421
422 /* The Type must be either Fixed Acpi_event or GPE */
423
424 switch (type) {
425
426 case ACPI_EVENT_FIXED:
427
428 /* Decode the Fixed Acpi_event */
429
430 switch (event) {
431 case ACPI_EVENT_PMTIMER:
432 register_id = TMR_STS;
433 break;
434
435 case ACPI_EVENT_GLOBAL:
436 register_id = GBL_STS;
437 break;
438
439 case ACPI_EVENT_POWER_BUTTON:
440 register_id = PWRBTN_STS;
441 break;
442
443 case ACPI_EVENT_SLEEP_BUTTON:
444 register_id = SLPBTN_STS;
445 break;
446
447 case ACPI_EVENT_RTC:
448 register_id = RTC_STS;
449 break;
450
451 default:
452 return (AE_BAD_PARAMETER);
453 break;
454 }
455
456 /* Get the status of the requested fixed event */
457
458 *event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id);
459 break;
460
461
462 case ACPI_EVENT_GPE:
463
464 /* Ensure that we have a valid GPE number */
465
466 if ((event >= NUM_GPE) ||
467 (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
468 return (AE_BAD_PARAMETER);
469 }
470
471
472 /* Obtain status on the requested GPE number */
473
474 acpi_hw_get_gpe_status (event, event_status);
475 break;
476
477
478 default:
479 status = AE_BAD_PARAMETER;
480 }
481
482
483 return (status);
484 }
485