Posts mit dem Label acpi werden angezeigt. Alle Posts anzeigen
Posts mit dem Label acpi werden angezeigt. Alle Posts anzeigen

06.02.2011

Yet another cpufreq update

The title says it all. I've found another bug in my cpufreq package broke the ACPI handler. The script tried to execute /usr/local/bin/cpufreq which of course doesn't exist if You installed my packge. I've changed it to execute cpufreq which gives You the possibility to put a custom version of the cpufreq script into /usr/local/bin and which is then executed instead of the package version. If you stay with the packaged version, it will of course execute that.
I recommend You install the update as soon as it's available. As always, report any bugs You might find!

02.02.2011

cpufreq update

I've released version 1.1.0 of my cpufreq package. It fixes numerous bugs, including the one that made the upstart job not work at all. Unfortunately, version 1.0.0 is so broken that You can't just update to 1.1.0. The old version will break the update and You'll end up with essential files missing. Due to this, I've made it impossible to upgrade from 1.0.0 to any other version. In order to get the new version, You will have to remove (or purge) the old version first, e.g. with apt-get:
Code:
$ apt-get purge cpufreq

After that, You are safe to install the new version (make sure to update Your package list, first!):
Code:
$ apt-get update
$ apt-get upgrade cpufreq

I'm sorry for the troubles this may have caused You (or will cause You during the update). As far as I can judge, it will not happen again with this package. I fixed the control files to prevent deleting files that are being installed by a newer version of the same package (in fact, they don't delete anything anymore).

In addition to the bugfixes, I've included a configuration file: /etc/default/powersave. Using that file, You are able to control the behavior of the ACPI handler and the upstart job. You can specify which CPU governors to install and You can disable each of them completely. I hope this compensates You for the pain the bugs caused :)

A side note here: The package will not remove any files in /etc when being removed normally (not purged). The upstart job and the ACPI handler will stay, but they won't do anything, since the cpufreq executable is not present. If You want to delete those files, purge the package (called "Mark for Complete Removal" in Synaptic) or delete them manually.

Another side note: When future upgrades are being installed, You might be asked if You want to keep some configuration files or install the "package maintainer's" (that's me) version. If You haven't changed the file in question and are unsure, it's best to install the new version, since it may contain bugfixes or new features (although You shouldn't be asked if You didn't change the file).

Since this problem seems to be fixed (report any bugs that persist or came up, please!), I will focus on the package to switch the graphics card now. Stay tuned for more!

That's it! You're done!

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!

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!