1 /*****************************************************************************
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 Andrew Grover
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.
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.
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 Plxxe, Suite 330, Boston, MA 02111-1307 USA
28 #define _COMPONENT ACPI_BUTTON
32 static struct proc_dir_entry
*bn_proc_root
= NULL
;
35 /*****************************************************************************
37 *****************************************************************************/
39 /*****************************************************************************
47 * DESCRIPTION: Prints out information on a specific button.
49 ****************************************************************************/
63 switch (button
->type
) {
65 case BN_TYPE_POWER_BUTTON
:
66 case BN_TYPE_POWER_BUTTON_FIXED
:
67 acpi_os_printf("Power Button: found\n");
70 case BN_TYPE_SLEEP_BUTTON
:
71 case BN_TYPE_SLEEP_BUTTON_FIXED
:
72 acpi_os_printf("Sleep Button: found\n");
75 case BN_TYPE_LID_SWITCH
:
76 acpi_os_printf("Lid Switch: found\n");
82 buffer
.pointer
= acpi_os_callocate(buffer
.length
);
83 if (!buffer
.pointer
) {
88 * Get the full pathname for this ACPI object.
90 acpi_get_name(button
->acpi_handle
, ACPI_FULL_PATHNAME
, &buffer
);
93 * Print out basic button information.
95 DEBUG_PRINT(ACPI_INFO
, ("+------------------------------------------------------------\n"));
97 switch (button
->type
) {
99 case BN_TYPE_POWER_BUTTON
:
100 case BN_TYPE_POWER_BUTTON_FIXED
:
101 DEBUG_PRINT(ACPI_INFO
, ("| PowerButton[0x%02x]|[%p] %s\n", button
->device_handle
, button
->acpi_handle
, buffer
.pointer
));
104 case BN_TYPE_SLEEP_BUTTON
:
105 case BN_TYPE_SLEEP_BUTTON_FIXED
:
106 DEBUG_PRINT(ACPI_INFO
, ("| SleepButton[0x%02x]|[%p] %s\n", button
->device_handle
, button
->acpi_handle
, buffer
.pointer
));
109 case BN_TYPE_LID_SWITCH
:
110 DEBUG_PRINT(ACPI_INFO
, ("| LidSwitch[0x%02x]|[%p] %s\n", button
->device_handle
, button
->acpi_handle
, buffer
.pointer
));
114 DEBUG_PRINT(ACPI_INFO
, ("+------------------------------------------------------------\n"));
116 acpi_os_free(buffer
.pointer
);
117 #endif /*ACPI_DEBUG*/
123 /****************************************************************************
125 * FUNCTION: bn_add_device
133 ****************************************************************************/
137 BM_HANDLE device_handle
,
140 ACPI_STATUS status
= AE_OK
;
141 BM_DEVICE
*device
= NULL
;
142 BN_CONTEXT
*button
= NULL
;
144 FUNCTION_TRACE("bn_add_device");
146 DEBUG_PRINT(ACPI_INFO
, ("Adding button device [0x%02x].\n", device_handle
));
148 if (!context
|| *context
) {
149 DEBUG_PRINT(ACPI_ERROR
, ("Invalid context.\n"));
150 return_ACPI_STATUS(AE_BAD_PARAMETER
);
154 * Get information on this device.
156 status
= bm_get_device_info( device_handle
, &device
);
157 if (ACPI_FAILURE(status
)) {
158 return_ACPI_STATUS(status
);
162 * Allocate a new BN_CONTEXT structure.
164 button
= acpi_os_callocate(sizeof(BN_CONTEXT
));
166 return_ACPI_STATUS(AE_NO_MEMORY
);
169 button
->device_handle
= device
->handle
;
170 button
->acpi_handle
= device
->acpi_handle
;
175 * Either fixed-feature or generic (namespace) types.
177 if (strncmp(device
->id
.hid
, BN_HID_POWER_BUTTON
,
178 sizeof(BM_DEVICE_HID
)) == 0) {
180 if (device
->id
.type
== BM_TYPE_FIXED_BUTTON
) {
182 button
->type
= BN_TYPE_POWER_BUTTON_FIXED
;
184 /* Register for fixed-feature events. */
185 status
= acpi_install_fixed_event_handler(
186 ACPI_EVENT_POWER_BUTTON
, bn_notify_fixed
,
190 button
->type
= BN_TYPE_POWER_BUTTON
;
193 //proc_mkdir(BN_PROC_POWER_BUTTON, bn_proc_root);
200 * Either fixed-feature or generic (namespace) types.
202 else if (strncmp( device
->id
.hid
, BN_HID_SLEEP_BUTTON
,
203 sizeof(BM_DEVICE_HID
)) == 0) {
205 if (device
->id
.type
== BM_TYPE_FIXED_BUTTON
) {
207 button
->type
= BN_TYPE_SLEEP_BUTTON_FIXED
;
209 /* Register for fixed-feature events. */
210 status
= acpi_install_fixed_event_handler(
211 ACPI_EVENT_SLEEP_BUTTON
, bn_notify_fixed
,
215 button
->type
= BN_TYPE_SLEEP_BUTTON
;
218 //proc_mkdir(BN_PROC_SLEEP_BUTTON, bn_proc_root);
225 else if (strncmp( device
->id
.hid
, BN_HID_LID_SWITCH
,
226 sizeof(BM_DEVICE_HID
)) == 0) {
228 button
->type
= BN_TYPE_LID_SWITCH
;
230 //proc_mkdir(BN_PROC_LID_SWITCH, bn_proc_root);
237 return_ACPI_STATUS(status
);
241 /****************************************************************************
243 * FUNCTION: bn_remove_device
251 ****************************************************************************/
257 ACPI_STATUS status
= AE_OK
;
258 BN_CONTEXT
*button
= NULL
;
260 FUNCTION_TRACE("bn_remove_device");
262 if (!context
|| !*context
) {
263 return_ACPI_STATUS(AE_BAD_PARAMETER
);
266 button
= (BN_CONTEXT
*)*context
;
268 DEBUG_PRINT(ACPI_INFO
, ("Removing button device [0x%02x].\n", button
->device_handle
));
271 * Remove the /proc entry for this button.
273 switch (button
->type
) {
275 case BN_TYPE_POWER_BUTTON
:
276 case BN_TYPE_POWER_BUTTON_FIXED
:
277 /* Unregister for fixed-feature events. */
278 status
= acpi_remove_fixed_event_handler(
279 ACPI_EVENT_POWER_BUTTON
, bn_notify_fixed
);
280 //remove_proc_entry(BN_PROC_POWER_BUTTON, bn_proc_root);
283 case BN_TYPE_SLEEP_BUTTON
:
284 case BN_TYPE_SLEEP_BUTTON_FIXED
:
285 /* Unregister for fixed-feature events. */
286 status
= acpi_remove_fixed_event_handler(
287 ACPI_EVENT_SLEEP_BUTTON
, bn_notify_fixed
);
288 //remove_proc_entry(BN_PROC_SLEEP_BUTTON, bn_proc_root);
291 case BN_TYPE_LID_SWITCH
:
292 //remove_proc_entry(BN_PROC_LID_SWITCH, bn_proc_root);
296 acpi_os_free(button
);
300 return_ACPI_STATUS(status
);
304 /*****************************************************************************
306 *****************************************************************************/
308 /*****************************************************************************
310 * FUNCTION: bn_initialize
319 ****************************************************************************/
324 ACPI_STATUS status
= AE_OK
;
325 BM_DEVICE_ID criteria
;
328 FUNCTION_TRACE("bn_initialize");
330 MEMSET(&criteria
, 0, sizeof(BM_DEVICE_ID
));
331 MEMSET(&driver
, 0, sizeof(BM_DRIVER
));
333 driver
.notify
= &bn_notify
;
334 driver
.request
= &bn_request
;
337 * Create button's root /proc entry.
339 //bn_proc_root = proc_mkdir(BN_PROC_ROOT, bm_proc_root);
340 //if (!bn_proc_root) {
341 // return_ACPI_STATUS(AE_ERROR);
345 * Register for power buttons.
347 MEMCPY(criteria
.hid
, BN_HID_POWER_BUTTON
, sizeof(BN_HID_POWER_BUTTON
));
348 status
= bm_register_driver(&criteria
, &driver
);
351 * Register for sleep buttons.
353 MEMCPY(criteria
.hid
, BN_HID_SLEEP_BUTTON
, sizeof(BN_HID_SLEEP_BUTTON
));
354 status
= bm_register_driver(&criteria
, &driver
);
357 * Register for LID switches.
359 MEMCPY(criteria
.hid
, BN_HID_LID_SWITCH
, sizeof(BN_HID_LID_SWITCH
));
360 status
= bm_register_driver(&criteria
, &driver
);
362 if (status
== AE_NOT_FOUND
)
365 return_ACPI_STATUS(status
);
369 /****************************************************************************
371 * FUNCTION: bn_terminate
379 ****************************************************************************/
384 ACPI_STATUS status
= AE_OK
;
385 BM_DEVICE_ID criteria
;
388 FUNCTION_TRACE("bn_terminate");
390 MEMSET(&criteria
, 0, sizeof(BM_DEVICE_ID
));
391 MEMSET(&driver
, 0, sizeof(BM_DRIVER
));
393 driver
.notify
= &bn_notify
;
394 driver
.request
= &bn_request
;
397 * Unregister for power buttons.
399 MEMCPY(criteria
.hid
, BN_HID_POWER_BUTTON
, sizeof(BN_HID_POWER_BUTTON
));
400 status
= bm_unregister_driver(&criteria
, &driver
);
403 * Unregister for sleep buttons.
405 MEMCPY(criteria
.hid
, BN_HID_SLEEP_BUTTON
, sizeof(BN_HID_SLEEP_BUTTON
));
406 status
= bm_unregister_driver(&criteria
, &driver
);
409 * Unregister for LID switches.
411 MEMCPY(criteria
.hid
, BN_HID_LID_SWITCH
, sizeof(BN_HID_LID_SWITCH
));
412 status
= bm_unregister_driver(&criteria
, &driver
);
415 * Remove button's root /proc entry.
418 //remove_proc_entry(BN_PROC_ROOT, bm_proc_root);
421 return_ACPI_STATUS(status
);
425 /****************************************************************************
427 * FUNCTION: bn_notify_fixed
435 ****************************************************************************/
441 ACPI_STATUS status
= AE_OK
;
442 BN_CONTEXT
*button
= NULL
;
444 FUNCTION_TRACE("bn_notify_fixed");
447 return_ACPI_STATUS(AE_BAD_PARAMETER
);
450 button
= (BN_CONTEXT
*)context
;
452 DbgPrint("Fixed button status change event detected.\n");
454 switch (button
->type
) {
456 case BN_TYPE_POWER_BUTTON_FIXED
:
457 DEBUG_PRINT(ACPI_INFO
, ("Fixed-feature button status change event detected.\n"));
458 /*bm_generate_event(button->device_handle, BN_PROC_ROOT,
459 BN_PROC_POWER_BUTTON, BN_NOTIFY_STATUS_CHANGE, 0);*/
462 case BN_TYPE_SLEEP_BUTTON_FIXED
:
463 DEBUG_PRINT(ACPI_INFO
, ("Fixed-feature button status change event detected.\n"));
464 /*bm_generate_event(button->device_handle, BN_PROC_ROOT,
465 BN_PROC_SLEEP_BUTTON, BN_NOTIFY_STATUS_CHANGE, 0);*/
469 DEBUG_PRINT(ACPI_INFO
, ("Unsupported fixed-feature event detected.\n"));
474 return_ACPI_STATUS(status
);
478 /****************************************************************************
480 * FUNCTION: bn_notify
488 ****************************************************************************/
492 BM_NOTIFY notify_type
,
493 BM_HANDLE device_handle
,
496 ACPI_STATUS status
= AE_OK
;
498 FUNCTION_TRACE("bn_notify");
501 return_ACPI_STATUS(AE_BAD_PARAMETER
);
504 switch (notify_type
) {
505 case BM_NOTIFY_DEVICE_ADDED
:
506 status
= bn_add_device(device_handle
, context
);
509 case BM_NOTIFY_DEVICE_REMOVED
:
510 status
= bn_remove_device(context
);
513 case BN_NOTIFY_STATUS_CHANGE
:
514 DEBUG_PRINT(ACPI_INFO
, ("Button status change event detected.\n"));
516 DbgPrint("Button status change event detected.\n");
518 if (!context
|| !*context
) {
519 return_ACPI_STATUS(AE_BAD_PARAMETER
);
522 switch(((BN_CONTEXT
*)*context
)->type
) {
524 case BN_TYPE_POWER_BUTTON
:
525 case BN_TYPE_POWER_BUTTON_FIXED
:
526 /*bm_generate_event(device_handle, BN_PROC_ROOT,
527 BN_PROC_POWER_BUTTON, notify_type, 0);*/
530 case BN_TYPE_SLEEP_BUTTON
:
531 case BN_TYPE_SLEEP_BUTTON_FIXED
:
532 /*bm_generate_event(device_handle, BN_PROC_ROOT,
533 BN_PROC_SLEEP_BUTTON, notify_type, 0);*/
536 case BN_TYPE_LID_SWITCH
:
537 /*bm_generate_event(device_handle, BN_PROC_ROOT,
538 BN_PROC_LID_SWITCH, notify_type, 0);*/
553 return_ACPI_STATUS(status
);
557 /****************************************************************************
559 * FUNCTION: bn_request
567 ****************************************************************************/
574 ACPI_STATUS status
= AE_OK
;
576 FUNCTION_TRACE("bn_request");
579 * Must have a valid request structure and context.
581 if (!request
|| !context
) {
582 return_ACPI_STATUS(AE_BAD_PARAMETER
);
589 switch (request
->command
) {
596 request
->status
= status
;
598 return_ACPI_STATUS(status
);