26 #include <linux/kernel.h>
27 #include <linux/module.h>
29 #include <linux/types.h>
32 #include <linux/input.h>
33 #include <linux/slab.h>
37 #define PREFIX "ACPI: "
39 #define ACPI_BUTTON_CLASS "button"
40 #define ACPI_BUTTON_FILE_INFO "info"
41 #define ACPI_BUTTON_FILE_STATE "state"
42 #define ACPI_BUTTON_TYPE_UNKNOWN 0x00
43 #define ACPI_BUTTON_NOTIFY_STATUS 0x80
45 #define ACPI_BUTTON_SUBCLASS_POWER "power"
46 #define ACPI_BUTTON_HID_POWER "PNP0C0C"
47 #define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
48 #define ACPI_BUTTON_TYPE_POWER 0x01
50 #define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
51 #define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
52 #define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
53 #define ACPI_BUTTON_TYPE_SLEEP 0x03
55 #define ACPI_BUTTON_SUBCLASS_LID "lid"
56 #define ACPI_BUTTON_HID_LID "PNP0C0D"
57 #define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
58 #define ACPI_BUTTON_TYPE_LID 0x05
60 #define _COMPONENT ACPI_BUTTON_COMPONENT
77 static int acpi_button_add(
struct acpi_device *
device);
78 static int acpi_button_remove(
struct acpi_device *
device,
int type);
79 static void acpi_button_notify(
struct acpi_device *
device,
u32 event);
81 #ifdef CONFIG_PM_SLEEP
82 static int acpi_button_resume(
struct device *
dev);
86 static struct acpi_driver acpi_button_driver = {
89 .ids = button_device_ids,
91 .add = acpi_button_add,
92 .remove = acpi_button_remove,
93 .notify = acpi_button_notify,
95 .drv.pm = &acpi_button_pm,
107 static struct acpi_device *lid_device;
116 static int acpi_button_state_seq_show(
struct seq_file *seq,
void *
offset)
120 unsigned long long state;
125 (state ?
"open" :
"closed"));
131 return single_open(file, acpi_button_state_seq_show, PDE(inode)->
data);
136 .open = acpi_button_state_open_fs,
142 static int acpi_button_add_fs(
struct acpi_device *device)
152 if (acpi_button_dir || acpi_lid_dir) {
159 if (!acpi_button_dir)
166 goto remove_button_dir;
170 acpi_device_dir(device) =
proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
171 if (!acpi_device_dir(device)) {
178 S_IRUGO, acpi_device_dir(device),
179 &acpi_button_state_fops, device);
191 acpi_device_dir(device) =
NULL;
199 static int acpi_button_remove_fs(
struct acpi_device *device)
201 struct acpi_button *button = acpi_driver_data(device);
207 acpi_device_dir(device));
210 acpi_device_dir(device) =
NULL;
235 unsigned long long state;
249 static int acpi_lid_send_state(
struct acpi_device *device)
251 struct acpi_button *button = acpi_driver_data(device);
252 unsigned long long state;
261 input_report_switch(button->
input,
SW_LID, !state);
262 input_sync(button->
input);
268 if (ret == NOTIFY_DONE)
271 if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
281 static void acpi_button_notify(
struct acpi_device *device,
u32 event)
283 struct acpi_button *button = acpi_driver_data(device);
284 struct input_dev *
input;
291 input = button->
input;
293 acpi_lid_send_state(device);
298 input_report_key(input, keycode, 1);
300 input_report_key(input, keycode, 0);
306 acpi_bus_generate_proc_event(device, event, ++button->
pushed);
310 "Unsupported event [0x%x]\n", event));
315 #ifdef CONFIG_PM_SLEEP
316 static int acpi_button_resume(
struct device *
dev)
318 struct acpi_device *device = to_acpi_device(dev);
319 struct acpi_button *button = acpi_driver_data(device);
322 return acpi_lid_send_state(device);
327 static int acpi_button_add(
struct acpi_device *device)
330 struct input_dev *
input;
339 device->driver_data =
button;
341 button->
input = input = input_allocate_device();
344 goto err_free_button;
347 name = acpi_device_name(device);
348 class = acpi_device_class(device);
373 error = acpi_button_add_fs(device);
380 input->phys = button->
phys;
382 input->id.product = button->
type;
383 input->dev.parent = &device->dev;
385 switch (button->
type) {
402 error = input_register_device(input);
406 acpi_lid_send_state(device);
414 if (device->wakeup.flags.valid) {
417 device->wakeup.gpe_number);
418 if (!device_may_wakeup(&device->dev)) {
428 acpi_button_remove_fs(device);
430 input_free_device(input);
436 static int acpi_button_remove(
struct acpi_device *device,
int type)
438 struct acpi_button *button = acpi_driver_data(device);
440 if (device->wakeup.flags.valid) {
442 device->wakeup.gpe_number);
447 acpi_button_remove_fs(device);
448 input_unregister_device(button->
input);