FreeBSD on the Thinkpad X260

Author: Jonathan Vasquez <jon@xyinn.org>
Last Updated: 2022-07-27-1200
Currently On: FreeBSD 13.1-RELEASE releng/13.1-n250148-fc952ac2212 GENERIC amd64
Machine: Thinkpad X260

2022-07-27-1200 ET

I recommend using wifibox as a workaround to the stability problems and slow speeds of the current if_iwlwifi driver. Once the FreeBSD driver is stable and complete, you can switch back to it. This change alone should massively increase the stability of the system.

2022-07-24-1504 ET

I've upgraded to the Thinkpad X1C7.

Desktop (i3)

Desktop Screenshot

Laptop Dual

Laptop

Thoughts

It's hard to believe that after my long fight with the framework laptop, that I would finally have a machine that does everything I need it to do (with some quirks xD) on FreeBSD. Although all of the experience I've picked up while trying to get the framework laptop to work was invaluable to my overall understanding of FreeBSD, and will help me not only on this laptop, but also on my server.

Overall everything works fairly well. You can take a look at the information below for further details and tweaks needed.

The Thinkpad X260 I got came with the following:

After setting everything all up on FreeBSD 13.1-RELEASE and starting to daily drive this machine, I ended up changing the resolution for the internal display back to the 1368x768 resolution (which normally comes on regular Thinkpad X260s that don't have this resolution upgrade.) 1920x1080 on this 12.5" display is just too small for my liking. However, I still recommend getting the screen upgrade if you can solely because of it being an IPS display. The viewing angles are just much better than normal Thinkpad X260 TN displays. If you do use 1920x1080, you'll probably want to run it at 200% scaling lol.. definitely more than 100%. However, since Xorg doesn't support per display scaling (Wayland does), A combination of 1920x1080 @ 100% for my External HDMI monitor and 1368x768 @ 100% for the internal display, is the sweet spot.

The machine also came with an extended battery (48 wh) version which seems to be holding a charge. I bought a replacement 24 wh battery as well (mostly cause it's flatter) but the extended battery is growing on me :).

Since everything is working on 13.1-RELEASE, I don't really need to run -STABLE anymore, but I'll probably do it anyways to help with testing (and possibly get any new improvements - at a risk of course - ZFS <3).

System Status Overview

Definitions

Status Overview

Functionality Status Remarks
Graphics Works Works perfectly fine with drm-kmod.
Ethernet Works Gigabit Ethernet is fully supported.
WiFi Works 802.11a only on iwm module. It seems that for my regular use (when on wireless) 802.11a/g surprisingly is fast enough lol. I'm usually on Ethernet though so the speed can go through there if needed. On another note, when resuming from sleep, the card associates back with the AP quickly, but getting an IP from DHCP sometimes takes a while. Using a static IP seems to improve this situation. Use wifibox in the meantime. You can switch back to the FreeBSD driver once it's complete and stable.
HDMI Works
Sound (Speakers) Works
Sound (3.5 mm) Works Works perfectly fine after applying quirks. By default, my computer speakers will play fine, but plugging in my headphones would mute the speakers (appropriately), but wouldn't continue playing audio through the headphones. The quirk fixes this.
Sleep/Resume Works It works :D !!!
USB Ports Works
Trackpoint Works
Trackpad Works See below for adding more gestures.
Camera Works The camera works at 720p @ 30 fps. Load cuse module, add user to webcamd, and start webcamd. Make sure to re-log if you aren't rebooting.
Microphone Works
SD Card Reader Works The SD card reader works but it's pretty slow. On a FAT32 SD card (It's a Micro SD card via an SD adapter), I got a peak of 5.5 Mbps but it was usually at 2 Mbps. On exFAT it was around 1.8 Mbps - 2.2 Mbps, although the slower speed is in part since exFAT on FreeBSD is only implemented via FUSE (thus userspace). Given the only reason I use my SD card is to put all of my FLACs & MP3s for my Sony MP3 player, this SD card is just way too slow for that amount of data I have for it to actually be practically useful. It's nice it works though lol.
Hibernate Untested I haven't tested this but it most likely doesn't work. From what I've "heard", FreeBSD doesn't have the hibernation code implemented.
Fingerprint Reader Untested I don't use this.
Mini DisplayPort Untested I don't use this.
SmartCard Reader Untested I don't use this.
Bluetooth Untested I don't use this on laptops, just on my phone.

Status Overview (Other)

Other components / accessories I've tested that don't come with the Thinkpad X260.

Functionality Status Remarks
Sound (AudioQuest DragonFly Cobalt v1.0) Works It works great. You just need to be careful of suspending the machine while this device is being used. FreeBSD will try and wait for the process using this device to exist before finishing the suspend, but that won't ever happen. If nothing is using it though, the system sleeps/resumes fine it seems. I've opened up Bug Report - 265121.
Sound (Headset - Razer USB Sound Card) Works
Microphone (Headset - Razer USB Sound Card) Works You'll probably need to do some adjusting so the headset microphone audio doesn't feed back into the headset speakers.

Issues / Workarounds / Misc

Crash on lid close (while on battery power)

The machine kept crashing on me if I closed the lid while on battery power. (It didn't matter if I wasn't running X and just on console). After researching and debugging, I had to disable intel p state to resolve the issue. Apparently something was introduced in 13.X that broke it, people reported that they were fine on 12.X. You can add the following to /boot/loader.conf:

# Disabling intel pstates since it currently crashes
# the system if we close the lid while on battery power.
hint.hwpstate_intel.0.disabled=1

Combined Speakers/Headphones

The pin configuration on my machine were different than the ones posted on the Thinkpad X260 page. I added the following to my /boot/loader.conf:

# Combined Speakers + Headphones
hint.hdaa.0.nid21.config="as=1 seq=15"

There may be more combinations you'll want to play with but for now this is the only thing I wanted to tweak for my current workflow.

Below you can see the output of my verbose boot that contains the original pin configuration detected by the BIOS / FreeBSD and the patched version:

hdaa0: Original pins configuration:
hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa0: 18 90a60130 3  0  Mic           Fixed Digital Internal   Unknown 1
hdaa0: 19 40000000 0  0  Line-out      None  Unknown 0x00       Unknown 0
hdaa0: 20 90170110 1  0  Speaker       Fixed Analog  Internal   Unknown 1
hdaa0: 21 03211040 4  0  Headphones    Jack  1/8     Left       Black   0
hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 24 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 25 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 26 03a11020 2  0  Mic           Jack  1/8     Left       Black   0
hdaa0: 27 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 29 40738105 0  5  Modem-handset None  ATAPI   0x00       Purple  1
hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: Patching widget caps nid=29 0x00400400 -> 0x00700400
hdaa0: Patching pin config nid=21 0x03211040 -> 0x0321101f
hdaa0: Patched pins configuration:
hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa0: 18 90a60130 3  0  Mic           Fixed Digital Internal   Unknown 1
hdaa0: 19 40000000 0  0  Line-out      None  Unknown 0x00       Unknown 0 DISA
hdaa0: 20 90170110 1  0  Speaker       Fixed Analog  Internal   Unknown 1
hdaa0: 21 0321101f 1  15 Headphones    Jack  1/8     Left       Black   0
hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 24 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 25 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 26 03a11020 2  0  Mic           Jack  1/8     Left       Black   0
hdaa0: 27 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA

You can see above that the original pin configuration had my internal speakers (nid 20) on as 1 seq 0 and the headphone jack (nid 21) was on as 4 seq 0. Placing the headphone jack on the same audio set as the internal speakers allows sound to flow to all channels on the same audio set. Using seq 15 is the special code that tells the system to automatically mute the device with the lowest seq number in the same audio set. Thus plugging in the headphones, mutes the internal speakers.

Touchpad (Tapping / Scrolling / Right Click)

The second issue is that you still need to get the gestures (two finger tap (right click), tap to click, etc).

In order to get gestures (scrolling, right click, tap to click, etc) you'll want to add the following into /usr/local/etc/X11/xorg.conf.d/40-libinput.conf:

Section "InputClass"
        Identifier "libinput touchpad catchall"
        MatchDriver "libinput"
        MatchIsTouchpad "on"
        MatchDevicePath "/dev/input/event*"
        Option "Tapping" "on"
EndSection

Xorg crashes after resuming from sleep

I haven't gotten to the bottom of this since I've switched to an X1 Carbon Gen 7, so I didn't have enough time to test this solution on this machine, but someone online mentioned the following options in /etc/sysctl.conf:

hw.usb.no_suspend_wait=1
kern.vt.suspendswitch=0
kern.vt.deadtimer=60