FreeBSD 10 on the Asus Zenbook UX31E

This laptop landed in my hands a couple weeks ago, and a quick check online suggested it was well supported by FreeBSD. So I gave it a try! It worked out of the box… nearly.

Summary

  • running FreeBSD 10.2-RELEASE
  • just works: accelerated graphics, USB, including cabled Ethernet dongle, sound
  • seems to just work: wifi, although this particular laptop tends to disassociate under heavy network load
  • works after loading a pre-installed module: special keys and backlight control
  • works after some tweaks: frequency and power management
  • works after back-porting a 11-CURRENT kernel patch: suspend/resume
  • works after back-porting a custom patch: multi-touch trackpad
  • may not work (unsure): webcam
  • not tested, should just work: integrated MMC card reader, Bluetooh

Graphics

Using the default console driver, after the X server has started once the console becomes unusable (can’t restore text mode after graphics driver is initialized).

To fix this the following are needed in /boot/loader.conf [2]:

# load the kernel driver for integrated graphics
i915kms_load="YES"
# use the new VT console driver ("newcons")
kern.vty=vt
# ensure the console starts in graphics mode (should be default)
hw.vga.textmode=0
# set console resolution to match screen
kern.vt.fb.default_mode="1600x900"

Backlight control and special keys

Needs the pre-built module acpi_asus_wmi, add to /boot/loader.conf:

acpi_asus_wmi_load="YES"

Tuning power consumption

See the guide in [2]. This involves:

  • enabling and configuring powerd in /etc/rc.conf:

    powerd_enable="YES"
    powerd_flags="-a hadp -b adp -i 50 -m 800 -M 1601 -n adp -p 250 -r 90"
    performance_cx_lowest="Cmax"
    economy_cx_lowest="Cmax"
    
  • adding some tweaks in /boot/loader.conf:

    ### power tuning by the book
    hint.p4tcc.0.disabled=1
    hint.acpi_throttle.0.disabled=1
    drm.i915.enable_rc6=7
    hw.pci.do_power_nodriver=3
    hw.snd.latency=7
    

Suspend/resume

The article in [2] suggests that suspend/resume works out of the box in FreeBSD 10. However this is not so, due to FreeBSD bug 194884: the USB devices are not set in the proper power state upon suspending.

This bug has been fixed in 11-CURRENT but I still want to use 10.2-RELEASE to benefit from freebsd-update. So I back-ported the patch:

  1. download the kernel sources from 10-STABLE

  2. apply the following patch:

    # cd /usr/src; svnlite diff
    Index: sys/dev/acpica/acpi.c
    ===================================================================
    --- sys/dev/acpica/acpi.c       (revision 292841)
    +++ sys/dev/acpica/acpi.c       (working copy)
    @@ -691,7 +691,7 @@
     static void
     acpi_set_power_children(device_t dev, int state)
     {
    -       device_t child, parent;
    +       device_t child;
            device_t *devlist;
            struct pci_devinfo *dinfo;
            int dstate, i, numdevs;
    @@ -703,13 +703,12 @@
             * Retrieve and set D-state for the sleep state if _SxD is present.
             * Skip children who aren't attached since they are handled separately.
             */
    -       parent = device_get_parent(dev);
            for (i = 0; i < numdevs; i++) {
                    child = devlist[i];
                    dinfo = device_get_ivars(child);
                    dstate = state;
                    if (device_is_attached(child) &&
    -                   acpi_device_pwr_for_sleep(parent, dev, &dstate) == 0)
    +                   acpi_device_pwr_for_sleep(dev, child, &dstate) == 0)
                            acpi_set_powerstate(child, dstate);
            }
            free(devlist, M_TEMP);
    Index: sys/dev/pci/pci.c
    ===================================================================
    --- sys/dev/pci/pci.c   (revision 292841)
    +++ sys/dev/pci/pci.c   (working copy)
    @@ -3718,7 +3718,7 @@
                    child = devlist[i];
                    dstate = state;
                    if (device_is_attached(child) &&
    -                   PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0)
    +                   PCIB_POWER_FOR_SLEEP(pcib, child, &dstate) == 0)
                            pci_set_powerstate(child, dstate);
            }
     }
    
  3. build and install the kernel as usual

  4. add the following to /boot/loader.conf:

    # this is needed otherwise video may not resume:
    acpi_video_load="YES"
    # this is needed otherwise the trackpad may hang after resume
    hint.psm.0.flags="0x6000"
    
  5. reboot

Trackpad is Elantech, not Synaptics

Although the trackpad is advertised as synaptics-compatible, neither of the following work as of December 2015:

  1. adding hw.psm.synaptics_support=1 to /boot/loader.conf (the driver does not activate Synaptics support despite the hint)
  2. forcing the Synaptics driver from package xf86-input-synaptics (X.org complains the Synaptics protocol is not recognized)

This is because the laptop has an Elantech trackpad, which is slightly incompatible with Synaptics.

Out of the box, the trackpad is recognized as a standard PS/2 mouse instead. In order to make it slightly less annoying you can start by enabling 3-button emulation in moused, for example in /etc/rc.conf:

moused_enable="YES"
moused_flags="-3"

However a proper fix is to add Elantech support to the psm(4) driver. I have filed this as FreeBSD bug 205690; the bug report contains a patch that you can use to add support for the trackpad in 10-STABLE. This will require a custom kernel build, and also installing the patched sys/mouse.h and moused(8).

With this installed I found the following settings in /boot/loader.conf to work best:

hw.psm.elantech_support=1
# disable two-finger scroll, instead the
# right area becomes a scrolling area
hw.psm.elantech.two_finger_scroll=0
hw.psm.elantech.vscroll_ver_area=-600

Note that the updated driver code has its own 3-button emulation, so be sure to remove the "-3" flag to moused if you have added it earlier.