Skip to content

feat: add kernel switching for Microsoft Surface devices #1443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 24, 2025
26 changes: 18 additions & 8 deletions microsoft/surface/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# NOTE: Structure changes from 2023-01-10

Please read the [Deprecated Behaviour README](./OLD-BEHAVIOUR-DEPRECATION.md) to understand how some structural changes to
the code might affect you!

# Derivations for Microsoft Surface notebooks

These derivatives use the patches from the [linux-surface repo](https://github.com/linux-surface/linux-surface/tree/master/patches).
Expand Down Expand Up @@ -32,13 +27,24 @@ Not all hardware is fully supported, but the
[linux-surface feature matrix](https://github.com/linux-surface/linux-surface/wiki/Supported-Devices-and-Features#feature-matrix)
provides details on which devices are supported on which types of machine.

The kernel-specific derivations are under the [`common/kernel/`](./common/kernel/) sub-directory.
In order to simplify maintenance of the Nix code, only the most-recent kernel patch-set is expected
to be maintained in this repo.
The kernel-specific derivations are under the [`common/kernel/`](./common/kernel/) sub-directory. This directory defines patch sets for each supported kernel release (see Kernel versions below for more information).

_*NOTE:*_ Some built-in Kernel config items need to be set, that aren't set by default:
- https://github.com/linux-surface/surface-aggregator-module/wiki/Testing-and-Installing

#### Kernel versions

There are multiple versions of the Surface kernel available:

- `longterm`, which tracks the latest long term support (LTS) release.
- `stable`, which tracks the most recent stable release.

This repo uses `longterm` by default, but you can switch it to `stable` by adding this to your configuration file:

```nix
hardware.microsoft-surface.kernelVersion = "stable";
```

### Support Tools

### IPTS
Expand Down Expand Up @@ -120,3 +126,7 @@ References:
- https://github.com/thebitstick/surfacego-wifi
- https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/ath10k
- https://wireless.wiki.kernel.org/en/users/drivers/ath10k/firmware

## Structural changes from earlier versions (2023-01-10 and earlier)

If you're upgrading from an older version of nixos-hardware, please read the [Deprecated Behaviour README](./OLD-BEHAVIOUR-DEPRECATION.md) to understand how some structural changes to the code might affect you!
93 changes: 80 additions & 13 deletions microsoft/surface/common/default.nix
Original file line number Diff line number Diff line change
@@ -1,22 +1,89 @@
{ lib, ... }:
{ config, lib, pkgs, ... }:

let
inherit (lib) mkDefault;
inherit (lib) mkDefault mkOption types versions;

# Set the version and hash for the kernel sources
srcVersion = with config.hardware.microsoft-surface;
if kernelVersion == "longterm" then
"6.12.19"
else if kernelVersion == "stable" then
"6.14.2"
else
abort "Invalid kernel version: ${kernelVersion}";

srcHash = with config.hardware.microsoft-surface;
if kernelVersion == "longterm" then
"sha256-1zvwV77ARDSxadG2FkGTb30Ml865I6KB8y413U3MZTE="
else if kernelVersion == "stable" then
"sha256-xcaCo1TqMZATk1elfTSnnlw3IhrOgjqTjhARa1d6Lhs="
else
abort "Invalid kernel version: ${kernelVersion}";

# Set the version and hash for the linux-surface releases
pkgVersion = with config.hardware.microsoft-surface;
if kernelVersion == "longterm" then
"6.12.7"
else if kernelVersion == "stable" then
"6.14.2"
else
abort "Invalid kernel version: ${kernelVersion}";

pkgHash = with config.hardware.microsoft-surface;
if kernelVersion == "longterm" then
"sha256-Pv7O8D8ma+MPLhYP3HSGQki+Yczp8b7d63qMb6l4+mY="
else if kernelVersion == "stable" then
"sha256-Pzn+C52TtDcqDVepM5z2cVNCsnRDy0Wwn+FLwgsuicQ="
else
abort "Invalid kernel version: ${kernelVersion}";

# Fetch the linux-surface package
repos = pkgs.callPackage ({ fetchFromGitHub, rev, hash }: {
linux-surface = fetchFromGitHub {
owner = "linux-surface";
repo = "linux-surface";
rev = rev;
hash = hash;
};
}) { hash = pkgHash; rev = "arch-${pkgVersion}-1"; };

# Fetch and build the kernel package
inherit (pkgs.callPackage ./kernel/linux-package.nix { inherit repos; }) linuxPackage surfacePatches;
kernelPatches = surfacePatches {
version = pkgVersion;
patchFn = ./kernel/${versions.majorMinor pkgVersion}/patches.nix;
};
kernelPackages = linuxPackage {
inherit kernelPatches; version = srcVersion;
sha256 = srcHash;
ignoreConfigErrors=true;
};

in {
imports = [
./kernel
];
options.hardware.microsoft-surface.kernelVersion = mkOption {
description = "Kernel Version to use (patched for MS Surface)";
type = types.enum [
"longterm"
"stable"
];
default = "longterm";
};

microsoft-surface.kernelVersion = mkDefault "6.12";
config = {
boot = {
inherit kernelPackages;

# Seems to be required to properly enable S0ix "Modern Standby":
boot.kernelParams = mkDefault [ "mem_sleep_default=deep" ];
# Seems to be required to properly enable S0ix "Modern Standby":
kernelParams = mkDefault [ "mem_sleep_default=deep" ];
};

# NOTE: Check the README before enabling TLP:
services.tlp.enable = mkDefault false;
# NOTE: Check the README before enabling TLP:
services.tlp.enable = mkDefault false;

# i.e. needed for wifi firmware, see https://github.com/NixOS/nixos-hardware/issues/364
hardware.enableRedistributableFirmware = mkDefault true;
hardware.sensor.iio.enable = mkDefault true;
# Needed for wifi firmware, see https://github.com/NixOS/nixos-hardware/issues/364
hardware = {
enableRedistributableFirmware = mkDefault true;
sensor.iio.enable = mkDefault true;
};
};
}
158 changes: 158 additions & 0 deletions microsoft/surface/common/kernel/6.14/patches.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
{ lib,
kernel ? lib.kernel,
patchSrc,
version,
}:

[
{
name = "microsoft-surface-patches-linux-${version}";
patch = null;
extraStructuredConfig = with kernel; {
STAGING_MEDIA = yes;
##
## Surface Aggregator Module
##
CONFIG_SURFACE_AGGREGATOR = module;
# CONFIG_SURFACE_AGGREGATOR_ERROR_INJECTION is not set
CONFIG_SURFACE_AGGREGATOR_BUS = yes;
CONFIG_SURFACE_AGGREGATOR_CDEV = module;
CONFIG_SURFACE_AGGREGATOR_HUB = module;
CONFIG_SURFACE_AGGREGATOR_REGISTRY = module;
CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH = module;

CONFIG_SURFACE_ACPI_NOTIFY = module;
CONFIG_SURFACE_DTX = module;
CONFIG_SURFACE_PLATFORM_PROFILE = module;

CONFIG_SURFACE_HID = module;
CONFIG_SURFACE_KBD = module;

CONFIG_BATTERY_SURFACE = module;
CONFIG_CHARGER_SURFACE = module;

CONFIG_SENSORS_SURFACE_TEMP = module;
CONFIG_SENSORS_SURFACE_FAN = module;

CONFIG_RTC_DRV_SURFACE = module;

##
## Surface Hotplug
##
CONFIG_SURFACE_HOTPLUG = module;

##
## IPTS and ITHC touchscreen
##
## This only enables the user interface for IPTS/ITHC data.
## For the touchscreen to work, you need to install iptsd.
##
CONFIG_HID_IPTS = module;
CONFIG_HID_ITHC = module;

##
## Cameras: IPU3
##
CONFIG_VIDEO_DW9719 = module;
CONFIG_VIDEO_IPU3_IMGU = module;
CONFIG_VIDEO_IPU3_CIO2 = module;
CONFIG_IPU_BRIDGE = module;
CONFIG_INTEL_SKL_INT3472 = module;
CONFIG_REGULATOR_TPS68470 = module;
CONFIG_COMMON_CLK_TPS68470 = module;
CONFIG_LEDS_TPS68470 = module;

##
## Cameras: Sensor drivers
##
CONFIG_VIDEO_OV5693 = module;
CONFIG_VIDEO_OV7251 = module;
CONFIG_VIDEO_OV8865 = module;

##
## Surface 3: atomisp causes problems (see issue #1095). Disable it for now.
##
# CONFIG_INTEL_ATOMISP is not set

##
## ALS Sensor for Surface Book 3, Surface Laptop 3, Surface Pro 7
##
CONFIG_APDS9960 = module;

##
## Build-in UFS support (required for some Surface Go devices)
##
CONFIG_SCSI_UFSHCD = module;
CONFIG_SCSI_UFSHCD_PCI = module;

##
## Other Drivers
##
CONFIG_INPUT_SOC_BUTTON_ARRAY = module;
CONFIG_SURFACE_3_POWER_OPREGION = module;
CONFIG_SURFACE_PRO3_BUTTON = module;
CONFIG_SURFACE_GPE = module;
CONFIG_SURFACE_BOOK1_DGPU_SWITCH = module;
};
}
{
name = "ms-surface/0001-secureboot";
patch = patchSrc + "/0001-secureboot.patch";
}
{
name = "ms-surface/0002-surface3";
patch = patchSrc + "/0002-surface3.patch";
}
{
name = "ms-surface/0003-mwifiex";
patch = patchSrc + "/0003-mwifiex.patch";
}
{
name = "ms-surface/0004-ath10k";
patch = patchSrc + "/0004-ath10k.patch";
}
{
name = "ms-surface/0005-ipts";
patch = patchSrc + "/0005-ipts.patch";
}
{
name = "ms-surface/0006-ithc";
patch = patchSrc + "/0006-ithc.patch";
}
{
name = "ms-surface/0007-surface-sam";
patch = patchSrc + "/0007-surface-sam.patch";
}
{
name = "ms-surface/0008-surface-sam-over-hid";
patch = patchSrc + "/0008-surface-sam-over-hid.patch";
}
{
name = "ms-surface/0009-surface-button";
patch = patchSrc + "/0009-surface-button.patch";
}
{
name = "ms-surface/0010-surface-typecover";
patch = patchSrc + "/0010-surface-typecover.patch";
}
{
name = "ms-surface/0011-surface-shutdown";
patch = patchSrc + "/0011-surface-shutdown.patch";
}
{
name = "ms-surface/0012-surface-gpe";
patch = patchSrc + "/0012-surface-gpe.patch";
}
{
name = "ms-surface/0013-cameras";
patch = patchSrc + "/0013-cameras.patch";
}
{
name = "ms-surface/0014-amd-gpio";
patch = patchSrc + "/0014-amd-gpio.patch";
}
{
name = "ms-surface/0015-rtc";
patch = patchSrc + "/0015-rtc.patch";
}
]
15 changes: 0 additions & 15 deletions microsoft/surface/common/kernel/default.nix

This file was deleted.

3 changes: 1 addition & 2 deletions microsoft/surface/common/kernel/linux-package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
fetchurl,
buildLinux,
linuxPackagesFor,
repos,
}:

let
inherit (builtins) elem;
inherit (lib) recurseIntoAttrs types versions;

repos = pkgs.callPackage ../repos.nix {};

linuxPackage =
{ url ? "mirror://kernel/linux/kernel/v${versions.major version}.x/linux-${version}.tar.xz",
sha256 ? null,
Expand Down
31 changes: 0 additions & 31 deletions microsoft/surface/common/kernel/linux-surface/default.nix

This file was deleted.

25 changes: 0 additions & 25 deletions microsoft/surface/common/repos.nix

This file was deleted.

Loading