Last year I needed/wanted a new laptop, something with decent battery life but still lightweight and with a useful vertical screen resolution. The Acer C110 I had before was nice but lasted less than 2 hrs on battery. So I got an Atom-based unit, an Acer Aspire One 751h: 1.3GHz Atom Z520, 2Gb memory, 160Gb disk, 1366x768/11.6in display, 1.37kg (weighed it myself), 6+ hours of battery life, and - very important to me - a decent, full-size keyboard, all packed into the size of a sheet of A4.
Nice gear - except for the not-quite-Intel GMA500 graphics crap, for which no decent (semi-)free drivers exist. I won't bore you with the tedious story of getting decent graphics going - it was quite tedious, but I'm really stubborn.
So here are some of my lessons learned, hopefully helpful to you people out there. The features and subsystems not mentioned (the majority) worked out of the box or without more than normal configuration steps required.
The Acer ACPI bios is an odd beast, and a lot of things are done pretty badly, relying on a windows driver to take up the slack and clean up the resulting mess. Obviously we don't have that windows framework on a Linux box, so we have to make do.
Example: the brightness keys generate acpi events but the bios doesn't catch them to actually update the brightness. That part you've got to do yourself...
After playing with acer_ec.pl (raw interface to the environmental controller
chip, register 0x51 reflects the wanted backlight level) and the vga
setpci -v -s 00:02.0 F4.B=20 sets
the backlight to, say, 20/100%)
I found out that the kernel option
loading the acer-wmi module plus a bit of acpi glue gets things done. Put the following in
event=video.* 0000008 action=cat /sys/class/backlight/acer-wmi/actual_brightness > /sys/class/backlight/acer-wmi/brightness
This creates an acpi hook to read the desired "actual" level (which reflects the keys and not
the led level) when the relevant keys are pressed;
Then it's actually sufficient to just write that
value to the acer-wmi's brightness sys file to set the led level. Amazing (but don't ask how
much fiddling it took me to figure this out...). A patch is also needed, see update at the end of the post.
Killswitches/keys and Wifi/Bluetooth
Both wifi and bluetooth kill switches generate scancodes, but oddly: you get different scancodes for on-to-off and off-to-on. The BT device (a bcm2046, bt-usb supports it fine) only shows up on the (usb) bus when the kill switch was toggled. The only thing that doesn't create a scancode is Fn-F6 (backlight off).
The acer-wmi module always enables the bluetooth hardware on load, and the following in /etc/modprobe.d/anything.conf takes care of that annoyance.
install acer-wmi /sbin/modprobe --first-time --ignore-install acer-wmi; rfkill block bluetooth
The kill switches front and top work fine, but you need to clear the rfkill block at the right time. I do this with hotplug:
echo 1 > /sys/$DEVPATH/statetriggered by RFKILL_NAME=hci0 and ACTION=add enables the device when the bluetooth device shows up on the bus.
The wifi is a Broadcomm bcm4312, which needs at least kernel 2.6.35 and non-free firmware. You need to use b43-fwcutter to prep that firmware. With that, the right kernel and SSB (Sonics Silicon Backplane) compiled as module(!) the thing works fine. Without SSB nothing works, and with SSB compiled into the kernel nothing works either (at least with 2.6.35, haven't tried anything newer so please correct me if i'm wrong).
The Acer Bios is especially stupid wrt. sleep: the sleep button only creates a scan code but no acpi notify events, and thus no sleeping happens - unless you connect the dots between key press and acpi sleep by yourself. (The sleep button is defined as an acpi object but there's nothing in the bios that triggers that object - and I've looked hard, incl. disassembly of the acpi bios tables...).
I fixed that by mapping the scancode to a key symbol for X, and my fvwm was told to run
sudo /etc/acpi/sleep.sh when this key triggers. Ugly but sufficient.
Sleep and restore generally work fine, a
echo -n "mem" >/sys/power/state in sleep.sh is
perfectly sufficient to trigger the suspend and no quirks have to be handled - except graphics:
all GMA500 drivers I've used so far want to be switched to a text console (
chvt 1 is enough)
before suspending or the display won't come back up properly.
Your choices with the GMA500 all suck. Some suck much worse than others, but you certainly shouldn't expect smooth sailing.
The VESA driver works, but it's very slow. With 915resolution you get the native 1366x768 resolution without any trouble. Slow but trusty.
With Lenny-and-bits-from-everywhere I used the non-free-but-somewhat-packaged "PSB" driver first. This "PSB" closed-source driver is a sorry mess - PSB stands for "Prickly Shite and Buggy" in my opinion. The graphics driver crashed every now and then, no Xvideo extension, suspend/restore were about 85% successful and so on. But on Lenny(+-) it worked sort-of ok.
However, with newer Xorg releases (1.7 onwards) the PSB driver doesn't work properly: without Option "shadowfb" "true", Firefox doesn't show any menus. And with the option enabled no 3D apps work, no GL, and worse: after starting any GL app the display freezes on switching to the text mode consoles (and also when you stop X). Damned if you do, damned if you don't - and that's it for PSB in my book. RIP (actually rest in HELL, damn thing).
The other closed-source driver, "IEGD" (must be short for "increasingly extreme grotty dregs"), doesn't work with such newfangled versions of X at all, nor does it support recent kernels. No go.
However, the last closed-source driver innovatively named "EMGD" ("even more gross driver") actually works not so badly - but the config is fiddly and not totally feature-complete.
I pulled the Ubuntu-PPA-packaged emgd stuff (the "Lucid" variant), and after quite some trial and error almost everything that I need works. What doesn't work conveniently: xrandr doesn't see anything on the VGA port, hot-switching between internal/external display doesn't work (only full cloning) and the VGA port is only detected if you start X after the external monitor is detected. But OTOH Xvideo, GL, suspend and resume work fine.
And let's be honest: this is an Atom-powered portable box, it's not meant for heavy-duty video watching or gaming. For my purposes (programming on the go, editing files, network access and the like) the 751h is totally sufficient.
Here are a few of the relevant config file snippets, hope they help. The xorg.conf fragment for the emgd:
Section "Device" Identifier "psb nextgen horror" Driver "emgd" Screen 0 BusID "PCI:00:02:0" Option "PcfVersion" "1792" Option "VideoRam" "32768" # port 4 is lvds, 2 is vga via sdvob; default order 42000 # and the poulsbo doesn't have any further outputs Option "ALL/1/General/PortOrder" "24000" Option "ALL/1/General/DisplayConfig" "2" #clone Option "ALL/1/Port/2/General/EdidAvail" "1" # use edid if present Option "ALL/1/Port/2/General/EdidNotAvail" "7" Option "ALL/1/Port/2/Name" "crt" Option "ALL/1/Port/4/Name" "lcd" # read timing from edid Option "ALL/1/Port/4/General/Edid" "1" # enable backlight control, port driver method (only allowed one) Option "ALL/1/Port/4/FPInfo/BkltMethod" "1" # enable backlight, 20 should be same attr Option "ALL/1/Port/4/Attr/20" "1" Option "ALL/1/Port/4/FPinfo/BkltEnable" "1" # level, 0..100 Option "ALL/1/Port/4/Attr/70" "0" EndSection Section "ServerFlags" # the ppa/lucid driver is for a newer abi than the debian squeeze x core, # but with that option on things work fine. Option "IgnoreABI" "true" EndSection
My acer-customization startup script that sets up the keyboard:
#! /bin/sh ### BEGIN INIT INFO # Provides: acerextras # Required-Start: $local_fs keymap # Default-Start: S # Required-Stop: # Default-Stop: ### END INIT INFO PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="Acer Key setup" SCRIPTNAME=$0 echo -n "Starting $DESC..." modprobe acer-wmi # most of these came from https://wiki.ubuntu.com/KubuntuLaptopKeycodes # remainder: assigned arbitrarily, starting at keycode 130 # fn-left: brightness down setkeycodes e04c 101 # fn-right: brightness up setkeycodes e054 212 # fn-f1, odd symbol setkeycodes e027 130 # fn-f2, odd symbol. setkeycodes e026 131 # fn-f3, bluetooth but only on off. on enable you get e03b. # note: same for the hardware killswitch in front setkeycodes e059 132 setkeycodes e03b 237 # fn-f5, ext/int display setkeycodes e029 241 # fn-f6, backlight off: no scancode at all # odd: two different codes on the same damn thing. # fn-f7, pad off setkeycodes e072 133 # fn-f7, pad on setkeycodes e071 134 # wifi on setkeycodes e055 135 # wifi off setkeycodes e056 136 echo done
My /etc/X11/Xmodmap to make the few unknown/custom keys known to X (can't be bothered fiddling this into xkb, which is beastly IMNSHO):
! that's applied on top of ! Option "XkbRules" "xorg" ! Option "XkbModel" "pc104" ! Option "XkbLayout" "us" ! Option "XkbOptions" "terminate:ctrl_alt_bksp,ctrl:nocaps" ! naming: see /usr/share/X11/XKeysymDB ! generic preference: ! windows keys as super l/r, not meta l/r: not nice for emacs, imnsho keycode 0x73 = Super_L keycode 0x74 = Super_R add mod4 = Super_R ! menu key: compose keycode 0x75 = Multi_key ! the default was Meta_L, emacs then uses that one...bad, alt=meta is better. keycode 115 = Hyper_L !acer 751h keycode 101=XF86MonBrightnessDown keycode 212=XF86MonBrightnessUp keycode 223=XF86Sleep ! wifi on/off keycode 192=XF86LaunchA keycode 191=XF86LaunchB keycode 160 = XF86AudioMute keycode 174 = XF86AudioLowerVolume keycode 176 = XF86AudioRaiseVolume
Looks like my brain wasn't fully up to speed when I wrote up this info; the brightness change does actually not make it automagically from the EC (environmental controller) to the WMI driver to the VGA/backlight controller - it needs a little bit of help. My patch (downloadable here, against 2.6.35's drivers/platform/x86/acer-wmi.c) tells the Acer WMI driver to forget asking the BIOS for help when reading brightness levels but read them directly from the EC. Then, when a brightness change is requested, it writes the change to the EC first (remembering where we are) an then to the relevant VGA register (which actually sets the brightness level). A second patch convinces the acpi subsystem not to try any brightness changes itself (which it fails at anyway) but rather to forward the acpi event to the rest of the universe, so that we can do things ourselves.