Skip to contentSkip to conversation

Eject button handling in quickstart driver

PATCH In review Rainer Koenig 3 participants 5 messages Mar 7, 2012 – Mar 8, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Eject button handling in quickstart driver

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
}
}

Matthew Garrett advised me that there is a quickstart driver in staging that was designed to handle the PNP0C32 devices. I had a look at it and it needed patching for my purpose because

- the driver only reports the pressed button on wakeup events, but in my case it should report the pressure of the "Optical Disc Drive Eject" button during runtime.
- The driver was generating character input events when I pressed the button during runtime, resulting in the funny question of the bash open if I want to see all possible completions.

So I made a minor change to this driver to handle my "ODDE" button event as I want it and to be minimal intrusive to the remaining functionality.

Of course this needs a small "daemon like skript" that polls the pressed_button file frequently and initiates the eject command if the button is pressed. This one (modified from the Sourceforge quickstart download) works:

#!/bin/bash
#
# Sample application launcher.
# Angelo Arrifano <[email protected]>
# http://quickstart.sourceforge.net
#
# Put this script on ~/.config/autostart.
#

# Add your button actions here
LAUNCH["ODDE"]="eject /dev/sr0"

# The sysfs file telling which button was pressed PRESSEDFILE="/sys/devices/platform/quickstart/pressed_button"

if [[ ! -e "$PRESSEDFILE" ]]; then
exit 1
fi

while (true) do
PRESSEDBUTTON="$(cat "$PRESSEDFILE")"
if [[ "$PRESSEDBUTTON" != "none" ]]; then
${LAUNCH[$PRESSEDBUTTON]};
echo -n "none" > "$PRESSEDFILE"
fi
sleep 1;
done

# End of script

---

drivers/staging/quickstart/quickstart.c 2012-03-07 14:50:36.000000000 +0100 renamed from drivers/staging/quickstart/quickstart.c 2012-03-07 14:32:37.000000000 +0100 +10 -4
@@ -223,10 +223,16 @@
        if (event == QUICKSTART_EVENT_WAKE)
                quickstart_data.pressed = quickstart->btn;
        else if (event == QUICKSTART_EVENT_RUNTIME) {
-               input_report_key(quickstart_input, quickstart->btn->id, 1);
-               input_sync(quickstart_input);
-               input_report_key(quickstart_input, quickstart->btn->id, 0);
-               input_sync(quickstart_input);
+                if (strncasecmp(quickstart->btn->name, "ODDE", 4) == 0) {
+                  /* ODDE is Optical Disc Drive Eject */
+                  quickstart_data.pressed = quickstart->btn;
+                }
+                else {
+                 input_report_key(quickstart_input, quickstart->btn->id, 1);
+                 input_sync(quickstart_input);
+                 input_report_key(quickstart_input, quickstart->btn->id, 0);
+                 input_sync(quickstart_input);
+                }
        }
        return;
 }
Signature · 19 lines
Dipl.-Inf. (FH) Rainer Koenig
Project Manager Linux Clients
Dept. PDG 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:[email protected]

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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#1 lore raw
Quoted 101 lines · Rainer Koenig

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 }
       }

Matthew Garrett advised me that there is a quickstart driver in staging that was designed to handle the PNP0C32 devices. I had a look at it and it needed patching for my purpose because

- the driver only reports the pressed button on wakeup events, but in my case it should report the pressure of the "Optical Disc Drive Eject" button during runtime.
- The driver was generating character input events when I pressed the button during runtime, resulting in the funny question of the bash open if I want to see all possible completions.

So I made a minor change to this driver to handle my "ODDE" button event as I want it and to be minimal intrusive to the remaining functionality.

Of course this needs a small "daemon like skript" that polls the pressed_button file frequently and initiates the eject command if the button is pressed. This one (modified from the Sourceforge quickstart download) works:

#!/bin/bash
#
# Sample application launcher.
# Angelo Arrifano <[email protected]>
# http://quickstart.sourceforge.net
#
# Put this script on ~/.config/autostart.
#

# Add your button actions here
LAUNCH["ODDE"]="eject /dev/sr0"

# The sysfs file telling which button was pressed PRESSEDFILE="/sys/devices/platform/quickstart/pressed_button"

if [[ ! -e "$PRESSEDFILE" ]]; then
       exit 1
fi

while (true) do
PRESSEDBUTTON="$(cat "$PRESSEDFILE")"
if [[ "$PRESSEDBUTTON" != "none" ]]; then
       ${LAUNCH[$PRESSEDBUTTON]};
       echo -n "none" > "$PRESSEDFILE"
fi
sleep 1;
done

# End of script

---

drivers/staging/quickstart/quickstart.c 2012-03-07 14:50:36.000000000 +0100 renamed from drivers/staging/quickstart/quickstart.c    2012-03-07 14:32:37.000000000 +0100 +3 -4
@@ -223,10 +223,16 @@
        if (event == QUICKSTART_EVENT_WAKE)
                quickstart_data.pressed = quickstart->btn;
        else if (event == QUICKSTART_EVENT_RUNTIME) {
-               input_report_key(quickstart_input, quickstart->btn->id, 1);
-               input_sync(quickstart_input);
-               input_report_key(quickstart_input, quickstart->btn->id, 0);
-               input_sync(quickstart_input);
+                if (strncasecmp(quickstart->btn->name, "ODDE", 4) == 0) {
+                  /* ODDE is Optical Disc Drive Eject */
+                  quickstart_data.pressed = quickstart->btn;

drivers/staging/quickstart/quickstart.c 2012-03-07 14:50:36.000000000 +0100 line 238

Quoted 10 lines
drivers/staging/quickstart/quickstart.c 2012-03-07 14:50:36.000000000 +0100 renamed from drivers/staging/quickstart/quickstart.c    2012-03-07 14:32:37.000000000 +0100 +7 -0
+                }
+                else {
+                 input_report_key(quickstart_input, quickstart->btn->id, 1);
+                 input_sync(quickstart_input);
+                 input_report_key(quickstart_input, quickstart->btn->id, 0);
+                 input_sync(quickstart_input);
+                }
        }
        return;
  }

I'm really not sure it's how this driver is supposed to work. From what I understand, it reads a keymap from ACPI, associate button strings to ids, and when a button is pressed, send the button id using an input device.
Currently raw id are sent to the input device. I think it may be a good idea to send "real" keycodes like KEY_EJECTCD for well known keys (using a kind of keymap).

Signature · 6 lines
Corentin Chary
http://xf.iksaif.net
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#2 lore raw
In reply to Rainer Koenig

drivers/staging/quickstart/quickstart.c 2012-03-07 14:50:36.000000000 +0100 line 229

Quoted 4 lines · Rainer Koenig
drivers/staging/quickstart/quickstart.c 2012-03-07 14:50:36.000000000 +0100 renamed from drivers/staging/quickstart/quickstart.c 2012-03-07 14:32:37.000000000 +0100 +4 -0
+                if (strncasecmp(quickstart->btn->name, "ODDE", 4) == 0) {
+                  /* ODDE is Optical Disc Drive Eject */
+                  quickstart_data.pressed = quickstart->btn;
+                }

This is wrong. Since the GHID method returns an arbitrary vendor-specific value, you should just make sure that there's appropriate keymap remapping support and then provide a udev fragment that does the appropriate GHID->keycode assignment. Also, you really do need to report this as KEY_CDEJECT - it's not acceptable to require an acpid script.

Signature · 1 line
Matthew Garrett | [email protected]
#3 lore raw

Matthew,

Am 07.03.2012 16:21, schrieb Matthew Garrett:

Quoted 6 lines

This is wrong. Since the GHID method returns an arbitrary vendor-specific value, you should just make sure that there's appropriate keymap remapping support and then provide a udev fragment that does the appropriate GHID->keycode assignment. Also, you really do need to report this as KEY_CDEJECT - it's not acceptable to require an acpid script.

I had a look at the driver this morning. Just for testing purposes I changed it in a way that it sends KEY_EJECTCD codes over the input_report_key()-function, but this just works when I also have set the KEY_EJECTCD bit with set_bit() before.

This brings me to the point, how I need to set the bits in that array when the driver is loaded? Setting it with the "0x01" that the GHID method returns is of no use, on the other hand I can replace the keymap with /lib/udev/keymap, but that probably doesn't affect the bits in this array.

The easiest (and maybe possible because BIOS development is just around
the corner here) would be to change the ACPI code so that GHID returns the KEY_EJECTCD already, then it works out of the box, but the open question is if this change will lead do regressions in the already existing Windows driver.

Another idea: Making the quickstart driver aware of common HIDs like the ODDE in my case and creating a correct keymap during driver initalization. Then there is no need to remap GHID results to keycodes via /lib/udev/keymap. What do you think of this idea?

Regards
Rainer

Signature · 19 lines
Dipl.-Inf. (FH) Rainer Koenig
Project Manager Linux Business 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:[email protected]

Internet         ts.fujitsu.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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw
Quoted 4 lines · Rainer Koenig

I had a look at the driver this morning. Just for testing purposes I changed it in a way that it sends KEY_EJECTCD codes over the input_report_key()-function, but this just works when I also have set the KEY_EJECTCD bit with set_bit() before.

Yup.

Quoted 5 lines

This brings me to the point, how I need to set the bits in that array when the driver is loaded? Setting it with the "0x01" that the GHID method returns is of no use, on the other hand I can replace the keymap with /lib/udev/keymap, but that probably doesn't affect the bits in this array.

It'll affect the bits in those arrays if you have the appropriate keymap get and set functions in the driver. The mapping of GHID values to keycodes is vendor (and plausibly machine...) specific per spec, and the way we typically handle that is with keymaps.

Quoted 6 lines

The easiest (and maybe possible because BIOS development is just around the corner here) would be to change the ACPI code so that GHID returns the KEY_EJECTCD already, then it works out of the box, but the open
question is if this change will lead do regressions in the already existing Windows driver.

Right, you'd need to update the registry entries in Windows.

Quoted 5 lines

Another idea: Making the quickstart driver aware of common HIDs like the ODDE in my case and creating a correct keymap during driver initalization. Then there is no need to remap GHID results to keycodes
via /lib/udev/keymap. What do you think of this idea?

ODDE isn't a HID, it's just a device name. There's no vendor namespacing, and on some hardware it'll change between BIOS versions.

Signature · 1 line
Matthew Garrett | [email protected]