MacBookPro9,2 · A1278 · FreeBSD 15.1-RELEASE-p1 · zippy

FreeBSD 15 on a MacBook Pro Mid-2012

Complete setup guide — trackpad, display, brightness, keyboard backlight, function keys, lid close, KDE Plasma 6, and more.

Display & GPU Trackpad (gestures) Keyboard Audio + OSD KDE Plasma 6 Lid Close NetGear A6100 USB WiFi (2.4 & 5GHz) BCM4331 built-in (unsupported) S3 Sleep (broken)

Hardware Overview

ComponentHardwareDriverStatus
CPUIntel Core i5-3210M (Ivy Bridge, 2.5GHz, 2c/4t)cpufreqWorking
GPUIntel HD Graphics 4000i915kmsWorking
RAM16GB DDR3Working
Disk~900GB HDD (SATA)ahciWorking
AudioCirrus Logic CS4206 (Intel Panther Point HDA)snd_hdaWorking
TrackpadApple Wellspring5A (USB 0x05ac:0x0252)wsp + libinputWorking (gestures)
KeyboardApple USB (composite with trackpad)ukbd / evdevWorking
Screen BacklightIntel Panel/dev/backlight/intel_backlight0Working
Kbd BacklightApple SMCasmcWorking
EthernetBroadcom BCM57765bgeWorking
WiFi (USB dongle)NetGear A6100 (Realtek RTL8821AU)rtwnWorking — 2.4 & 5GHz
WiFi (built-in)Broadcom BCM4331bwn (no firmware)Not Supported
WebcamApple FaceTime HDwebcamdWorking
SMCApple System Management ControllerasmcWorking
BluetoothBCM2046Partial
S3 SleepBroken — do not use

What Works

FeatureNotes
Trackpad — tap, scroll, gesturesRequires hw.usb.usbhid.enable=0 + libinput — see step 1
Keyboard (all keys)evdev driver for kbdmux fixes X responsiveness
F1/F2 — Screen brightnessVia /dev/backlight/intel_backlight0 + xbindkeys script
F5/F6 — Keyboard backlightVia dev.asmc.0.light.control sysctl + xbindkeys script
F7/F8/F9 — Media keysplayerctl via xbindkeys
F10/F11/F12 — Volume + OSDKDE kglobalaccel → PulseAudio → plasma-pa OSD
F3/F4 — KonsoleXF86Launch1 / XF86LaunchA → konsole via xbindkeys
Ctrl+Alt+Fn VT switchingxkbcomp preserves XF86Switch_VT_N at XKB level 5
Audio — speakers, headphonesAuto-detected, no config needed
WiFi 2.4GHz + 5GHzNetGear A6100 USB dongle (rtwn driver)
GPU accelerationi915kms — KDE Plasma runs smoothly
Lid close → screen blankUPower DBus watcher + xset dpms — see step 10
Webcamwebcamd userspace driver
Ethernetbge0 — auto-detected
Power managementpowerd adaptive mode
Do Not Attempt S3 sleep (suspend to RAM) is broken on this hardware. The machine does not resume cleanly. Do not set hw.acpi.lid_switch_state=S3 or any sleep/hibernate actions in KDE Powerdevil.
1

Trackpad Fix — hw.usb.usbhid.enable=0

This is the most important fix. Understanding why it works will help you diagnose regressions.

The Problem

The Apple keyboard/trackpad is a single composite USB device (0x05ac:0x0252) with three HID interfaces:

USB Device 0x05ac:0x0252 (Wellspring5A ANSI)
├── Interface 0   HID Keyboard       (bInterfaceProtocol=0x01)
├── Interface 1   HID Touchpad       (bInterfaceProtocol=0x00)  ← wsp needs this
└── Interface 2   HID Consumer Ctrl  (bInterfaceProtocol=0x00)

FreeBSD has wsp, a driver written specifically for Apple trackpads — and 0x0252 is in its device table. But it never bound.

wsp is a uhub-level driver — it probes at the raw USB layer. usbhid is a bridge driver that by default claims every HID-class interface first, creating a hidbus for each one. Once usbhid claims Interface 1, the generic hms (basic mouse) driver attaches to the hidbus — and wsp never gets to probe at all. Result: basic mouse, no gestures, no /dev/wsp0.

Why blacklisting hms.ko alone didn't work Blacklisting hms.ko via devmatch_blacklist only stops devmatch from autoloading it. usbhid still claimed Interface 1 and created the hidbus. Without hms, the trackpad had no driver at all — wsp still wasn't reached because usbhid was still in the way.

The Fix

/boot/loader.conf
hw.usb.usbhid.enable=0

With usbhid disabled, the USB layer handles each interface directly:

With hw.usb.usbhid.enable=0 (working):
USB Device 0x05ac:0x0252
├── Interface 0 → ukbd1  → keyboard input
├── Interface 1 → wsp0   → /dev/wsp0 → moused → /dev/sysmouse
└── Interface 2 → (none)  → brightness/backlight via ACPI/SMC still works

Without it (broken default):
USB Device 0x05ac:0x0252
└── usbhid → hidbus
    ├── hkbd1  (keyboard)
    ├── hms1   (trackpad = basic mouse only, no gestures)
    └── hcons0 (consumer control / media keys)
Why brightness still works: F1/F2 brightness is handled by acpi_video via ACPI events, and keyboard backlight by asmc. Neither goes through hcons or usbhid.

Verify It Worked

dmesg | grep wsp
# Expected: wsp0 on uhub5
#           wsp0: <Apple Inc. Apple Internal Keyboard / Trackpad> on usbus2

ls /dev/wsp0 # should exist

rc.conf — moused

/etc/rc.conf
devmatch_blacklist="ums.ko bcm5974.ko"
moused_enable="YES"
moused_port="/dev/wsp0"
moused_flags="-t auto"

X11 Touchpad Config — libinput

/usr/local/etc/X11/xorg.conf.d/20-apple-touchpad.conf
Section "InputClass"
    Identifier "Apple Trackpad"
    MatchProduct "Apple Inc. Apple Internal Keyboard / Trackpad"
    Driver "libinput"
    Option "Tapping"           "on"
    Option "TappingButtonMap"  "lrm"
    Option "NaturalScrolling"  "true"
    Option "ScrollMethod"      "twofinger"
    Option "ClickMethod"       "clickfinger"
    Option "DisableWhileTyping" "true"
EndSection

# Prevent libinput from trying to open /dev/wsp0 directly — moused owns it
# and libinput segfaults (null deref) instead of returning "device busy"
Section "InputClass"
    Identifier "Ignore wsp0"
    MatchDevicePath "/dev/wsp0"
    Option "Ignore" "true"
EndSection

TappingButtonMap lrm: 1-finger tap = left, 2-finger tap = right, 3-finger = middle. Physical 2-finger click = right click. The second block matters even though wsp isn't fighting usbhid for the device — without it, libinput crashes Xorg with SIGSEGV whenever it probes /dev/wsp0 while moused already holds it.

wsp Sensitivity Tuning

/etc/sysctl.conf
hw.usb.wsp.enable_single_tap_clicks=1
hw.usb.wsp.pressure_tap_threshold=25
hw.usb.wsp.pressure_untouch_threshold=20
hw.usb.wsp.z_factor=6    # scroll speed (lower = slower)
hw.usb.wsp.scale_factor=6  # cursor speed (higher = faster)
A full reboot is required — not just logout. wsp must claim the USB interface at boot before usbhid could load.

Recurring Issue — USB Disconnect After Days of Uptime

After several days of uptime the trackpad goes dead — even at the SDDM login screen, before any user session starts. If it happens mid-session, Xorg can crash outright (SIGABRT on device removal), which can crash-loop kwin/plasmashell and, if the saved KWin session has stale window entries, respawn a storm of Konsole windows on every crash-loop restart.

Root cause: the SMSC 2.0 hub (ugen2.3, vendor 0x0424 product 0x2513) that hosts the internal Apple devices on usbus2 enters pwr=SAVE (USB autosuspend) and eventually drops the trackpad (ugen2.9, vendor 0x05ac product 0x0252) entirely. Per usbconfig(8), power_save is the default for all USB hubs — nothing has to go wrong first, the hub starts every boot in this state.

A devd rule alone is not enough Internal/on-board USB devices enumerate during kernel init (dmesg.boot shows them attaching around Root mount waiting for: usbus2) — well before devd itself starts as an rc.d service. devd never sees that first ATTACH event, so a devd rule is reactive only (catches a later genuine detach/reattach) and does nothing to stop the hub drifting into SAVE on every boot.

Fix, part 1 — boot-time rc.d script (does the real work)

/usr/local/etc/rc.d/apple_usb_power
#!/bin/sh
#
# PROVIDE: apple_usb_power
# REQUIRE: FILESYSTEMS
# KEYWORD: nojail

. /etc/rc.subr

name="apple_usb_power"
rcvar="apple_usb_power_enable"
start_cmd="apple_usb_power_start"

apple_usb_power_start()
{
	for dev in $(usbconfig list | cut -d: -f1); do
		desc=$(usbconfig -d "${dev}" dump_device_desc 2>/dev/null)
		if echo "${desc}" | grep -q "idVendor = 0x0424" && \
		   echo "${desc}" | grep -q "idProduct = 0x2513"; then
			usbconfig -d "${dev}" power_on
		fi
		if echo "${desc}" | grep -q "idVendor = 0x05ac" && \
		   echo "${desc}" | grep -q "idProduct = 0x0252"; then
			usbconfig -d "${dev}" power_on
		fi
	done
}

load_rc_config $name
run_rc_command "$1"

Matches devices by vendor:product ID rather than a hardcoded ugen name, so it survives renumbering across reboots. Enable and test:

sudo chmod 555 /usr/local/etc/rc.d/apple_usb_power
sudo sysrc apple_usb_power_enable="YES"
sudo service apple_usb_power start
sudo usbconfig list | grep -E "ugen2\.[39]"   # hub should now show pwr=ON
rcorder places this right after FILESYSTEMS, well before SDDM starts — verify with rcorder /usr/local/etc/rc.d/apple_usb_power /etc/rc.d/*.

Fix, part 2 — devd rule (secondary, catches genuine runtime reconnects)

/usr/local/etc/devd/apple-usb-power.conf
notify 100 {
    match "system" "USB";
    match "subsystem" "DEVICE";
    match "type" "ATTACH";
    match "vendor" "0x0424";
    match "product" "0x2513";
    action "usbconfig -d $device-name power_on";
};

notify 100 {
    match "system" "USB";
    match "subsystem" "DEVICE";
    match "type" "ATTACH";
    match "vendor" "0x05ac";
    match "product" "0x0252";
    action "usbconfig -d $device-name power_on";
};

If it disconnects again despite both fixes

sudo usbconfig list | grep -E "ugen2\.[39]"       # check current pwr= state
sudo service apple_usb_power start                # force power_on immediately
sudo service moused restart
sudo service sddm restart                          # if Xorg crashed

If power_on still doesn't hold across days, add hw.usb.no_suspend_wait=1 to /etc/sysctl.conf as a more aggressive suspend-prevention measure. If Xorg crashing triggers a KWin crash-loop, a bloated saved session (~/.config/session/kwin_saved*) can respawn dozens of Konsole windows on every restart — fix with pkill -9 -u joe konsole then clear/trim that session file.

2

Display / GPU — i915kms

Intel HD Graphics 4000 (Ivy Bridge) via the i915kms Linux KMS compatibility driver. GPU acceleration works for KDE Plasma 6.

/boot/loader.conf
i915kms_load="YES"

On boot you'll see the VT switch from efifb to drmfb in dmesg — this is normal. Xorg requires /dev/dri/card0 which this module creates; without it X fails with a fatal error at a black screen.

Install the Xorg Intel driver: pkg install xf86-video-intel

Major Version Upgrades — drm-kmod Breakage

i915kms is not part of base — it ships in the graphics/drm-66-kmod package, built against one specific kernel ABI (__FreeBSD_version / kern.osreldate). A freebsd-update version bump (e.g. 15.0 → 15.1) installs a new kernel but does not touch /boot/modules/*.ko — those come from pkg, not freebsd-update.

Symptom Kernel panic on boot shortly after freebsd-update install + reboot into the new kernel. Recovery requires single-user mode to disable the module before the system boots normally again.

1 — In single-user mode, disable i915kms so the box boots

sysrc -f /boot/loader.conf -x i915kms_load
sysrc kld_list=""

Reboot to confirm the stale module was the cause — you'll be back to multi-user, but with no GPU driver: Xorg fails with open /dev/dri/card0: No such file or directory (expected, no black-screen mystery).

2 — Finish the freebsd-update upgrade

A panic on first reboot usually means you're mid-upgrade (kernel installed, userland not yet):

freebsd-version -k   # kernel version
freebsd-version -u   # userland version — if these differ, finish the upgrade:
sudo freebsd-update install
sudo pkg update -f
sudo freebsd-update install   # second pass, installs userland

3 — Get a kernel-matched drm-kmod build

pkg upgrade alone will likely report drm-kmod as "up to date" even when it isn't. drm-66-kmod is provided by two repos — the general FreeBSD-ports repo (lags behind, keeps an older build) and FreeBSD-ports-kmods (tracks the current kernel ABI). Plain pkg upgrade can silently pick the stale one.

sysctl kern.osreldate                              # e.g. 1501000
pkg info drm-66-kmod | grep FreeBSD_version         # must match osreldate above
pkg rquery -r FreeBSD-ports-kmods "%n %v" drm-66-kmod

If the installed FreeBSD_version doesn't match kern.osreldate, force it explicitly:

sudo pkg upgrade -r FreeBSD-ports-kmods drm-66-kmod drm-kmod

4 — Re-enable and test

No fresh reboot needed to test — kldload does the same attach as boot-time loading, and lets you watch dmesg live instead of guessing from a cold boot:

sudo kldload i915kms
dmesg | tail -20   # look for "[drm] Initialized i915 ..." and "Replacing driver efifb with drmfb"
ls /dev/dri/        # card0 should exist
sudo service sddm restart

Once confirmed working, make it permanent:

sudo sysrc -f /boot/loader.conf i915kms_load="YES"
sudo sysrc kld_list="i915kms"
Key takeaway After any freebsd-update that bumps the kernel version, drm-kmod needs to be re-matched via pkg upgrade -r FreeBSD-ports-kmods drm-66-kmod before re-enabling i915kms_load — don't just re-enable the old config and reboot, it'll panic again.
3

Keyboard Fix — evdev for kbdmux

The keyboard works fine in TTY but feels laggy in X. The cause: libinput applies debounce/fuzz filtering to the kbdmux (keyboard multiplexer) device, making keys feel sluggish and unresponsive.

Fix: force the evdev driver for the kbdmux device instead of libinput.

/usr/local/etc/X11/xorg.conf.d/10-keyboard.conf
Section "InputClass"
    Identifier   "kbdmux evdev"
    MatchProduct "System keyboard multiplexer"
    Driver       "evdev"
EndSection
/etc/sysctl.conf
# KBDMUX(2) + HID_MOUSE(4) + HID_KBD(8) = 14
kern.evdev.rcpt_mask=14
Use 14, not 12. Value 12 omits KBDMUX(2), which breaks TTY keyboard input and Ctrl+Alt+Fn VT switching. SYSMOUSE(1) is intentionally excluded — moused feeds /dev/sysmouse directly, so including it would cause double mouse events.
4

Screen Brightness — Intel Backlight Device

Brightness is controlled via /dev/backlight/intel_backlight0, exposed by i915kms. The acpi_video sysctl nodes (hw.acpi.video.lcd0.*) exist but do not control the actual display on this hardware — use the backlight device directly.

Load acpi_video at boot (still needed for F-key keysym generation, even though the sysctl path doesn't work for brightness):

/boot/loader.conf
acpi_video_load="YES"

The video group owns the backlight device — no sudo needed:

pw groupmod video -m joe

Manual control

# Check current level (0–100)
backlight -f /dev/backlight/intel_backlight0

# Set level
backlight -f /dev/backlight/intel_backlight0 70

~/bin/brightness.sh — F1 / F2 hotkeys

~/bin/brightness.sh
#!/bin/sh
BACKLIGHT="/dev/backlight/intel_backlight0"
STEP=10
current=$(backlight -f "$BACKLIGHT" | awk '{print $2}')
case "$1" in
    up)   new=$(( current + STEP )); [ "$new" -gt 100 ] && new=100 ;;
    down) new=$(( current - STEP )); [ "$new" -lt  10 ] && new=10  ;;
esac
backlight -f "$BACKLIGHT" "$new"

Bound in ~/.xbindkeysrc:

"$HOME/bin/brightness.sh down"
  XF86MonBrightnessDown

"$HOME/bin/brightness.sh up"
  XF86MonBrightnessUp
5

Keyboard Backlight — asmc

The Apple SMC driver (asmc) is supported out of the box on FreeBSD 15 for MacBookPro9,2. No patching required.

/boot/loader.conf
asmc_load="YES"
/etc/sysctl.conf
# Keyboard backlight brightness — range 0–255
dev.asmc.0.light.control=100

Manual control

sysctl dev.asmc.0.light.control=150

~/bin/kbd-brightness.sh — F5 / F6 hotkeys

~/bin/kbd-brightness.sh
#!/bin/sh
STEP=30
current=$(sysctl -n dev.asmc.0.light.control)
case "$1" in
    up)   new=$(( current + STEP )); [ "$new" -gt 255 ] && new=255 ;;
    down) new=$(( current - STEP )); [ "$new" -lt   0 ] && new=0   ;;
esac
sysctl dev.asmc.0.light.control="$new" >/dev/null

Bound in ~/.xbindkeysrc to XF86KbdBrightnessDown / XF86KbdBrightnessUp.

6

Function Keys — xkbcomp + xbindkeys

The MacBook top-row keys send plain F1–F12 keycodes in X. They must be remapped to XF86 media keysyms. Use xkbcomp — not xmodmap. xmodmap wipes XKB level 5 (the Ctrl+Alt level) where XF86Switch_VT_N lives, which breaks Ctrl+Alt+Fn VT switching entirely.

~/.xkb_macbook.xkb

Generate a base keymap and edit the FK01–FK12 entries to put XF86 keysyms at levels 1–4 and preserve XF86Switch_VT_N at level 5:

# Generate base keymap from current X state
setxkbmap us
xkbcomp :0 ~/.xkb_macbook.xkb

# Edit FK01–FK12 entries to read, e.g.:
# key <FK01> { type="CTRL+ALT", symbols[Group1]= [
#   XF86MonBrightnessDown, XF86MonBrightnessDown,
#   XF86MonBrightnessDown, XF86MonBrightnessDown,
#   XF86Switch_VT_1 ] };
# ... and so on for FK02–FK12

# Apply immediately
xkbcomp ~/.xkb_macbook.xkb $DISPLAY

The CTRL+ALT key type maps: level 1 = unmodified, level 5 = Ctrl+Alt. The X server sees XF86Switch_VT_N on Ctrl+Alt+Fn and switches VT directly — no daemon needed.

Add to KDE autostart:

~/.config/autostart/xmodmap.desktop
[Desktop Entry]
Type=Application
Name=xkb macbook keys
Exec=xkbcomp /home/joe/.xkb_macbook.xkb %DISPLAY
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true

~/.xbindkeysrc

# Screen brightness — F1 / F2
"$HOME/bin/brightness.sh down"
  XF86MonBrightnessDown

"$HOME/bin/brightness.sh up"
  XF86MonBrightnessUp

# Keyboard backlight — F5 / F6
"$HOME/bin/kbd-brightness.sh down"
  XF86KbdBrightnessDown

"$HOME/bin/kbd-brightness.sh up"
  XF86KbdBrightnessUp

# Media keys — F7 / F8 / F9
"playerctl previous"
  XF86AudioPrev

"playerctl play-pause"
  XF86AudioPlay

"playerctl next"
  XF86AudioNext

# F3 — Konsole
"konsole"
  XF86Launch1

# F4 — Konsole
"konsole"
  XF86LaunchA

# Right-click workaround (Ctrl + click)
"xdotool click 3"
  control + b:1
Do not add XF86AudioMute, XF86AudioLowerVolume, or XF86AudioRaiseVolume to xbindkeys. xbindkeys grabs keys before KDE's kglobalaccel can claim them — if xbindkeys owns the volume keysyms, the KDE OSD will never appear. Volume is handled by KDE's audioshortcutsservice automatically.
KeyAction
F1 / F2Screen brightness down / up
F3 / F4New Konsole window
F5 / F6Keyboard backlight down / up
F7 / F8 / F9Media: Prev / Play-Pause / Next
F10 / F11 / F12Mute / Volume down / Volume up (KDE OSD)
Ctrl+Alt+F1–F8VT switching (X server native via xkbcomp level 5)
7

Volume Keys & KDE OSD

The Cirrus Logic CS4206 is detected automatically by snd_hda. Volume key control (F10/F11/F12) and the KDE OSD popup are handled through PulseAudio and the plasma6-plasma-pa Plasma applet.

Install plasma-pa

sudo pkg install plasma6-plasma-pa

Log out and back in. The volume icon will appear in the system tray and the OSD will show on F10/F11/F12.

How it works

xkbcomp maps F10/F11/F12 to XF86AudioMute / XF86AudioLowerVolume / XF86AudioRaiseVolume at XKB level 1. KDE's audioshortcutsservice (a kded module) registers these as global shortcuts via kglobalaccel, routes changes through PulseAudio, and plasma-pa displays the OSD.

F10/F11/F12
  → xkbcomp (XF86Audio* keysyms at XKB level 1)
  → kglobalaccel → audioshortcutsservice (kded)
  → PulseAudio → plasma-pa applet
  → volume OSD popup ✓
Critical Do not bind volume keysyms in xbindkeys. If xbindkeys claims XF86AudioMute/LowerVolume/RaiseVolume, it wins the X11 key grab before kglobalaccel — KDE never sees the keypresses and the OSD never fires. These three keysyms must be absent from ~/.xbindkeysrc.

Manual volume via mixer: mixer vol.volume=+5% (relative) · mixer vol.volume=0.75 (absolute) · mixer vol.mute=toggle

8

Audio

The Cirrus Logic CS4206 is detected automatically — no configuration needed beyond the default FreeBSD install.

DeviceDescription
pcm0Internal speakers (system default)
pcm1Analog headphone jack
pcm2Digital output (S/PDIF)
cat /dev/sndstat   # list devices and their state
mixer              # check/set volume
9

WiFi — BCM4331 Not Supported + USB Dongle

Built-in WiFi Not Supported The Broadcom BCM4331 requires 5th generation proprietary firmware. FreeBSD's bwn driver only supports 4th gen. b43-fwcutter cannot extract the required firmware. A USB WiFi adapter is required.
Confirmed Working — Buy This NetGear A6100 (Realtek RTL8821AU chipset) — plug-and-play on FreeBSD 15. Auto-loads the rtwn driver with no firmware or configuration needed. Supports 2.4GHz and 5GHz (802.11ac/VHT80). Tested on this exact machine.

Setup

/etc/rc.conf
wlans_rtwn0="wlan0"
ifconfig_wlan0="WPA DHCP"
/etc/wpa_supplicant.conf
network={
    ssid="YourNetworkName"
    psk="YourPassword"
}

Verify

dmesg | grep rtwn
# rtwn0: <Realtek RTL8821AU...>
# rtwn0: MAC/BB RTL8821AU, RF 6052 1T1R

ifconfig wlan0  # shows IP, SSID, channel
A harmless dmesg message appears: ieee80211_sta_join: BSS ...: 2GHz channel, VHT info; ignoring — your router is advertising 802.11ac capabilities on 2.4GHz (invalid). The driver correctly ignores it and connects normally.
10

Lid Close — Screen Blank

S3 sleep is broken on this hardware. The solution is to blank the screen on lid close using a UPower DBus watcher, with KDE Powerdevil's lid action disabled entirely.

Why the obvious approaches don't work

devd rules: ACPI lid events do not reach /dev/devctl on this machine — closing the lid produces nothing on devctl. A devd rule matching system="ACPI" subsystem="Lid" is inert here.

KDE Powerdevil lid actions: All broken or wrong. The Plasma 6 LidAction values mapped by trial and error:

ValueAction
0Nothing ← use this
8Hibernate
16Show logout/session dialog
32Lock screen
64Invisible input grab — desktop looks normal but nothing is clickable
The default value (64) is the worst outcome: kscreenlocker grabs all X input without rendering any visible UI. The desktop looks normal but is completely unresponsive after opening the lid.

Fix — Part 1: Disable KDE lid action

~/.config/powerdevilrc
[AC][SuspendAndShutdown]
AutoSuspendAction=0
LidAction=0

[Battery][SuspendAndShutdown]
LidAction=0

Fix — Part 2: UPower DBus watcher

UPower already tracks lid state (KDE uses it internally). This script taps that existing signal:

/usr/local/bin/lid-screen.sh
#!/bin/sh
export DISPLAY=:0

dbus-monitor --system \
    "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/freedesktop/UPower'" |
awk '
/string "LidIsClosed"/ { wait=1; next }
wait && /boolean true/  { system("xset dpms force off"); wait=0 }
wait && /boolean false/ { wait=0 }
'
chmod +x /usr/local/bin/lid-screen.sh
~/.config/autostart/lid-screen.desktop
[Desktop Entry]
Type=Application
Name=Lid Screen Blank
Exec=/usr/local/bin/lid-screen.sh
Restart=always
X-KDE-autostart-phase=1

Result

  • Close lid → screen goes dark immediately
  • Open lid → DPMS wakes on first mouse movement or keypress
  • No input grab, no lock screen, no partial suspend — everything is clickable after open
11

KDE Plasma 6 Desktop

Minimal KDE Plasma 6 install with SDDM display manager. Wayland does not work on this hardware — use the X11 session.

Install Plasma 6 (minimal)

pkg install plasma6-kwin-x11 plasma6-plasma-workspace plasma6-plasma-desktop \
  plasma6-systemsettings plasma6-kscreenlocker plasma6-polkit-kde-agent-1 \
  plasma6-xdg-desktop-portal-kde plasma6-plasma-activities \
  plasma6-plasma-activities-stats plasma6-breeze plasma6-libkscreen \
  plasma6-kscreen plasma6-powerdevil plasma6-ksystemstats \
  plasma6-libksysguard plasma6-kde-cli-tools plasma6-kdecoration \
  plasma6-kactivitymanagerd plasma6-kglobalacceld plasma6-milou \
  plasma6-plasma-pa sddm konsole

KDE Apps

pkg install dolphin ark kate gwenview okular plasma6-spectacle networkmgr

Enable SDDM

sysrc lightdm_enable="NO"
sysrc sddm_enable="YES"
At the SDDM login screen, click the session selector and choose Plasma (X11) — NOT Wayland. Wayland will produce a black screen on this hardware.
If Plasma logs you back to SDDM immediately with a black screen, check ~/.local/share/sddm/xorg-session.log. The most common cause is a missing package — usually plasma6-kactivitymanagerd (included above).

Why Wayland Specifically Fails: kwin_wayland SIGSEGV

Beyond the missing Qt Wayland platform plugin, kwin_wayland also hits a real crash: a Qt 6.11.1 bug where QKdeTheme::createKdeTheme() SIGSEGVs in handleThemeChanged() because KDE_SESSION_VERSION is set in the environment (injected by SDDM for KDE sessions) before a required global is initialized.

Fix: replace the real binary with a wrapper that strips the offending env vars before exec'ing it:

sudo mv /usr/local/bin/kwin_wayland /usr/local/bin/kwin_wayland.bin
sudo tee /usr/local/bin/kwin_wayland <<'EOF'
#!/bin/sh
exec env -u KDE_SESSION_VERSION -u KDE_FULL_SESSION /usr/local/bin/kwin_wayland.bin "$@"
EOF
sudo chmod 755 /usr/local/bin/kwin_wayland
Regresses on every kwin upgrade pkg upgrade of plasma6-kwin overwrites /usr/local/bin/kwin_wayland with the raw binary, silently dropping the wrapper (confirmed happened 2026-07-07, caught and reapplied 2026-07-09). Not urgent day-to-day since this machine runs the X11 session — check file /usr/local/bin/kwin_wayland after KDE package upgrades if Wayland is ever tried again; it should say POSIX shell script, not ELF 64-bit.
12

Webcam

The Apple FaceTime HD camera uses the webcamd userspace driver.

pkg install webcamd
sysrc webcamd_enable="YES"
pw groupmod webcamd -m joe
service webcamd start
Log out and back in after adding yourself to the webcamd group for the change to take effect.

Packages Installed

PackagePurpose
doas / sudoPrivilege escalation (sudo needed for non-TTY X session contexts)
xf86-video-intelIntel GPU Xorg driver
xf86-input-libinputlibinput Xorg input driver (trackpad)
plasma6-*KDE Plasma 6 desktop (see step 11)
plasma6-plasma-paPulseAudio Plasma applet + volume OSD
sddmDisplay manager
konsoleKDE terminal emulator
dolphinFile manager
ark / kate / gwenview / okularArchive / editor / image / document viewers
plasma6-spectacleScreenshot tool
networkmgrFreeBSD WiFi/network manager GUI
webcamdWebcam userspace driver
xbindkeysKey binding daemon (brightness, media, konsole hotkeys)
xdotoolX input simulation (right-click workaround)
xprintidleX idle time detection
playerctlMedia player control (F7/F8/F9)
deskflowKVM software (keyboard/mouse sharing)
firefoxWeb browser
gitSource control
rustRust compiler
libreofficeOffice suite
cupsPrinting

Final Configuration Files

/boot/loader.conf
kern.geom.label.disk_ident.enable="0"
kern.geom.label.gptid.enable="0"
zfs_load="YES"
i915kms_load="YES"
wsp_load="YES"
asmc_load="YES"
acpi_video_load="YES"
coretemp_load="YES"
hw.usb.usbhid.enable=0
kern.hz=100
vfs.zfs.arc_max="4294967296"
/etc/rc.conf
hostname="zippy"
ifconfig_bge0="DHCP"
ifconfig_bge0_ipv6="inet6 accept_rtadv"
sshd_enable="YES"
powerd_enable="YES"
powerd_flags="-b adaptive -a adaptive -i 25 -r 85 -N"
moused_nondefault_enable="NO"
dumpdev="NO"
zfs_enable="YES"
dbus_enable="YES"
lightdm_enable="NO"
devmatch_blacklist="ums.ko bcm5974.ko"
moused_enable="YES"
moused_port="/dev/wsp0"
moused_flags="-t auto"
webcamd_enable="YES"
sddm_enable="YES"
apple_usb_power_enable="YES"
wlans_rtwn0="wlan0"
ifconfig_wlan0="WPA DHCP"
cupsd_enable="YES"
avahi_daemon_enable="NO"
/etc/sysctl.conf
vfs.zfs.vdev.min_auto_ashift=12
kern.evdev.rcpt_mask=14       # KBDMUX(2)+HID_MOUSE(4)+HID_KBD(8) — do NOT use 12
dev.asmc.0.light.control=100
hw.usb.wsp.enable_single_tap_clicks=1
hw.usb.wsp.pressure_tap_threshold=25
hw.usb.wsp.pressure_untouch_threshold=20
hw.usb.wsp.z_factor=6
hw.usb.wsp.scale_factor=6
hw.pci.do_power_nodriver=3
dev.asmc.0.fan.0.minspeed=3000
kern.coredump=0
/usr/local/etc/X11/xorg.conf.d/10-keyboard.conf
Section "InputClass"
    Identifier   "kbdmux evdev"
    MatchProduct "System keyboard multiplexer"
    Driver       "evdev"
EndSection
/usr/local/etc/X11/xorg.conf.d/20-apple-touchpad.conf
Section "InputClass"
    Identifier "Apple Trackpad"
    MatchProduct "Apple Inc. Apple Internal Keyboard / Trackpad"
    Driver "libinput"
    Option "Tapping"           "on"
    Option "TappingButtonMap"  "lrm"
    Option "NaturalScrolling"  "true"
    Option "ScrollMethod"      "twofinger"
    Option "ClickMethod"       "clickfinger"
    Option "DisableWhileTyping" "true"
EndSection

Section "InputClass"
    Identifier "Ignore wsp0"
    MatchDevicePath "/dev/wsp0"
    Option "Ignore" "true"
EndSection

See USB Disconnect fix for /usr/local/etc/rc.d/apple_usb_power and /usr/local/etc/devd/apple-usb-power.conf — omitted here for space.

KDE Autostart (~/.config/autostart/)

xmodmap.desktop          → xkbcomp /home/joe/.xkb_macbook.xkb %DISPLAY
xbindkeys.desktop        → xbindkeys
kbd-backlight-daemon.desktop → /home/joe/bin/kbd-backlight-daemon.sh
lid-screen.desktop       → /usr/local/bin/lid-screen.sh

Scripts (~/bin/)

brightness.sh       → F1/F2 screen brightness via /dev/backlight/intel_backlight0
kbd-brightness.sh   → F5/F6 keyboard backlight via dev.asmc.0.light.control

F10/F11/F12 volume is handled entirely by KDE's audioshortcutsservice via kglobalaccel — no shell script involved. Do not bind these in xbindkeys.

How to Revert

Revert trackpad to basic mouse only

  1. Remove hw.usb.usbhid.enable=0 from /boot/loader.conf
  2. Reboot

The trackpad falls back to hms (basic mouse, no gestures). /dev/wsp0 won't exist — moused fails silently — but the trackpad still works as a basic mouse through X11 evdev. hcons returns, restoring full HID media key events.

Revert X11 touchpad config to synaptics

Replace /usr/local/etc/X11/xorg.conf.d/20-apple-touchpad.conf with:

Section "InputClass"
    Identifier "Apple Touchpad synaptics"
    MatchProduct "Apple Inc. Apple Internal Keyboard / Trackpad Touchpad"
    Driver "synaptics"
    Option "Protocol"       "event"
    Option "TapButton1"     "1"
    Option "TapButton2"     "3"
    Option "RTCornerButton" "3"
    Option "VertEdgeScroll" "on"
    Option "FingerLow"      "1"
    Option "FingerHigh"     "5"
    Option "MinPressure"    "0"
    Option "MaxPressure"    "255"
EndSection
?

Troubleshooting

/dev/wsp0 doesn't exist after reboot

dmesg | grep wsp
sudo usbconfig list | grep -i trackpad
kldstat | grep wsp

Verify hw.usb.usbhid.enable=0 and wsp_load="YES" are in /boot/loader.conf.

Trackpad moves but no tap or scroll

xinput list  # Apple trackpad should appear as a pointer device
grep -i "libinput\|trackpad\|apple" /var/log/Xorg.0.log

Cursor / scroll speed adjustment

sysctl hw.usb.wsp.scale_factor=8   # cursor (default 6, higher = faster)
sysctl hw.usb.wsp.z_factor=4       # scroll (default 6, lower = slower)

Add to /etc/sysctl.conf to persist.

Brightness keys not working

kldstat | grep acpi_video
ls -la /dev/backlight/intel_backlight0

Ensure acpi_video_load="YES" and i915kms_load="YES" are in /boot/loader.conf. Ensure your user is in the video group: id | grep video.

Keyboard backlight not responding

kldstat | grep asmc
sysctl dev.asmc.0.light.control=200

Ensure asmc_load="YES" is in /boot/loader.conf.

Ctrl+Alt+Fn VT switching not working

Almost always caused by xmodmap wiping the XKB keymap. Verify the correct keymap is applied:

xkbcomp :0 /tmp/check.xkb && grep -A3 "key <FK01>" /tmp/check.xkb

You should see XF86Switch_VT_1 at position 5. If you see NoSymbol there, xmodmap has run and wiped level 5. Reapply:

xkbcomp ~/.xkb_macbook.xkb $DISPLAY

Volume OSD not appearing (F10/F11/F12)

pkg info plasma6-plasma-pa
ps aux | grep pulse
grep -i "XF86Audio" ~/.xbindkeysrc  # must return nothing

If any XF86Audio* bindings appear in xbindkeys, remove them — then reload:

killall xbindkeys && xbindkeys

After opening lid — desktop visible but nothing clickable

KDE Powerdevil's lid action grabbed X input without a visible UI. Check:

grep LidAction ~/.config/powerdevilrc

Should be LidAction=0. If it's 64, that's the culprit. Fix: set LidAction=0 in all [SuspendAndShutdown] sections and use the UPower DBus script instead. If stuck right now: type your login password and press Enter — kscreenlocker may be running invisibly and that may dismiss it.

WiFi — harmless dmesg noise

ieee80211_sta_join: BSS ...: 2GHz channel, VHT info; ignoring — router is advertising 802.11ac on 2.4GHz (invalid). Driver ignores it, connects normally. Not a bug.

Kernel panics on boot right after a freebsd-update version bump

This is drm-kmod ABI breakage — see Major Version Upgrades for the full recovery procedure. Short version: boot single-user, sysrc -f /boot/loader.conf -x i915kms_load and sysrc kld_list="" to get back to multi-user, finish the freebsd-update, then pkg upgrade -r FreeBSD-ports-kmods drm-66-kmod before re-enabling i915kms.

Trackpad dead again after days of uptime, or dead at the SDDM login screen

See Recurring Issue — USB Disconnect. Quick check: sudo usbconfig list | grep -E "ugen2\.[39]" — if the hub shows pwr=SAVE, run sudo service apple_usb_power start to force it back on immediately.

Wayland session (kwin_wayland) SIGSEGVs again after a KDE package upgrade

pkg upgrade of plasma6-kwin overwrites /usr/local/bin/kwin_wayland with the raw binary, silently dropping the wrapper. See KDE Plasma 6 → Why Wayland Specifically Fails for the reapply command. Not urgent day-to-day since this machine runs Session=plasmax11 (X11).