[Patch] Eject button for button driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Background: Fujitsu is releasing currently small desktop systems like the
ESPRIMO Q510 that have no direct accessible eject button for the optical drive.

http://www.fujitsu.com/fts/products/computing/pc/desktops/all-round/esprimo-q510/index.html

Instead of an eject button on the drive the system has a button on the
mainboard that will send a notify event to the assigned device using the
following ACPI code:

Scope(\_GPE)
{
        Method(_L15, 0)                                         // ODD Eject GPIO handler
        {
                 Notify(\_SB.ODDE, 0x80)                         // Notify a ODD Eject Button event
to the OS
        }
} //Scope(\_GPE)

Scope(\_SB)
{
//
// Direct Application Launch Button definition used for Windows Vista, Windows 7, Linux ...
//
        Device(ODDE)                                            // Eject Button Device
        {
                Name(_HID, EISAID("PNP0C32"))   // HID ACPI button device
                Name(_UID, 1)                                   // Unique instance # of that device
                Name(_STA, 0x0F)                                // Device is working properly

                Method(GHID, 0)                                 // Button "role" method
                {
                        Return(Buffer(){1})                 // Application Launch Button role
                }
        }

To implement this I modified the button.c driver by adding the eject button code.
During testing it came out, that the button is constantly firing GPE15 events as
long at is pressed, so I added some code that only handles one event per second
and drops the other events.

To make the eject function work the user also needs to add a rule to acpid that
triggers the eject command on the eject event.

Signed-off-by: Rainer Koenig <Rainer.Koenig@xxxxxxxxxxxxxx>

---

--- upstream/drivers/acpi/button.c      2012-03-06 10:12:04.000000000 +0100
+++ new/drivers/acpi/button.c   2012-03-06 10:25:23.000000000 +0100
@@ -31,6 +31,7 @@
 #include <linux/seq_file.h>
 #include <linux/input.h>
 #include <linux/slab.h>
+#include <linux/jiffies.h>  /* for accepting only on eject event per second */
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>

@@ -57,6 +58,11 @@
 #define ACPI_BUTTON_DEVICE_NAME_LID    "Lid Switch"
 #define ACPI_BUTTON_TYPE_LID           0x05

+#define ACPI_BUTTON_SUBCLASS_EJECT      "eject"
+#define ACPI_BUTTON_HID_EJECT           "PNP0C32"
+#define ACPI_BUTTON_DEVICE_NAME_EJECT   "Eject Button"
+#define ACPI_BUTTON_TYPE_EJECT          0x07
+
 #define _COMPONENT             ACPI_BUTTON_COMPONENT
 ACPI_MODULE_NAME("button");

@@ -70,6 +76,7 @@
        {ACPI_BUTTON_HID_SLEEPF, 0},
        {ACPI_BUTTON_HID_POWER,  0},
        {ACPI_BUTTON_HID_POWERF, 0},
+        {ACPI_BUTTON_HID_EJECT,  0},
        {"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, button_device_ids);
@@ -102,6 +109,8 @@
 static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;

+static unsigned long eject_expire; /* when do the eject jiffies expire? */
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
@@ -287,6 +296,16 @@
                input = button->input;
                if (button->type == ACPI_BUTTON_TYPE_LID) {
                        acpi_lid_send_state(device);
+                        acpi_bus_generate_proc_event(device, event, ++button->pushed);
+                } else if (button->type == ACPI_BUTTON_TYPE_EJECT) {
+                        if (time_is_before_jiffies(eject_expire)) {
+                          eject_expire = jiffies+HZ;  /* expire delay 1 second */
+                          input_report_key(input, KEY_EJECTCD, 1);
+                          input_sync(input);
+                          input_report_key(input, KEY_EJECTCD, 0);
+                          input_sync(input);
+                          acpi_bus_generate_proc_event(device, event, ++button->pushed);
+                  }
                } else {
                        int keycode = test_bit(KEY_SLEEP, input->keybit) ?
                                                KEY_SLEEP : KEY_POWER;
@@ -295,11 +314,9 @@
                        input_sync(input);
                        input_report_key(input, keycode, 0);
                        input_sync(input);
-
+                        acpi_bus_generate_proc_event(device, event, ++button->pushed);
                        pm_wakeup_event(&device->dev, 0);
                }
-
-               acpi_bus_generate_proc_event(device, event, ++button->pushed);
                break;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -357,6 +374,12 @@
                strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
                sprintf(class, "%s/%s",
                        ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
+        } else if (!strcmp(hid, ACPI_BUTTON_HID_EJECT)) {
+                button->type = ACPI_BUTTON_TYPE_EJECT;
+                strcpy(name, ACPI_BUTTON_DEVICE_NAME_EJECT);
+                sprintf(class, "%s/%s",
+                        ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_EJECT);
+                eject_expire = jiffies; /* initial value for the eject delay */
        } else {
                printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
                error = -ENODEV;
@@ -390,6 +413,10 @@
                input->evbit[0] = BIT_MASK(EV_SW);
                set_bit(SW_LID, input->swbit);
                break;
+        case ACPI_BUTTON_TYPE_EJECT:
+                input->evbit[0] = BIT_MASK(EV_KEY);
+                set_bit(KEY_EJECTCD, input->keybit);
+                break;
        }

        error = input_register_device(input);

-- 
Dipl.-Inf. (FH) Rainer Koenig
Project Manager Linux Clients
Dept. TSP WPS R&D SW OSE

Fujitsu Technology Solutions
Bürgermeister-Ullrich-Str. 100
86199 Augsburg
Germany

Telephone: +49-821-804-3321
Telefax:   +49-821-804-2131
Mail:      mailto:Rainer.Koenig@xxxxxxxxxxxxxx

Internet         ts.fujtsu.com
Company Details  ts.fujitsu.com/imprint.html
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux