{ self, pkgs, config, lib, options, ... }: let # TODO: introduce options for these kernelPdMapper = true; cfg = config.hardware.thinkpad-x13s; in { options.hardware.thinkpad-x13s = { # TODO: respect this enable = lib.mkEnableOption "x13s hardware support"; bluetoothMac = lib.mkOption { type = lib.types.str; description = "mac address to set on boot"; }; }; config = let inherit (config.boot.loader) efi; kp = [ { name = "x13s-cfg"; patch = null; extraStructuredConfig = with lib.kernel; { EFI_ARMSTUB_DTB_LOADER = lib.mkForce yes; OF_OVERLAY = lib.mkForce yes; BTRFS_FS = lib.mkForce yes; BTRFS_FS_POSIX_ACL = lib.mkForce yes; MEDIA_CONTROLLER = lib.mkForce yes; SND_USB_AUDIO_USE_MEDIA_CONTROLLER = lib.mkForce yes; SND_USB = lib.mkForce yes; SND_USB_AUDIO = lib.mkForce module; USB_XHCI_PCI = lib.mkForce module; NO_HZ_FULL = lib.mkForce yes; HZ_100 = lib.mkForce yes; HZ_250 = lib.mkForce no; DRM_AMDGPU = lib.mkForce no; DRM_NOUVEAU = lib.mkForce no; QCOM_TSENS = lib.mkForce yes; NVMEM_QCOM_QFPROM = lib.mkForce yes; ARM_QCOM_CPUFREQ_NVMEM = lib.mkForce yes; VIRTIO_PCI = lib.mkForce module; # forthcoming kernel work: QCOM_PD_MAPPER = lib.mkForce module; }; } ]; qrtr = pkgs.callPackage "${self.inputs.adamcstephens_stop-export}/hardware/x13s/qrtr/qrtr.nix" {}; pd-mapper = pkgs.callPackage "${self.inputs.adamcstephens_stop-export}/hardware/x13s/qrtr/pd-mapper.nix" { inherit qrtr; }; # We can't quite move to mainline linux linux_x13s_pkg = {buildLinux, ...} @ args: buildLinux (args // rec { version = "6.7.0"; modDirVersion = lib.versions.pad 3 version; extraMeta.branch = lib.versions.majorMinor version; src = self.inputs.linux_x13s; kernelPatches = (args.kernelPatches or []) ++ kp; } // (args.argsOverride or {})); # we add additional configuration on top of te normal configuration above # using the extraStructuredConfig option on the kernel patch linux_x13s = pkgs.callPackage linux_x13s_pkg { defconfig = "johan_defconfig"; }; linuxPackages_x13s = pkgs.linuxPackagesFor linux_x13s; dtbName = "sc8280xp-lenovo-thinkpad-x13s.dtb"; dtb = "${linuxPackages_x13s.kernel}/dtbs/qcom/${dtbName}"; x13s_alsa-ucm-conf = pkgs.alsa-ucm-conf.overrideAttrs (prev: { src = self.inputs.alsa-ucm-conf; }); alsa-ucm-conf-env.ALSA_CONFIG_UCM2 = "${x13s_alsa-ucm-conf}/share/alsa/ucm2"; in lib.mkIf cfg.enable { nixpkgs.overlays = [ ( final: prev: { x13s_extra-firmware = pkgs.callPackage "${self.inputs.adamcstephens_stop-export}/hardware/x13s/extra-firmware.nix" {}; inherit qrtr pd-mapper; } ) ]; # ensure the x13s' dtb file is in the boot partition # TODO:: is this needed for the VT display somehow? system.activationScripts.x13s-dtb = '' in_package="${dtb}" esp_tool_folder="${efi.efiSysMountPoint}/" in_esp="''${esp_tool_folder}${dtbName}" >&2 echo "Ensuring $in_esp in EFI System Partition" if ! ${pkgs.diffutils}/bin/cmp --silent "$in_package" "$in_esp"; then >&2 echo "Copying $in_package -> $in_esp" mkdir -p "$esp_tool_folder" cp "$in_package" "$in_esp" sync fi ''; boot = { loader.systemd-boot.enable = true; loader.systemd-boot.extraFiles = { "${dtbName}" = dtb; }; loader.efi.canTouchEfiVariables = false; loader.efi.efiSysMountPoint = "/boot"; blacklistedKernelModules = ["wwan"]; kernelPackages = linuxPackages_x13s; kernelParams = [ "dtb=${dtbName}" "boot.shell_on_fail" # jhovold recommended "efi=noruntime" "clk_ignore_unused" "pd_ignore_unused" "arm64.nopauth" # blacklist graphics in initrd so the firmware can load from disk "rd.driver.blacklist=msm" ]; initrd = { includeDefaultModules = false; # kernelModules = [ # "nvme" # "phy_qcom_qmp_pcie" # "pcie_qcom" # "i2c_core" # "i2c_hid" # "i2c_hid_of" # "i2c_qcom_geni" # "leds_qcom_lpg" # "pwm_bl" # "qrtr" # "pmic_glink_altmode" # "gpio_sbu_mux" # "phy_qcom_qmp_combo" # "gpucc_sc8280xp" # "dispcc_sc8280xp" # "phy_qcom_edp" # "panel_edp" # # "msm" # ]; availableKernelModules = [ "i2c_hid" "i2c_hid_of" "i2c_qcom_geni" "leds_qcom_lpg" "pwm_bl" "qrtr" "pmic_glink_altmode" "gpio_sbu_mux" "phy_qcom_qmp_combo" "panel_edp" # "msm" "phy_qcom_edp" "i2c_core" "i2c_hid" "i2c_hid_of" "i2c_qcom_geni" "pcie_qcom" "phy_qcom_qmp_combo" "phy_qcom_qmp_pcie" "phy_qcom_qmp_usb" "phy_qcom_snps_femto_v2" "phy_qcom_usb_hs" "nvme" "usbcore" "xhci_hcd" "usbhid" "usb_storage" "uas" ]; }; }; # default is performance powerManagement.cpuFreqGovernor = "ondemand"; hardware.enableAllFirmware = true; hardware.firmware = [ # pkgs.linux-firmware pkgs.x13s_extra-firmware ]; systemd.services.pd-mapper = { wantedBy = ["multi-user.target"]; serviceConfig = { ExecStart = "${lib.getExe pd-mapper}"; Restart = "always"; }; }; environment.sessionVariables = alsa-ucm-conf-env; systemd.user.services.pipewire.environment = alsa-ucm-conf-env; systemd.user.services.wireplumber.environment = alsa-ucm-conf-env; systemd.services.bluetooth = { serviceConfig = { # disabled because btmgmt call hangs ExecStartPre = [ "" "${pkgs.util-linux}/bin/rfkill block bluetooth" "${pkgs.bluez5-experimental}/bin/btmgmt public-addr ${cfg.bluetoothMac}" "${pkgs.util-linux}/bin/rfkill unblock bluetooth" ]; RestartSec = 5; Restart = "on-failure"; }; }; }; }