24.01.2011

Power saving for the win!

Update 2: I've released a new version of the package that fixes numerous bugs and brings new features. Since updating requires some special care, it's best to check out the new article on this before trying to do anything manually.

Update: Apparently the startup script doesn't work correctly yet. Upon system boot, the governor is set to performance, probably after my script set it to ondemand or powersave. I'm currently looking into this and will release an update as soon as possible. Until then, You can either set the governor manually after logging in, You can remove my package, or You can turn the ondemand init-script back on:
Code:
update-rc.d ondemand enable
The latter method will set the governor to ondemand on system startup. This is not as good as powersave if You're running on battery, but it's still better than performance.


I'm happy to announce the second package in my PPA! cpufreq has joined the ranks of tablet-mode and is ready to be downloaded!

It's basically nothing else than a packaged version of my article on CPU governors and the power supply status. It has a few more checks (if certain nodes on the sys filesystem exist) and now also displays a list of available frequencies. If You want to increase the running time of Your laptop on battery, I recommend You get it while it's hot!

As of now, the package requires absolutely no configuration (as long as some things on Your system work the same way they do on mine) and if You should encounter any problems, just drop by, leave a comment or write me a mail. I'll try to fix it as soon as possible.

To install it, add the PPA to Your APT sources and update Your package list (as described here). After that, install it via synaptic or the console:
Code:
apt-get install cpufreq

Congratulations! You can now pull the plug and Your system automatically changes to the powersave governor! In addition, You can use cpufreq to change the governor manually on the command line (see the man page for details).

That's it! You're done!

17.01.2011

2 new packages to come!

Here's a small announcement:
I will probably create a package for automatic CPU frequency scaling based on my article here. From what I read in the forums where this blog was posted, there are many people (especially those new to Ubuntu) who have problems or difficulties setting up and installing scripts. The package will thus contain the script, the ACPI handler and the upstart job. This is nothing more and nothing less than I already posted in the article, but will of course be much easier to install and update. I hope the package will be useful for many people and I would be very happy about any feedback on this topic (there are visitor statistics available for me concerning the blog, but unfortunately there's no download counter for my PPA).
Another package I'm currently working on is based on the post about switchable graphics. It will contain a small graphical (also usable without a GUI) program which is able to switch the graphics card between the integrated (less power consuming) Intel card and the discrete (more powerful) ATI card. It will of course still restart the X server upon changing the card as there is currently no way to circumvent this. Personally I have little use for such a program (as I don't really need the graphical power of the ATI card in Linux), but I think it might be come in handy once in a while and may be even more useful for other people. As for the first announced package, I would be very happy about any feedback concerning this.

09.12.2010

Update to tablet-mode

Update: I've released yet another version of the package. It fixes the same bug as described below again (but now it really works! ;) ). The problem was a variable substitution in the Tcl "switch" statement (and some other flaws that I somehow didn't notice before). Version 1.4.0 is available via my Launchpad PPA and can be downloaded by the usual means.


I've released a new version of my tablet-mode package (see my article on my PPA if You don't know what I'm talking about).
Yesterday I wanted to use my notebook as a tablet and noticed that the touch function was not turned off as it was supposed to be. It turned out that the IDs of my Wacom devices (finger, stylus, eraser) had changed and were no longer the ones I had in my /etc/tablet-mode/tablet-mode.conf. Today I checked again and they were back to normal. Now to not have You change the values in the configuration file every now and then (and then have You change them back again shortly after), I changed the behavior of the script so that it does no longer require numeric IDs in the configuration but rather requires string identifiers like "Wacom ISDv4 E3 Pen stylus". It then looks up the corresponding numeric IDs by itself every time it is run.
Another problem that I fixed was that the script didn't even use the values from the configuration file at all. Due to a wrong variable name, the finger device always had the same numeric ID, no matter what You had in Your config file. The result was that when the device had another ID than 11 on Your system, the touch function was not turned off when entering tablet mode and the touch device was not rotated when rotating Your screen.
So, if You have the package installed, just update to the latest version and if not, You can safely install it :)

05.12.2010

Screen brightness

Changing the screen brightness can extend the battery life by a considerable amount, so this a quite important thing concerning laptops. Unfortunately, that functionality is broken. On my laptop with Ubuntu, I am unable to change the display brightness by the usual means. The buttons do create a reaction, but that reactions merely consists of the GNOME Power Manager displaying a notification with a bar that changes. Nothing happens to my display.
Additionally, every time I press one of the keys, that bar increases or decreases by two steps instead of one. So when I keep the button pressed for about 4-5 seconds, that notification keeps blinking for about 10-15 seconds before finally disappearing.
And now the good part: I found a solution :)
I managed to get the brightness keys working. I am able to change the brightness by an arbitrary amount upon a key press, yet so far I was unable to make that annoying notification disappear.
Thanks to some post in some forum (unfortunately I remember neither the author nor the forum), I got to know the location of a node on the /sys filesystem where the brightness can be changed by echoing numbers into it.
(Note: You need root access to write files in /etc/acpi/).
  1. Create a script to be executed upon pressing one of the brightness keys. Mine is named brightness.sh and is placed in /etc/acpi/.
    Code:
    #! /bin/bash

    # pressing the buttons generates 2 events, so we need to ignore one
    if [ "$2" != "LCD" ]
    then
        exit 0
    fi
    # get brightness
    CURRENT_BRIGHTNESS="$(sudo setpci -s 00:02.0 F4.B | tr "[a-z]" "[A-Z]")"
    # to upper case
    CURRENT_BRIGHTNESS="$(echo "$CURRENT_BRIGHTNESS" | tr "[a-z]" "[A-Z]")"
    # add/substract 16
    case "$3" in
        "00000086")
            OP="+"
            ;;
        "00000087")
            OP="-"
            ;;
        *)
            exit 0
    esac
    NEW_BRIGHTNESS="$(echo "obase=16;ibase=16;$CURRENT_BRIGHTNESS $OP 10" | bc)"
    # check boundaries
    if [ "$(echo "ibase=16; $NEW_BRIGHTNESS < F" | bc)" -eq 1 ] then     NEW_BRIGHTNESS="F" elif [ "$(echo "ibase=16; $NEW_BRIGHTNESS > FF" | bc)" -eq 1 ]
    then
        NEW_BRIGHTNESS="FF"
    fi
    # set brightness
    setpci -s 00:02.0 F4.B=$NEW_BRIGHTNESS
    The script changes the brightness in steps of 10. You can change this amount by changing the number in line 23 (NEW_BRIGHTNESS=...). The brightness is a number between 0 and 255 and is read and saved as a hexadecimal number (0 to FF).
  2. Make the script executable.
    Code:
    $ chmod +x /etc/acpi/brightness.sh
  3. Create an ACPI event handler to execute the script upon pressing one of the brightness keys. I called it brightness and placed it in /etc/acpi/events/.
    Code:
    # /etc/acpi/events/brightness
    # Calls /etc/acpi/brightness.sh to change screen brightness upon key press
    # Author: Frederik Möllers

    event=video
    action=/etc/acpi/brightness.sh %e
  4. Make acpid reload its configuration for the changes to take effect.
    Code:
    $ reload acpid

When pressing Your brightness keys, You display brightness should change now. The bar will still appear and display something wrong and will probably annoy You, but I haven't found out yet how to kill that thing. If it's not working, You can try to check wether the ACPI events are the correct ones (the script reacts on video LCD 00000086 00000000 and video LCD 00000087 00000000 - acpi_listen can tell You what events are generated by Your keys) and wether the call to setpci does the operation on the right card (lspci is Your friend, Your intel onBoard graphics card should have ID 00:02.0). If Your system has different values, just change them in the script and feel free to tell me so I can generalize the script and put a note on that here.

Warning: Never set Your brightness to 0! This is not only useless (You can't see anything because a value of 0 really means to completely turn off the light panel), but it will also kill Your system, forcing You to do a hard reset. You will be unable to change the brightness back to a positive number, even if You enter the correct command blindly. My script will not do this, but if You want to tinker around for Yourself, always keep this in mind!

That's it! You're done!

29.11.2010

Switchable graphics and power consumption

Update: The switch seems to work reliably for me now. I switched to the ATI card, restarted X, used it, switched back and restarted X again. The procedure worked without problems. If I find time I will probably write a small program to switch the graphics card similar to the one I wrote for screen rotation.

It is completed! Switchable graphics are supported by the Linux kernel!
The usage is pretty simple. You have 2 graphics cards installed in the system. Thus, You need drivers for both of them. For the tm2-1090eg this means You need to make sure that both the radeon and the intel module are loaded after You booted up Your laptop. If one of them does not appear in the output of lsmod, there's something wrong or You blacklisted is. How to cope with that is not covered in this guide.
Starting with some-kernel-version, there is a node in the sysfs, specifically in /sys/kernel/debug/, which is called vgaswitcheroo. This neat little thing gives us the possibility to switch the graphics adapter at runtime and also to turn off the idle one.
(As root) You can write different 3 values into the switch at /sys/kernel/debug/vgaswitcheroo/switch using:
Code:
$ echo <value> > /sys/kernel/debug/vgaswitcheroo/switch
The values are:
  1. OFF - This one is simple. It turns off the video adapter which is currently unused. It is of high value, though. I noticed that upon turning off my ATI card, the battery lifetime actually increased by a factor of 5! Before using this, I could use my laptop for about an hour before the batteries went dry and now I am able to hack on it for around 5 hours without a break. At the end of this article I will present an upstart script to automatically turn off the ATI card on startup (I can't think of a reason to use the ATI card on Linux. According to other people, the drivers don't work well and there is no need for 3D acceleration at all.).
  2. DDIS - Switch to the discrete graphics card (the ATI one). This requires a restart of the X server to take effect and the whole switching is buggy on my system. Every one or two switches, the system completely crashes and I need to hard-reboot my laptop. However, it may work for some people and may work for everyone in the near future, so I included it here as well.
  3. DIGD - Switch to the integrated graphics card (the Intel one). The same restrictions and errors apply as for the previous value.
You can also read the state of the switch:
Code:
$ cat /sys/kernel/debug/vgaswitcheroo/switch
So far so good. Now as I mentioned, the ATI card is practically useless unless You want to play games (and even then I heard it's not really making things look good). If You want to turn it off, You may copy the following script (name it ati-disable.conf and place it in /etc/init as root, of course).
Code:
# ati-disable - Disable ATI graphics card
#
# Disable the dedicated ATI graphics card to save power.

description "Disable ATI graphics card"
author "Frederik Möllers"

start on started gdm

script
    if [ -w /sys/kernel/debug/vgaswitcheroo/switch ]
    then
        echo "OFF" > /sys/kernel/debug/vgaswitcheroo/switch
    fi
end script
Upon reboot, Your ATI card should be turned off. You can check if it is by using the cat command from above.

That's it! You're done!

13.11.2010

Fred.deb

Update: There is a note on bugs at the end of the article.

Yay, I forged my first package! And I got my own PPA (personal package archive) at Launchpad!
The first package I made is based on my article on screen rotation. It contains the script itself (an improved version), the upstart script to map the keycodes and a configuration file (/etc/tablet-mode/tablet-mode.conf) to centrally configure the needed values.
Here's what You need to do if You want to use it (You need root access for most of the tasks):
  1. Add the PPA to Your sources:
    Code:
    add-apt-repository ppa:fredfredfred/ppa
  2. Refresh Your package list:
    Code:
    apt-get update
  3. Install the package:
    Code:
    apt-get install tablet-mode
  4. As told in the message during installation, You need to take a look at the configuration file, /etc/tablet-mode/tablet-mode.conf. Either use the comments from the file or have a look at my first article on this subject to find out the values You need. The values provided in the sample should work on an HP TouchSmart tm2-1090eg notebook, You only have to uncomment the last 2 lines to enable the keycode:scancode mapping upon system start.
  5. Bind the scan codes to rotatescreen tableton and rotatescreen tabletoff, as described in the other article.
That's it! You're done!

Bugs: If You turn the screen, put it down and then hibernate Your laptop, turn the screen back and power it back on, the screen is upside down as is the tablet orientation. I will not fix this, since I cannot. Upon resuming from suspend, there is no way for me to check which position the display is in. Use the console commands rotatescreen tableton and rotatescreen tabletoff to switch between the modes manually (or use the GUI).

07.11.2010

CPU governors and power supply status

Update: As announced, this script collection has been incorporated into my PPA as a package. Check it out here.

As promised, here's an article on CPU governors. As You might know by now, I use Ubuntu on my laptop. Unfortunately, it was kind of useless (until now) if I didn't plug in the power supply, since the battery was drained in less than an our of work (using nothing more than a text editor, kile). The problem source: The system doesn't change the cpu governor when the power cord is plugged out. Thus, the ondemand governor is used instead of the powersave one.
Luckily, there's an easy way to cope with this. The ACPI daemon acpid can be taught to execute arbitrary code upon any ACPI event. That means You can use it to automatically change the CPU governor depending on Your power supply status. Here's how it works:
  1. Create a script to change the CPU governor. You can use mine, too:
    Code:
    #! /bin/bash

    # Note: AC connection is in:
    # /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0003:00/power_supply/AC/online
    # 0 is disconnected, 1 is connected

    # If no arguments are passed, print governors
    if [ -z "$1" ]
    then
       for MYCPU in /sys/devices/system/cpu/cpu[0-9]*
       do :
          echo "$(basename $MYCPU): $(cat ${MYCPU}/cpufreq/scaling_governor)"
       done
       echo "Available (on cpu0): $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)"
       exit 0
    fi

    # Bring governor in control
    if [ "$UID" -ne "0" ]
    then
       echo "Error: Must be run as root!"
       exit 1
    fi
    echo -n "Handling over control to $1 governor... "
    if [ "$1" == "conservative" -o "$1" == "powersave" -o "$1" == "performance" -o "$1" == "ondemand" ]
    then
       for MYCPU in /sys/devices/system/cpu/cpu[0-9]*
       do :
          echo "$1" > ${MYCPU}/cpufreq/scaling_governor
       done
    # userspace governor needs speed argument
    elif [ "$1" == "userspace" ]
    then
       if [ "$2" -gt "0" ]
       then
          for MYCPU in /sys/devices/system/cpu/cpu[0-9]*
          do :
             echo "$1" > ${MYCPU}/cpufreq/scaling_governor
             echo "$(expr $2 \* 1000)" > ${MYCPU}/cpufreq/scaling_setspeed
          done
       else
          echo "userspace governor needs speed argument > 0!"
       fi
    else
       echo "Unknown governor: '$1'"
       exit 1
    fi
    echo "done"
    Make the script executable and place it somewhere, e.g. in /usr/local/bin. You can also use the script manually from the command line, e.g. with sudo cpufreq performance if You feel like You need everything Your computer got.
  2. Create a script for the acpid and place it in /etc/acpi (the script must be executable). Mine is called powersave.sh and looks like this:
    Code:
    #! /bin/bash

    # Called by /etc/acpi/events/powersave
    # Calls cpufreq script to set cpu governor
    # Author: Frederik Möllers

    if [ "$4" -eq 0 ]
    then
       /usr/local/bin/cpufreq powersave
    else
       /usr/local/bin/cpufreq ondemand
    fi
  3. Create a rule for the acpid and place it in /etc/acpi/events. Mine is called powersave and looks like this:
    Code:
    # /etc/acpi/events/powersave
    # Calls /etc/acpi/powersave to set cpu governor when ac adapter status changes
    # Author: Frederik Möllers

    event=ac_adapter
    action=/etc/acpi/powersave.sh %e
  4. Make acpid reload its configuration (as root):
    Code:
    $ reload acpid
  5. You might think You're done now, but actually You've only finished half of the job yet. When the system boots up, there will be no ACPI event telling acpid the status of Your power supply. Thus, if You boot with the power cord plugged out, Your system will still use the ondemand governor. To deal with that, You can create an upstart script which sets the CPU governor depending on the status of the power supply. Create a file /etc/init/cpufreq.conf (or with any other filename, but keep the .conf extension!) and fill it with something like the following.
    Code:
    # cpufreq
    #
    # Sets CPU governor to ondemand if AC is plugged in and powersave if not
    # Default is performance which is kind of overkill.

    description "CPU frequency scaling"
    author "Frederik Möllers"

    start on (virtual-filesystems and local-filesystems)

    script
       if [ "$(cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0003:00/power_supply/AC/online)" -eq 0 ]
       then
          sudo /usr/local/bin/cpufreq powersave
       else
          sudo /usr/local/bin/cpufreq ondemand
       fi
    end script
    WARNING: Depending on Your system, the path (/sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0003:00/) on the /sys filesystem where the status of Your power supply can be found, may differ from the one I use. It shouldn't be miles away, but especially the number following ACPI may be another one on other laptop. You might need to search for the power_supply directory manually and change the path.
  6. You're almost done! Since the default CPU governor is performance which, as I said in my script, is kind of overkill, Ubuntu ships with an init-script to set the governor to ondemand upon startup. This, however, collides with the upstart script You just created, so You need to disable that init-script (as root):
    Code:
    $ update-rc.d ondemand disable
    This will safely disable the ondemand script but will still offer You the chance to turn it back on if You ever want to revert the changes You made.
That's it! You're done!