1/******************************************************************************
2 *
3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4 *              $Revision: 1.1.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
50acpi_status
51acpi_enable (void)
52{
53	acpi_status             status;
54
55
56	FUNCTION_TRACE ("Acpi_enable");
57
58
59	/* Make sure we've got ACPI tables */
60
61	if (!acpi_gbl_DSDT) {
62		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n"));
63		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
64	}
65
66	/* Make sure the BIOS supports ACPI mode */
67
68	if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) {
69		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Only legacy mode supported!\n"));
70		return_ACPI_STATUS (AE_ERROR);
71	}
72
73	/* Transition to ACPI mode */
74
75	status = acpi_hw_set_mode (SYS_MODE_ACPI);
76	if (ACPI_FAILURE (status)) {
77		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Could not transition to ACPI mode.\n"));
78		return_ACPI_STATUS (status);
79	}
80
81	ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Transition to ACPI mode successful\n"));
82
83	return_ACPI_STATUS (status);
84}
85
86
87/*******************************************************************************
88 *
89 * FUNCTION:    Acpi_disable
90 *
91 * PARAMETERS:  None
92 *
93 * RETURN:      Status
94 *
95 * DESCRIPTION: Returns the system to original ACPI/legacy mode, and
96 *              uninstalls the SCI interrupt handler.
97 *
98 ******************************************************************************/
99
100acpi_status
101acpi_disable (void)
102{
103	acpi_status             status;
104
105
106	FUNCTION_TRACE ("Acpi_disable");
107
108
109	/* Restore original mode  */
110
111	status = acpi_hw_set_mode (acpi_gbl_original_mode);
112	if (ACPI_FAILURE (status)) {
113		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to transition to original mode"));
114		return_ACPI_STATUS (status);
115	}
116
117	/* Unload the SCI interrupt handler  */
118
119	acpi_ev_remove_sci_handler ();
120	acpi_ev_restore_acpi_state ();
121
122	return_ACPI_STATUS (status);
123}
124
125
126/*******************************************************************************
127 *
128 * FUNCTION:    Acpi_enable_event
129 *
130 * PARAMETERS:  Event           - The fixed event or GPE to be enabled
131 *              Type            - The type of event
132 *              Flags           - Just enable, or also wake enable?
133 *
134 * RETURN:      Status
135 *
136 * DESCRIPTION: Enable an ACPI event (fixed and general purpose)
137 *
138 ******************************************************************************/
139
140acpi_status
141acpi_enable_event (
142	u32                     event,
143	u32                     type,
144	u32                     flags)
145{
146	acpi_status             status = AE_OK;
147	u32                     register_id;
148
149
150	FUNCTION_TRACE ("Acpi_enable_event");
151
152
153	/* The Type must be either Fixed Acpi_event or GPE */
154
155	switch (type) {
156
157	case ACPI_EVENT_FIXED:
158
159		/* Decode the Fixed Acpi_event */
160
161		switch (event) {
162		case ACPI_EVENT_PMTIMER:
163			register_id = TMR_EN;
164			break;
165
166		case ACPI_EVENT_GLOBAL:
167			register_id = GBL_EN;
168			break;
169
170		case ACPI_EVENT_POWER_BUTTON:
171			register_id = PWRBTN_EN;
172			break;
173
174		case ACPI_EVENT_SLEEP_BUTTON:
175			register_id = SLPBTN_EN;
176			break;
177
178		case ACPI_EVENT_RTC:
179			register_id = RTC_EN;
180			break;
181
182		default:
183			return_ACPI_STATUS (AE_BAD_PARAMETER);
184			break;
185		}
186
187		/*
188		 * Enable the requested fixed event (by writing a one to the
189		 * enable register bit)
190		 */
191		acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
192
193		if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
194			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
195				"Fixed event bit clear when it should be set\n"));
196			return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
197		}
198
199		break;
200
201
202	case ACPI_EVENT_GPE:
203
204		/* Ensure that we have a valid GPE number */
205
206		if ((event > ACPI_GPE_MAX) ||
207			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
208			return_ACPI_STATUS (AE_BAD_PARAMETER);
209		}
210
211
212		/* Enable the requested GPE number */
213
214		if (flags & ACPI_EVENT_ENABLE) {
215			acpi_hw_enable_gpe (event);
216		}
217		if (flags & ACPI_EVENT_WAKE_ENABLE) {
218			acpi_hw_enable_gpe_for_wakeup (event);
219		}
220
221		break;
222
223
224	default:
225
226		status = AE_BAD_PARAMETER;
227	}
228
229
230	return_ACPI_STATUS (status);
231}
232
233
234/*******************************************************************************
235 *
236 * FUNCTION:    Acpi_disable_event
237 *
238 * PARAMETERS:  Event           - The fixed event or GPE to be enabled
239 *              Type            - The type of event, fixed or general purpose
240 *              Flags           - Wake disable vs. non-wake disable
241 *
242 * RETURN:      Status
243 *
244 * DESCRIPTION: Disable an ACPI event (fixed and general purpose)
245 *
246 ******************************************************************************/
247
248acpi_status
249acpi_disable_event (
250	u32                     event,
251	u32                     type,
252	u32                     flags)
253{
254	acpi_status             status = AE_OK;
255	u32                     register_id;
256
257
258	FUNCTION_TRACE ("Acpi_disable_event");
259
260
261	/* The Type must be either Fixed Acpi_event or GPE */
262
263	switch (type) {
264
265	case ACPI_EVENT_FIXED:
266
267		/* Decode the Fixed Acpi_event */
268
269		switch (event) {
270		case ACPI_EVENT_PMTIMER:
271			register_id = TMR_EN;
272			break;
273
274		case ACPI_EVENT_GLOBAL:
275			register_id = GBL_EN;
276			break;
277
278		case ACPI_EVENT_POWER_BUTTON:
279			register_id = PWRBTN_EN;
280			break;
281
282		case ACPI_EVENT_SLEEP_BUTTON:
283			register_id = SLPBTN_EN;
284			break;
285
286		case ACPI_EVENT_RTC:
287			register_id = RTC_EN;
288			break;
289
290		default:
291			return_ACPI_STATUS (AE_BAD_PARAMETER);
292			break;
293		}
294
295		/*
296		 * Disable the requested fixed event (by writing a zero to the
297		 * enable register bit)
298		 */
299		acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0);
300
301		if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
302			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
303				"Fixed event bit set when it should be clear,\n"));
304			return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
305		}
306
307		break;
308
309
310	case ACPI_EVENT_GPE:
311
312		/* Ensure that we have a valid GPE number */
313
314		if ((event > ACPI_GPE_MAX) ||
315			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
316			return_ACPI_STATUS (AE_BAD_PARAMETER);
317		}
318
319		/* Disable the requested GPE number */
320
321		if (flags & ACPI_EVENT_DISABLE) {
322			acpi_hw_disable_gpe (event);
323		}
324		if (flags & ACPI_EVENT_WAKE_DISABLE) {
325			acpi_hw_disable_gpe_for_wakeup (event);
326		}
327
328		break;
329
330
331	default:
332		status = AE_BAD_PARAMETER;
333	}
334
335	return_ACPI_STATUS (status);
336}
337
338
339/*******************************************************************************
340 *
341 * FUNCTION:    Acpi_clear_event
342 *
343 * PARAMETERS:  Event           - The fixed event or GPE to be cleared
344 *              Type            - The type of event
345 *
346 * RETURN:      Status
347 *
348 * DESCRIPTION: Clear an ACPI event (fixed and general purpose)
349 *
350 ******************************************************************************/
351
352acpi_status
353acpi_clear_event (
354	u32                     event,
355	u32                     type)
356{
357	acpi_status             status = AE_OK;
358	u32                     register_id;
359
360
361	FUNCTION_TRACE ("Acpi_clear_event");
362
363
364	/* The Type must be either Fixed Acpi_event or GPE */
365
366	switch (type) {
367
368	case ACPI_EVENT_FIXED:
369
370		/* Decode the Fixed Acpi_event */
371
372		switch (event) {
373		case ACPI_EVENT_PMTIMER:
374			register_id = TMR_STS;
375			break;
376
377		case ACPI_EVENT_GLOBAL:
378			register_id = GBL_STS;
379			break;
380
381		case ACPI_EVENT_POWER_BUTTON:
382			register_id = PWRBTN_STS;
383			break;
384
385		case ACPI_EVENT_SLEEP_BUTTON:
386			register_id = SLPBTN_STS;
387			break;
388
389		case ACPI_EVENT_RTC:
390			register_id = RTC_STS;
391			break;
392
393		default:
394			return_ACPI_STATUS (AE_BAD_PARAMETER);
395			break;
396		}
397
398		/*
399		 * Clear the requested fixed event (By writing a one to the
400		 * status register bit)
401		 */
402		acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
403		break;
404
405
406	case ACPI_EVENT_GPE:
407
408		/* Ensure that we have a valid GPE number */
409
410		if ((event > ACPI_GPE_MAX) ||
411			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
412			return_ACPI_STATUS (AE_BAD_PARAMETER);
413		}
414
415
416		acpi_hw_clear_gpe (event);
417		break;
418
419
420	default:
421
422		status = AE_BAD_PARAMETER;
423	}
424
425	return_ACPI_STATUS (status);
426}
427
428
429/*******************************************************************************
430 *
431 * FUNCTION:    Acpi_get_event_status
432 *
433 * PARAMETERS:  Event           - The fixed event or GPE
434 *              Type            - The type of event
435 *              Status          - Where the current status of the event will
436 *                                be returned
437 *
438 * RETURN:      Status
439 *
440 * DESCRIPTION: Obtains and returns the current status of the event
441 *
442 ******************************************************************************/
443
444
445acpi_status
446acpi_get_event_status (
447	u32                     event,
448	u32                     type,
449	acpi_event_status       *event_status)
450{
451	acpi_status             status = AE_OK;
452	u32                     register_id;
453
454
455	FUNCTION_TRACE ("Acpi_get_event_status");
456
457
458	if (!event_status) {
459		return_ACPI_STATUS (AE_BAD_PARAMETER);
460	}
461
462
463	/* The Type must be either Fixed Acpi_event or GPE */
464
465	switch (type) {
466
467	case ACPI_EVENT_FIXED:
468
469		/* Decode the Fixed Acpi_event */
470
471		switch (event) {
472		case ACPI_EVENT_PMTIMER:
473			register_id = TMR_STS;
474			break;
475
476		case ACPI_EVENT_GLOBAL:
477			register_id = GBL_STS;
478			break;
479
480		case ACPI_EVENT_POWER_BUTTON:
481			register_id = PWRBTN_STS;
482			break;
483
484		case ACPI_EVENT_SLEEP_BUTTON:
485			register_id = SLPBTN_STS;
486			break;
487
488		case ACPI_EVENT_RTC:
489			register_id = RTC_STS;
490			break;
491
492		default:
493			return_ACPI_STATUS (AE_BAD_PARAMETER);
494			break;
495		}
496
497		/* Get the status of the requested fixed event */
498
499		*event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id);
500		break;
501
502
503	case ACPI_EVENT_GPE:
504
505		/* Ensure that we have a valid GPE number */
506
507		if ((event > ACPI_GPE_MAX) ||
508			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
509			return_ACPI_STATUS (AE_BAD_PARAMETER);
510		}
511
512
513		/* Obtain status on the requested GPE number */
514
515		acpi_hw_get_gpe_status (event, event_status);
516		break;
517
518
519	default:
520		status = AE_BAD_PARAMETER;
521	}
522
523	return_ACPI_STATUS (status);
524}
525
526