Jump to content

GPD Pocket 4

From ArchWiki

This article or section does not follow the Laptop page guidelines.

Reason: Misses an Accessibility section. (Discuss in Talk:GPD Pocket 4)
Hardware PCI/USB ID Working?
HX 370 8840U
GPU 1002:150e 1002:1900 Yes
Wi-Fi 8086:2725 Yes
Bluetooth 8087:0032 Yes
Audio 1022:15e3 Yes
Touchscreen 0603:F001 Yes
Keyboard/Pointer 258a:000c Yes
Webcam 1bcf:28c4 1e08:5520 Yes
Fingerprint 2808:0752 Partial
Accelerometer Yes

The GPD Pocket 4 is a compact 8.8" convertible laptop with a 1600x2560 portrait display, touchscreen, and accelerometer for tablet mode.

Note A third configuration ships with the Ryzen AI 9 HX 365 (Radeon 880M); its IDs are not documented here. Identify yours with lspci -nn and lsusb — the GPU and webcam are the parts known to differ between configurations.

Screen orientation

The display panel is physically portrait (1600x2560) and requires rotation for normal laptop use: see Tablet PC#Screen rotation.

Touchscreen

The touchscreen (NVTK0603) requires calibration to match the display rotation.

Hyprland

Add a device section to your Hyprland configuration:

device {
    name = nvtk0603:00-0603:f001
    transform = 3
}
Note The transform value must match your monitor transform.

Wayland (udev)

For other Wayland compositors, create:

/etc/udev/rules.d/99-touchscreen.conf

ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="NVTK0603:00 0603:F001", ENV{LIBINPUT_CALIBRATION_MATRIX}="0 1 0 -1 0 1"

Then reload udev rules.

Xorg

Install xf86-input-wacom and create /etc/X11/xorg.conf.d/99-touchscreen.conf:

Section "InputClass"
    Identifier    "GPD Pocket 4 Touchscreen"
    Driver        "wacom"
    MatchProduct  "NVTK0603"
    Option        "TransformationMatrix" "0 1 0 -1 0 1 0 0 1"
EndSection

Automatic rotation

The GPD Pocket 4 has an accelerometer (MXC6655) that can be used for automatic screen rotation in tablet mode, see Tablet PC#Automatic rotation.

Warning The orientation mapping differs between variants — verify it on your own machine before relying on it. Using the wrong mapping leaves the display rotated 90° out.

Reported mappings, given as monitor-sensor orientation to Hyprland transform:

Variant Laptop mode reports normal left-up right-up bottom-up
HX 370 normal 3 0 2 1
8840U right-up 0 1 3 2

On the 8840U the table is rotated 90° relative to the HX 370: laptop position reports right-up, not normal.

To determine yours, run monitor-sensor (from iio-sensor-proxy) and hold the machine in each of the four orientations, noting which label is reported when the screen is upright.

Touchscreen gestures

For touch gestures (swipe to switch workspaces, etc.), install lisgdAUR from the AUR.

Create a gesture script (e.g., ~/.config/hypr/scripts/touchscreen-gestures.sh):

#!/bin/bash
# GPD Pocket 4 touchscreen gestures using lisgd
# Accepts orientation parameter: 0, 1, 2, 3 (matches Hyprland transform)

if [ -z "$CALLED_FROM_AUTOROTATE" ]; then
    pkill -f "lisgd" 2>/dev/null
    sleep 0.3
fi

DEVICE="/dev/input/event10"  # Adjust if needed
TRANSFORM="${1:-3}"  # Default to laptop mode (transform 3)

# Commands - customize as needed
WS_PREV="hyprctl dispatch workspace e-1"
WS_NEXT="hyprctl dispatch workspace e+1"
OVERVIEW="hyprctl dispatch overview:toggle"

# Map Hyprland transform to lisgd orientation (-o flag)
case "$TRANSFORM" in
    3) LISGD_ORIENT=0 ;;  # Laptop mode
    0) LISGD_ORIENT=1 ;;  # Portrait left
    1) LISGD_ORIENT=2 ;;  # Laptop upside down
    2) LISGD_ORIENT=3 ;;  # Portrait right
esac

lisgd -d "$DEVICE" -o "$LISGD_ORIENT" \
    -g "3,LR,*,0.08,$WS_PREV" \
    -g "3,RL,*,0.08,$WS_NEXT" \
    -g "3,UD,*,0.08,$OVERVIEW" \
    -g "3,DU,*,0.08,$OVERVIEW" \
    -t 150 -r 25 &
Note The -o flag enables rotation-aware gestures. The DEVICE path may vary; check /dev/input/ for your touchscreen device.

Add to Hyprland startup:

exec-once = ~/.config/hypr/scripts/touchscreen-gestures.sh

To integrate with auto-rotation, modify the auto-rotation script to restart the gesture script with the new orientation when rotation changes. See the auto-rotation section for details.

Backlight

The backlight is controlled via /sys/class/backlight/amdgpu_bl1/.

Install brightnessctl for easy control:

$ brightnessctl s 5%+   # increase
$ brightnessctl s 5%-   # decrease

Function keys

Key Visible?1 Marked?2 Effect
Fn+Insert Yes Yes XF86MonBrightnessUp
Fn+PrintSc Yes Yes XF86MonBrightnessDown
Fn+[ Yes Yes XF86AudioMute
Fn+] Yes Yes XF86AudioLowerVolume
Fn+\ Yes Yes XF86AudioRaiseVolume
Fn+Space No Yes Keyboard backlight toggle3
Fn+= No Yes Fan speed cycle3
  1. Visible to wev, xev, and similar tools.
  2. The key has a physical symbol describing its function.
  3. Controlled by keyboard/EC firmware, not configurable from the OS.

Touchpad

The GPD Pocket 4's pointing device (HAILUCK USB KEYBOARD Mouse) is detected by libinput as a basic pointer rather than a touchpad, which means standard touchpad gesture tools like libinput-gestures will not work.

$ libinput list-devices | grep -A5 "HAILUCK.*Mouse"
Capabilities:            pointer
Tap-to-click:            n/a
Scroll methods:          button

For swipe gestures, use the touchscreen gesture solution above instead.

Fingerprint reader

The FocalTech reader (2808:0752) is not supported by upstream libfprint: its focaltech_moc driver has a hardcoded product ID allowlist that does not include 0752, so fprintd-list reports No devices available even though the device enumerates correctly.

It does work with the proprietary FocalTech TOD driver packaged as libfprint-ft9201AUR, which conflicts with and replaces libfprint.

Warning This is a closed-source vendor blob. The original upstream repository was removed from GitHub by a DMCA notice in October 2025, and the package now sources from a community mirror. Keep a local copy of the built package, and revert with pacman -S libfprint if needed.

After installing, enrol and then verify — enrolment succeeding does not prove that matching works:

$ fprintd-enroll
$ fprintd-verify

Fingerprint stops working after suspend

fprintd normally closes the reader before suspend using a systemd logind sleep-delay inhibitor. If it is D-Bus activated late in the suspend sequence — for example by a lock screen that runs as the machine is going to sleep — that inhibitor request fails:

fprintd: Failed to install a sleep delay inhibitor: org.freedesktop.login1.OperationInProgress

The reader is USB-reset on resume, leaving fprintd holding a stale handle. All subsequent authentication then fails immediately, and because pam_fprintd returns PAM_AUTHINFO_UNAVAIL without contacting the daemon, fprintd itself logs nothing. Diagnose with:

$ fprintd-verify
failed to claim device: ... Open failed with error: The device has already been opened!

Work around it by stopping fprintd before sleep and starting it again afterwards, with two units:

  • a stop unit, ordered Before=sleep.target and enabled through it. One target is enough here, because sleep.target is pulled in by every kind of sleep.
  • a start unit, ordered after and enabled through suspend.target, hibernate.target, hybrid-sleep.target and suspend-then-hibernate.target.

fprintd.service is Type=dbus, so it is reactivated on demand.

Warning Enabling the start unit through suspend.target alone is not enough: hibernation and suspend-then-hibernate reach hibernate.target and suspend-then-hibernate.target and never suspend.target, so after a hibernate the reader is left closed and the first finger is ignored.
Note Run systemctl reenable on the start unit after changing its WantedBy= line; editing the unit file alone does not create the additional .wants/ symlinks.
Note A /etc/systemd/system-sleep/ hook is not a reliable alternative here, as the resume path can complete before a service restart finishes.

Fan control

Since Linux 6.18 the in-tree gpd_fan hwmon driver supports this machine; its DMI table includes G1628-04-L. It exposes fan1_input, pwm1 and pwm1_enable under /sys/class/hwmon/.

Warning pwm1_enable=0 means full speed, not off — inverted relative to the usual hwmon convention. 1 is manual and 2 is the automatic EC curve. In manual mode the driver has no temperature feedback and no ramp logic: the fan holds the value it was given regardless of temperature, so a userspace curve daemon that exits leaves the fan fixed. Do not run pwmconfig, which stops fans in order to correlate them.

The firmware-level Fn+= speed cycle listed under #Function keys is a lower-risk starting point.

Power management

Only s2idle is available (/sys/power/mem_sleep); there is no S3. This is normal for current AMD platforms and works well. Measured on the 8840U variant across a 101-minute suspend on battery:

  • 0.57 W average draw, roughly 1.3% per hour of the 45 Wh battery
  • 96% hardware sleep residency, from /sys/power/suspend_stats/last_hw_sleep

A residency below about 90% indicates the SoC is not reaching S0i3; see amd-debug-tools and its amd-s2idle tool to investigate.

Note The display is by far the largest idle consumer: approximately 7 W with the screen on, against 4.3 W with DPMS off. Configuring an idle DPMS-off timeout saves more than any other single change.

Hibernation

Although only s2idle is available for suspend, S4 hibernation works, including to a swap file on a LUKS-encrypted Btrfs root. Verified on the 8840U variant: the image is written, the machine powers off, and the session is restored after the disk is unlocked. The usual requirements apply, see Power management/Suspend and hibernate#Hibernation.

Hibernation can be refused outright when memory is full, which the kernel reports as:

PM: hibernation: Error -12 creating image

The kernel needs enough free memory to build the snapshot before writing it. This is worth noting on a machine using zram for swap: zram is backed by RAM, so reclaiming into it before hibernating frees nothing. Giving the on-disk swap a higher priority than zram leaves more headroom.

Tip When testing hibernation, read systemd's own verdict rather than the kernel's power-management lines:
$ journalctl -b 0 | grep -E 'Finished System Hibernate|Failed to start System Hibernate'
Warning ACPI: PM: Waking up from system sleep state S4 and Restoring platform NVS memory are logged by a successful resume as well, because the restored kernel unwinds through the same code. Neither indicates failure, and there are no image-writing progress messages to look for either.
Note /sys/power/disk cannot usefully be set by hand when systemd drives the hibernation: systemd-sleep writes that file itself from HibernateMode= (default platform shutdown). Use a drop-in under /etc/systemd/sleep.conf.d/ instead.

Display stays black after a long s2idle resume

On the 8840U (Radeon 780M, display block DCN 3.1.4) the internal eDP panel can stay black after resuming from a long s2idle, while the rest of the machine is fully alive: input, networking and even unlocking the session work normally, and the kernel logs no display error at all. Closing and reopening the lid, pressing keys and suspending again all leave the panel dark, because the compositor still believes the output is on and never issues a fresh modeset.

Forcing the compositor to run a modeset, for example by cycling DPMS off and on for that output, is worth trying; otherwise only a hard power-off recovers it.

This is freedesktop.org issue drm/amd#5287, which is open and not root-caused; the only evidence captured so far is that the DRM plane state is not re-attached on resume. It is reported on other Radeon 780M machines and under several desktops, so it is specific to neither this laptop nor any one compositor.

Warning Do not try to recover by switching to another virtual terminal. Handing DRM master to a legacy modesetting client can wedge the display block until the machine is rebooted.
Note Module parameters are not a workaround. Every amdgpu.dcdebugmask value tried upstream, along with amdgpu.sg_display=0, amdgpu.runpm=1 and pcie_aspm=force, still produced a black screen. There are two structural reasons: this panel reports PSR support 0, so the PSR and Panel Replay bits are inert, and DCN 3.1.4 does not implement IPS at all, so every IPS bit is a no-op as well.
Note Unrelated and harmless: kernels from 7.0 to 7.2 log REG_WAIT timeout 1us * 100 tries - dcn31_program_compbuf_size, often with a WARNING backtrace, whenever a mode is set. It is a register timeout made too short in 7.0 and corrected in 7.3. It appears many times a day on working systems and is not the cause of the black screen above.

Firmware

Warning The BIOS cannot be updated from Linux. fwupd identifies the machine correctly but reports no System Firmware device, as GPD does not publish UEFI capsule updates to LVFS. BIOS and EC updates therefore require the vendor's Windows tool, which is worth considering before removing a Windows installation.

The devices fwupd can see are the UEFI dbx, the integrated camera, the NVMe SSD and the Microsoft UEFI CA certificates.

See also