The most merciful thing in the world is the inability of the human mind to correlate all its contents.
H. P. Lovecraft
Helping the environment

A lot of work is done in making linux suspend work better. For me it works perfect (from linux kernel 2.6.20 or so). Therefore I wanted to go a step further and let my class A, heavy power-using receiver switch off when my desktop computer suspends (to ram). And switch back on when my computer wakes up. The motivation is that I only listen music via my computer.

To achieve this I bought the Gembird Silver Shield, a USB-switchable power adapter. I was prepared to do some nice USB snooping and C programming to get this device working in linux, but (un)fortunately there was already a working utility for this device.

Configuration for suspend/hibernate is not so easy and documentation is sparse for the user mode utilities. Since it took me more than the usual googling I will summarize my conclusions here for later use. First the gnome-screensaver measures the idle time. After this timeout is expired the gnome-power-manager starts to measure his own timeout (so before suspend the two times will stack). When the gnome-power-manager times out it will look at the Inhibit flag. If there is no inhibiting (for example my rhythmbox pushes Inhibiting, because I do not want to suspend when music is playing) your computer will suspend.

Since a custom script should be added to switch the power-switch off via usb with sispmctl the suspend-backend is important. Gnome power manager can use multiple backends to go to suspend mode. This works via hal (the hardware abstraction layer). Configuration for this is in /usr/share/hal/information. HAL is responsible for calling the suspend-backend. The default suspend-backend on my machine is pm-utils. (which can be tested with pm-(suspend/hibernate/power-save etc.). I also have a package called hibernate (which can also suspend, confusing isnt' it?). A third one is suspend2 (which can also hibernate....). These backends have different ways of adding custom hooks.

To add a hook to hibernate I added a file called local in /etc/hibernate/scriptlets.d/. The API is as follows (ugly in my book):

# -*- sh -*-

UsbPowerSocketDown() {
      /usr/bin/sispmctl -f1
}
UsbPowerSocketUp() {
      /usr/bin/sispmctl -o1
}

AddUsbOptions() {
      AddSuspendHook 10 UsbPowerSocketDown
      AddResumeHook 10 UsbPowerSocketUp
      return 0
}

AddUsbOptions

Pm-utils has a much nicer API. To add a custom hook add a file to /etc/pm/sleep.d . This uses init style ordering. So look in /usr/lib/pm-utils/sleep.d/ for a proper number. I needed to talk to the usb-bus AFTER the modules were loaded, so a number lower than 50. So I added /etc/pm/sleep.d/10usbpoweroptions with content like this:

#!/bin/bash
case $1 in
    suspend)
        /usr/bin/sispmctl -f1 
    ;;
    resume)
        sleep 1
        /usr/bin/sispmctl -o1 
    ;;
esac

After all this fiddling it works like a charm! Now hopefully one standard will emerge; because how to achieve the same result with KDE I don't know. I had to manually patch rhythmbox to change calling (via dbus) the Inhibit method from org.gnome.powermanager to org.freedesktop.powermanagement (because i used a wrong combination of versions..), so this suggests a move in the right direction.

-- Filed under:

Posted by jochem on 2nd February 2008, last update on 3rd February 2008