HP TouchSmart tm2

The TouchSmart tm2 came originally in multiple versions in addition to custom made from HP-shop. The two versions were tm2-1080 and tm2-1090; the differences between the two were the CPU (SU4100 vs. SU7300) and the amount of RAM (1+2=3 GB vs. 2+2=4 GB). There are also tm2-2050xx versions (tm2-2050us, tm2-2050ca, tm2-2050er, etc.).

  • Note
    These workarounds, solutions, and tips have been tested and verified to work on an HP TouchSmart Tm2-2050us running Ubuntu 10.04 Lucid Lynx and Ubuntu 10.10 Maverick Meerkat. They have been tested but not verified for 11.04 Natty Narwhal.

Installing Ubuntu 10.4 - 11.10 alongside Windows 7


The TouchSmart has four primary partitions when it ships. Hence, it is not possible to just resize and create a new partition - one of the existing ones must be deleted.

The "HP_TOOLS" seemed pretty useless, and as it only contained files for styling the diagnostics screen, this was chosen as the least useful, the files were backed up and the partition was deleted. Then the C-drive was resized so that it was approximately 30GB smaller, to use for Ubuntu.

  • Note
    The "HP_TOOLS" partition could be placed at USB flash drive, for more details see documentation for the various HP EFI tools installers (could be found in drivers download section for your product at HP support site).

Then I created a bootable memory stick with Ubuntu see https://help.ubuntu.com/community/Installation/FromUSBStick, booted (chose boot device by pressing [esc] right before the Windows 7-logo shows and by pressing boot select [F10]) and installed.

The display could occasionally stop working on the live USB/CD images, and at log in screen, this can be fixed by simply closing the display lid, and reopening it (this usually has to be done at least 2 or 3 times). In 11.04 it seem about every other boot up dose not allow you to do any thing just a black screen, no amount of closing and opening will fix this. In this case just restart your computer and try again. For fixing this very annoying bug see Screen Brightness section.

Status of devices


Status of the devices of the laptop, which parts are working and which parts are not. Eventually how to fix the problems.

Graphics


TouchSmart tm2 has two GPUs onboard: integrated (Intel, less acceleration, more battery life/less heating and noise) and discrete (ATI, much faster acceleration, less battery life/more heat and noise). This is called hybrid graphics.

  • Note
    Disabling discrete GPU battery life improvement could be very impressing. For example, for tm2-2050xx battery time increases from about 3 hrs. to about 7 hrs.

You can get your TouchSmart GPUs list by running:

lspci | grep VGA

There is a kernel mechanism available by default since Ubuntu 10.10 named vga_switcheroo, which makes possible to switch between GPUs.

Screen Brightness

There is a nasty bug somewhere between DSDT ACPI table and kernel, which (at least) sometimes takes internal display backlight off (which can be turned on back just with that close-lid-open-lid magic). It is already reported at launchpad (Bug #697514) and kernel.org (Bug 34582), but as for 2012-04-10 it is not processed yet.

There is workaround, though. DSDT can be fixed to remove error-causing block and brightness control will work almost perfectly. (Thanks to someh4x0r for debugging and Michael Kuron for pointing out DSDT patching technique using Grub2.) Following steps are tested with tm2-2050xx (BIOS versions F.05 and F.25) with Ubuntu 11.10.

1) Dump current DSDT table:

sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.dat

2) Disassemble DSDT table getting dsdt.dsl file:

iasl -d dsdt.dat

  • Note
    If iasl command is not found you can install Install Intel ASL Optimizing Compiler using:
    sudo apt-get install iasl

3) Fix method OBCL in dsdt.dsl file (open it with your favorite text editor) to look like (just copy over the existing method text):

                    Method (OBCL, 0, NotSerialized)
                    {
                        BINI ()
                        Return (Package (0x0D)
                        {
                            0x64, 
                            0x3C, 
                            0x06, 
                            0x0A, 
                            0x14, 
                            0x1E, 
                            0x28, 
                            0x32, 
                            0x3C, 
                            0x46, 
                            0x50, 
                            0x5A, 
                            0x64
                        })
                    }

For example, the original method, that should be replaced with upper content, for current (2012-04-10) tm2-2050xx BIOS version F.25 looks like:

                    Method (OBCL, 0, NotSerialized)
                    {
                        BINI ()
                        If (LEqual (IOSR, One))
                        {
                            Return (Package (0x0D)
                            {
                                0x64, 
                                0x3C, 
                                0x06, 
                                0x0A, 
                                0x14, 
                                0x1E, 
                                0x28, 
                                0x32, 
                                0x3C, 
                                0x46, 
                                0x50, 
                                0x5A, 
                                0x64
                            })
                        }
                        Else
                        {
                            Store (Package (0x0D)
                                {
                                    0x64, 
                                    0x3C, 
                                    Zero, 
                                    0x0A, 
                                    0x14, 
                                    0x1E, 
                                    0x28, 
                                    0x32, 
                                    0x3C, 
                                    0x46, 
                                    0x50, 
                                    0x5A, 
                                    0x64
                                }, Local0)
                            If (LEqual (OSYS, 0x07D6))
                            {
                                Return (Package (0x0D)
                                {
                                    0x64, 
                                    0x3C, 
                                    0x06, 
                                    0x0A, 
                                    0x14, 
                                    0x1E, 
                                    0x28, 
                                    0x32, 
                                    0x3C, 
                                    0x46, 
                                    0x50, 
                                    0x5A, 
                                    0x64
                                })
                            }

                            Return (Local0)
                        }
                    }

4) Now save the dsdt.dsl file and assemble it getting dsdt.aml file:

iasl -tc dsdt.dsl

Compiler may report some warnings and even errors, but dsdt.aml file will be created (these are initially left by your product vendor). To be sure you correctly patched the method you can compare warning/error count for assembling your version dsdt.dsl and assembling unchanged one, their quantity should be equal.

5) Copy dsdt.aml to /boot/ and set permissions:

sudo cp dsdt.aml /boot/
sudo chown root:root /boot/dsdt.aml
sudo chmod 644 /boot/dsdt.aml

6) Open file with you favorite editor:

gksudo gedit /etc/grub.d/01_acpi

Paste the following code:

# Uncomment to load custom ACPI table
GRUB_CUSTOM_ACPI="/boot/dsdt.aml"

# DON'T MODIFY ANYTHING BELOW THIS LINE!

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib

. ${libdir}/grub/grub-mkconfig_lib

# Load custom ACPI table
if [ x${GRUB_CUSTOM_ACPI} != x ] && [ -f ${GRUB_CUSTOM_ACPI} ] \
        && is_path_readable_by_grub ${GRUB_CUSTOM_ACPI}; then
    echo "Found custom ACPI table: ${GRUB_CUSTOM_ACPI}" >&2
    prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_CUSTOM_ACPI}` | sed -e "s/^/  /"
    cat << EOF
acpi (\$root)`make_system_path_relative_to_its_root ${GRUB_CUSTOM_ACPI}`
EOF
fi

7) Set permissions:

sudo chown root:root /boot/dsdt.aml
sudo chmod 644 /boot/dsdt.aml

8) Update grub:

update-grub2

Now restart OS and get fully working brightness control. If you've made some errors in step 3 and this prevents OS from correct operation (very unlikely but we'll assume it possible), you can boot from Ubuntu CD, delete /boot/dsdt.aml file, boot to your OS and repeat steps 1-5. Patched dsdt.aml file could be saved somewhere in case of OS reinstall.

  • Note
    In case of BIOS version upgrade steps 1-5 need to be done again for the new BIOS.


If the brightness of the Internal Display is too dark, then you can manually override it via:

sudo setpci -s 00:02.0 f4.b=FF

The value in the End ranges from 0-255.

Screen Brightness Control

Several people have reported screen brightness control as non-working with the tm2 in Ubuntu ( https://bugs.launchpad.net/ubuntu/+source/linux/+bug/516772 )

As mentioned above, the brightness of the internal display can be overridden using: sudo setpci -s 00:02.0 f4.b=FF However, this is cumbersome to remember and is prone to errorous input data. To address these problems, you could use the following script. Copy the text below and store it in /usr/local/bin/setbrightness

function print_usage() {
  echo "Usage:"
  echo "  sudo setbrightness BRIGHTNESS"
  echo "    where BRIGHTNESS is between 0 and FF"
}
brightness=$1
if [[ $(whoami) != "root" ]]; then
    print_usage
    echo "This script needs to be executed as root."
    exit 1
fi
if [ ! "$#" -eq 1 ]; then
    print_usage
    exit 1
fi
if [ "${#brightness}" -gt 2 ]; then
    print_usage
    exit 1
fi
disallowed_chars=$( echo $brightness | grep -o "[^0-9a-fA-F]*" )
if [ ! -z "$disallowed_chars"]; then
    print_usage
    exit 1
fi

setpci -s 00:02.0 F4.B=$brightness

Then make the script executable by running sudo chmod +x /usr/local/bin/setbrightness You should now be able to set the backlight by running sudo setbrightness <brightness> where <brightness> is a value between 0 (no backlight) and FF (full backlight).

To make the brightness buttons work, you need to create another script that increases or decreases the brightness relative to the current value. Copy the following text to /usr/local/bin/brightness-updown

function print_usage {
  echo "Turn the brightness up or down."
  echo "Usage:"
  echo "  sudo brightness-updown <up/down>"
}

if [[ $(whoami) != "root" ]]; then
    print_usage
    echo "This script needs to be executed as root."
    exit 1
fi
brightness_max=255
brightness_min=15
n_steps=5

step_size=$(( ($brightness_max - $brightness_min) / $n_steps ))
current_brightness=$(( 0x$(setpci -s 00:02.0 F4.B) ))

if [[ "$1" == "up" ]]; then
    if [ $current_brightness -eq $brightness_max ]; then
        exit 0
    fi
    wanted_brightness=$(( $current_brightness + $step_size ))

    if [ $wanted_brightness -gt $brightness_max ]; then
        wanted_brightness=$brightness_max
    fi
    
elif [[ "$1" == "down" ]]; then
    if [ $current_brightness -eq $brightness_min ]; then
        exit 0
    fi

    wanted_brightness=$(( $current_brightness - $step_size ))

    if [ $wanted_brightness -lt $brightness_min ]; then
        wanted_brightness=$brightness_min
    fi

else
    print_usage
    exit 1
fi

wanted_brightness_hex=$(printf "%X" $wanted_brightness)

sudo setbrightness $wanted_brightness_hex

Make the script executable sudo chmod +x /usr/local/bin/brightness-updown and test it using sudo brightness-updown up/down

To map the script to the brightness keys, execute acpi_listen press the brightness down and up buttons, and note the output. Example output shown below:

video LCD 00000087 00000000
video DD03 00000087 00000000
video LCD 00000086 00000000
video DD03 00000086 00000000

Then create two files in /etc/acpi/events/ called hp_brightness_up and hp_brightness_down as below:

event=video DD03 00000086 00000000
action=/usr/local/bin/brightness-updown up

and

event=video DD03 00000087 00000000
action=/usr/local/bin/brightness-updown down

Now restart acpi sudo restart acpid and the brightness keys should work.

vga_switcheroo


Ubuntu Community Documentation has a good article about handling hybrid graphics. It is strongly recommended to have a look in case GPU switching is required. In this section you'll find just some the very common information.

From Ubuntu 10.10, the vga_switcheroo kernel module is implemented by default. This module enables switching between graphic cards. It is operated through /sys/kernel/debug/vgaswitcheroo/switch with echo-commands. Here is a simple script to operate this in a simpler way.

Open your favorite editor f.ex. gedit:

gksudo gedit /usr/local/bin/switch

And paste the following code into the editor:

SWITCH=/sys/kernel/debug/vgaswitcheroo/switch
case "$1" in
    low)
        echo "Turning on low-power card."
        sudo sh -c "echo IGD > $SWITCH"
        ;;
    high)
        echo "Turning on high-power card."
        sudo sh -c "echo DIS > $SWITCH"
        ;;
    on)
        echo "Turning on unused card."
        sudo sh -c "echo ON > $SWITCH"
        ;;
    off)
        echo "Turning off unused card."
        sudo sh -c "echo OFF > $SWITCH"
        ;;
    xlow)
        echo "Queuing to use low-power card for next X session."
        sudo sh -c "echo DIGD > $SWITCH"
        ;;
    xhigh)
        echo "Queuing to use high-power card for next X session."
        sudo sh -c "echo DDIS > $SWITCH"
        ;;
    stat)
        cat $SWITCH
        ;;
    *)
        echo "Usage: $SCRIPTNAME {low, high, on, off, xlow, xhigh, stat}"
        echo "    low   - select low-power card"
        echo "    high  - select high-power card"
        echo "    on    - turn on unused card"
        echo "    off   - turn off unused card"
        echo "    xlow  - queue to use low-power card for next X session"
        echo "    xhigh - queue to use high-power card for next X session"
        echo "    stat  - output cards' current status"
        echo
        echo "Status:"
        cat $SWITCH
        ;;
esac

Then make it executable using:

sudo chmod +x /usr/local/bin/switch

As you most likely don't want both cards to be powered on at start-up, the following procedure will turn off the unused one at start-up:

To be able to run the script as administrator without providing a password you can add it to the sudoers file. Run:

sudo visudo

And append the following line (exchange $USERNAME with your username):

$USERNAME ALL=NOPASSWD:/usr/local/bin/switch

Now you may add the script to your startup applications. Go to System -> Preference -> Startup Applications, press Add and write gksudo switch off in the Command-field, and for example "Switch off unused graphics card" as the name.

Blacklisting GPU driver


As integrated GPU powerful enough for most common tasks (including Compiz effects), some users just switch discrete GPU permanently off by blacklisting radeon driver.

  • Note
    In case of blacklisting radeon driver discrete GPU will still be powered on and battery life won't increase. To power off the GPU use vga_switcheroo mechanism (also, there is possibly another way to switch on/off GPUs: acpi_call module, see hybrid-graphics-linux at Launchpad).

Here are the steps. Open file:

gksudo gedit /etc/modprobe.d/blacklist.conf

Add following line to the end of file:

blacklist radeon

Then use following command to update initramfs:

update-initramfs -c -k all

After restart discrete GPU will be permanently disabled.

To enable permanently discrete GPU back: remove blacklisting line you added, update initramfs again and restart.

ATI-proprietary driver


Did not work, and I haven't gotten it to work either. Ubuntu's recovery-option did not work (single), but changing the last part of the boot parameters to init=/bin/bash gave me a way of fixing the error.

Touchscreen & Stylus


No problems, everything worked out of the box.

To right click using stylus tap the screen, unlike windows you can not hover over the screen to right click.

On the Tm2-2050ca, when you rotate the screen, the stylus's input does not rotate with it. Up is down, and left is right. Need testing if rotation scripts in Screen rotation section solve the problem.

Touchscreen Calibration for Multiple Monitors

By default the Touchscreen is mapped to the 'Virtual Desktop', which makes it rather unusable. To avoid that, you have to map the three Devices to the first Display. For example with the following script:

# its either LVDS or LVDS-1, so use the first display from xrandr
@xrandr = `xrandr`;

$xrandr[1] =~ /(\w+)/;

$DISPLAY = $1;

system('xsetwacom --set "Wacom ISDv4 E3 Finger touch" MapToOutput ' . $DISPLAY);
system('xsetwacom --set "Wacom ISDv4 E3 Pen stylus" MapToOutput ' . $DISPLAY);
system('xsetwacom --set "Wacom ISDv4 E3 Pen eraser" MapToOutput ' . $DISPLAY);

Screen rotation

Does not work out of box, but could be implemented using methods in sections below.

Rotating the screen


Open /usr/local/bin/rotate-display in your favorite editor:

gksudo gedit /usr/local/bin/rotate-display

Paste the following code:

touchDev=`xinput --list | grep "Wacom .* touch" | grep -o "id=[0-9]*\W" | grep -o "[0-9]*"`
eraserDev=`xinput --list | grep "Wacom .* eraser" | grep -o "id=[0-9]*\W" | grep -o "[0-9]*"`
stylusDev=`xinput --list | grep "Wacom .* stylus" | grep -o "id=[0-9]*\W" | grep -o "[0-9]*"`

if [ $# != 1 ]; then
    echo 'Usage: '
    echo $0 'none|half|left'
    exit
fi

ROTATE="NONE"
DISP="normal"
if [ "$1" == "half" ]; then
    ROTATE="HALF"
    DISP="inverted"
elif [ "$1" == "left" ]; then
    ROTATE="CW"
    DISP="left"
elif [ "$1" == "right" ]; then
    ROTATE="CCW"
    DISP="right"
fi
echo "Rotating to: $DISP ($ROTATE)"
xsetwacom set $touchDev Rotate $ROTATE
xsetwacom set $eraserDev Rotate $ROTATE
xsetwacom set $stylusDev Rotate $ROTATE

xrandr -o $DISP

Make it executable:

gksudo chmod +x /usr/local/bin/rotate-display

You should now be able to rotate the display by running rotate-display $Direction where $Direction is one of: none, half, left, right

Automatical rotation


To automatically rotate the screen when the screen is flipped, do the following:

If hp_wmi is not loaded, (lsmod | grep hp_wmi returns nothing), add the following to gksudo gedit /etc/modules: hp_wmi (You may also load it for one session with gksudo modprobe hp_wmi)

Then open /usr/local/bin/auto-rotate with for example

gksudo gedit /usr/local/bin/auto-rotate

Paste the following code:

old="0"
while true; do
    if [ -e /sys/devices/platform/hp-wmi/tablet ]; then
        new=`cat /sys/devices/platform/hp-wmi/tablet`
        if [ "$new" != "$old" ]; then
            if [ $new == "1" ]; then
                rotate-display half
            elif [ $new == "0" ]; then
                rotate-display none
            fi
            old=$new
        fi
    fi
    sleep 0.5s
done

Make it executable

gksudo chmod +x /usr/local/bin/auto-rotate

Now you may add the script to your startup applications. Go to System -> Preference -> Startup Applications, press Add and write auto-rotate in the Command-field, and for example "Automatically rotate display" as the name.

You may change the direction by changing "rotate-display half" to for example "rotate-display left".

Automatical rotation using internal accelerometer


Some of the models are fitted with accelerometer in order to park the HDD head in case of extreme acceleration. This accelerometer can be used to rotate the screen, when the computer is tilted enough. For the purpose, you can see the tm2-autorotate project.

Rotating the screen using the rotate button on the side of the screen


Save the following script in a file (for example: key-rotate-screen.sh), and give it permissions to be executed, and add it to startup applications: go to System -> Preference -> Startup Applications, press Add and write key-rotate-screen.sh (with full path) in the Command-field, and for example "Automatically rotate display" as the name.

HP_WMI_NAME="HP WMI hotkeys"
KEY_ID="161"
 
primaryScreen=`xrandr | grep primary | cut -d' ' -f1`
touchDev=`xinput --list | grep "Wacom .* touch" | grep -o "id=[0-9]*\W" | grep -o "[0-9]*"`
eraserDev=`xinput --list | grep "Wacom .* eraser" | grep -o "id=[0-9]*\W" | grep -o "[0-9]*"`
stylusDev=`xinput --list | grep "Wacom .* stylus" | grep -o "id=[0-9]*\W" | grep -o "[0-9]*"`
 
function rotate_display() {
        ROTATE="NONE"
        DISP="normal"
        VGADISP="normal"
        if [ "$1" == "half" ]; then
            ROTATE="HALF"
            DISP="inverted"
            VGADISP="normal"
        elif [ "$1" == "left" ]; then
            ROTATE="CCW"
            DISP="left"
        elif [ "$1" == "right" ]; then
            ROTATE="CW"
            DISP="right"
        fi
        xsetwacom set "$touchDev" Rotate $ROTATE
        xsetwacom set "$eraserDev" Rotate $ROTATE
        xsetwacom set "$stylusDev" Rotate $ROTATE
        xrandr -o $DISP
}
 
trap "kill 0" SIGINT
 
exec 3< <(stdbuf -o0 xinput test "$HP_WMI_NAME")
 
while read <&3 data; do
        if echo $data | grep "$KEY_ID" | grep "release" >/dev/null; then
                currentRotation=$(xrandr -q -v | grep "$primaryScreen" | cut -d ' ' -f 5 | grep -v '(')
                nextRotation=""
                if [ -z "$currentRotation" ]; then
                        nextRotation="right"
                elif [ "$currentRotation" == "right" ]; then
                        nextRotation="half"
                elif [ "$currentRotation" == "inverted" ]; then
                        nextRotation="left"
                else
                        nextRotation="none"
                fi
                rotate_display $nextRotation
        fi
done

Finger print


Works nice with libpam-thinkfinger read ThinkFinger for more information

Keyboard


Function Keys


The HP TouchSmart tm2 have the function keys and the "special keys" like turning brightness up and down switched in comparison to many other laptops. This means to close a window with [Alt]+[F4], you have to press [Fn] as well. This can be switched back in the BIOS (press [esc] at start-up to access the BIOS).

Page Up/Down, Home and End


No matter how much you search the keyboard you will never find the Page up/down, home or end-buttons. However, these are accessed using [Fn]+[Arrow Key].

Touchpad


Right button does not work. Strange errors when pressing two buttons at the same time.

To right click tap the bottom right corner.

Starting from Ubuntu 11.04 pressing two fingers on the touchpad to right click or tap on the bottom right corner to right click.

Wireless


The wireless works out of the box (tm2-2050er / Ubuntu 11.10), no proprietary drivers required.

An easy way to install the Broadcom proprietary driver using Ubuntu 11.10 is to plug the laptop to a wired network and install the driver from System Settings -> Additional Drivers.

  • On the Tm2-2050ca, the wireless BCM4313 worked out of the box for me on a fresh installation of PinguyOS (ubuntu 10.10).

HDMI


Reported errors with HDMI (not working), not confirmed.

On the Tm2-2050ca/tm2-2050e HDMI output for video and sound works perfectly after changing the outputs in Sound Preferences.


CategoryHardware

HP TouchSmart tm2 (last edited 2014-02-24 12:22:14 by 195)