Special Keys

Getting the various special keys like "Access IBM", Mute etc. and the Fn-key combinations recognized is pretty easy. For an overview of the possibilities and more in-depth information see this ThinkWiki page.

Three software packages are needed:

You can install acpid and tpb with

apt-get install acpid tpb

ibm-acpi

Note: Version 2.6.14 of the Linux kernel has the most recent version of the ibm-acpi module include, so all you need to do is enable it in "Power management options (ACPI, APM)" -> "ACPI (Advanced Configuration and Power Interface) Support" -> "IBM ThinkPad Laptop Extras", preferably as module so you can pass it options at via modprobe. And don't enable "Generic Hotkey (EXPERIMENTAL)" in the same menu since it seems to conflict with the Thinkpad Extras in some way.

The ibm-acpi kernel module is part of the standard Linux kernel since version 2.6.10, but it's not the most recent version. To replace it with the newest version (at the time of writing 0.11, the upcoming kernel 2.6.14 will include 0.12a), it must be compiled as a module (CONFIG_ACPI_IBM=m; if you're using my kernel configuration file you're fine, otherwise search for "IBM Thinkpad Laptop Extras" in the kernel configuration). Download the compressed archive and then issue

tar -xzf ibm-acpi-0.11.tar.gz
cd ibm-acpi-0.11
make
make install

to install the new module. After that either reboot (the new module should get loaded automatically by the hotplug subsystem) or try

rmmod ibm_acpi
modprobe ibm_acpi

Make sure you're running the correct version, either by search the kernel message buffer with

dmesg | grep ibm_acpi

or by checking in the proc filesystem with

cat /proc/acpi/ibm/driver

To enable the hotkeys you have to echo some values into the proc filesystem:

echo enable > /proc/acpi/ibm/hotkey
echo 0xffef > /proc/acpi/ibm/hotkey

The first line basically enables the hotkey feature, the second selects all available key combinations apart from Fn+F5 (which toggles the bluetooth adapter on and off) to send ACPI events. See the ibm-acpi README file for details, also for the various other interesting files in that directory.

Since you probably don't want to do that everytime after the modules gets loaded, it's probably a good idea to put these module parameters into the /etc/modprobe.d/ directory, in my case I wrote a file called /etc/modprobe.d/ibm-acpi containing

options ibm_acpi experimental=1 hotkey=enable,0xffef

acpid

The next step is to configure acpid for the ACPI events sent by pressing the special keys and tell it what command to run. The name of the events all start with "ibm/", hence I wrote a file called /etc/acpi/events/ibm-acpi with the following content:

event=ibm/
action=/etc/acpi/actions/ibm.sh "%e"

The action line calls a script and passes the event name as first and only argument. The /etc/acpi/actions/ibm-acpi.sh is a simple shell script and looks like this:

#!/bin/bash
case "$1" in
# Fn+F12
"ibm/hotkey HKEY 00000080 0000100c")
/usr/sbin/hibernate
;;
# Fn+F4
"ibm/hotkey HKEY 00000080 00001004")
/usr/sbin/hibernate -F /etc/hibernate/hibernate.conf.ram
;;
# Fn+F6
"ibm/hotkey HKEY 00000080 00001006")
/root/bin/toggle_wlan
;;
# Fn+F8
"ibm/hotkey HKEY 00000080 00001008")
/root/bin/toggle_irda
;;
# Fn+F3
"ibm/hotkey HKEY 00000080 00001003")
/root/bin/toggle_backlight
;;
# log everything else to syslog
*)
/usr/bin/logger -i -t "IBM Special Button" $1
;;
esac

For a couple of events commands are run, the rest get logged to the syslog daemon. All Thinkpad's ACPI event names and their corresponding keys are listed on the above mentioned ThinkWiki page. The toggle_wlan and toggle_backlight scripts are attached in their current version if someone's interested, they'll be explained in more detail once I write the pages for the network and graphics card sections. The toggle_irda script is explained on the Infrared page. The hibernate script is part of Software Suspend 2.

Be sure to notify acpid about changes in files in /etc/acpi by issuing

/etc/init.d/acpid reload

tpb

The last part is to configure tpb. This is easy, because the most important functions work right away, namely the volume-up/down and mute buttons, the thinklight and the brightness control. The latter two work even without tpb, probably it's hardwired in the hardware, but tpb adds a nice on screen display.

The configuration file is /etc/tpbrc. Two things I changed from the defaults:

  • setting XEVENTS to OFF results in tpb not grabbing the Fn-key and the forward/backward-keys next to the cursor keys, because I'd like them to send normal keycodes. Try the 'xev' command to actually see the keycodes.
  • CALLBACK /etc/tpb_callback.sh tells tpb to run that script for the various events in recognizes.

I copied the example script from /usr/share/doc/tpb/callback_example.sh to that location and started editing. First I substituted all occurences of "echo" with "/usr/bin/logger -i -t tpb" to log all actions to the syslog daemon. The only action that I really defined is the one for the zoom-event (when pressing Fn and the space bar), because I wanted to use xzoom (apt-get install xzoom if you haven't guessed it by now) to get a zooming feature for X. That part of the callback script looks now like this:

  (zoom)
case $2 in
(on)
/usr/bin/X11/xzoom
;;
(off)
killall xzoom
;;
esac
;;

BTW, since tpb is run from the startup files of the X Window System, all commands run by the user running X, whereas the commands run from acpid are run with root privileges.

AttachmentSize
Binary Data toggle_backlight426 bytes
Binary Data toggle_wlan623 bytes

Sections:

Comments

Anonymous's picture

very nice page. I'd love to find a good collection of ibm-acpi scripts. for instance I now see there is a brightness pseudo file in the /proc/acpi/ibm dir and would like to use it to set brightness on AC or battery

thank you

Wolfgang Karall-Ahlborn's picture

just put a file in /etc/acpi/events for the battery and ac_adapter ACPI events (if you have laptop-mode-tools installed you can add the action lines to the two files already there called lm_ac_adapter and lm_battery):

event=battery.*
action=/etc/acpi/actions/brightness.sh battery

event=ac_adapter
action=/etc/acpi/actions/brightness.sh ac

and then put into /etc/acpi/actions/brightness.sh something like:

#!/bin/bash

# levels are from 0 (very dark) to 7 (very bright)
BATT_LEVEL=0
AC_LEVEL=7

case "$1" in
        battery)
                echo "level $BATT_LEVEL" > /proc/acpi/ibm/brightness
                ;;
        ac)
                echo "level $AC_LEVEL" > /proc/acpi/ibm/brightness
                ;;
esac
Anonymous's picture

I am using the 2.6.16-r9 patched with Suspend2 sources, OSD stops working after suspend/resume. Running the 'watch' command on /dev/nvram does not seem to change.

Only way to get it working is doing a system restart. Loading/Unloading nvram doesnt help either.