diff --git a/modules/devices/steamdeck/default.nix b/modules/devices/steamdeck/default.nix index a70b55ca..0ee4e007 100644 --- a/modules/devices/steamdeck/default.nix +++ b/modules/devices/steamdeck/default.nix @@ -16,6 +16,7 @@ in imports = [ ./controller.nix ./fan-control.nix + ./fde.nix ./firmware.nix ./graphical.nix ./hw-support.nix diff --git a/modules/devices/steamdeck/fde.nix b/modules/devices/steamdeck/fde.nix new file mode 100644 index 00000000..449d1cc3 --- /dev/null +++ b/modules/devices/steamdeck/fde.nix @@ -0,0 +1,105 @@ +{ config, lib, pkgs, utils, ... }: + +let + cfg = config.jovian.devices.steamdeck; +in +{ + options = { + jovian.devices.steamdeck = { + fde = { + deckbd = { + enable = lib.mkOption { + default = cfg.enable; + defaultText = lib.literalExpression "config.jovian.devices.steamdeck.enable"; + type = lib.types.bool; + description = '' + Whether to enable deckbd for initrd password entry. + + You must hold the menu button (≡) for a second before entering + your password. + ''; + }; + bindsTo = lib.mkOption { + inherit (utils.systemdUtils.unitOptions.commonUnitOptions.options.bindsTo) type; + description = '' + systemd units that require deckbd. + + For example, if you want controller input in unl0kr, add `config.boot.initrd.systemd.services.unl0kr-ask-password.name`. + + Plymouth and the console work by default. + ''; + }; + debug = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Enable debug output for deckbd. + + This will log keycodes to the journal. + ''; + }; + }; + }; + }; + }; + + config = lib.mkMerge [ + (lib.mkIf cfg.fde.deckbd.enable { + assertions = [ + { + assertion = cfg.enableDefaultStage1Modules; + message = '' + deckbd cannot be used without the required kernel modules. + + jovian.devices.steamdeck.enableDefaultStage1Modules must be enabled. + ''; + } + { + assertion = config.boot.initrd.systemd.enable; + message = '' + deckbd requires systemd-in-initrd. + + boot.initrd.systemd.enable must be set to true. Note that this may impact other NixOS features. + ''; + } + ]; + + jovian.devices.steamdeck.fde.deckbd.bindsTo = [ + "systemd-ask-password-console.service" + (lib.mkIf config.boot.plymouth.enable config.systemd.services.systemd-ask-password-plymouth.name) + # Note: Agents that have optional keyboard input, such as unl0kr, should not be added here. The user may not want it. + ]; + + boot.initrd = { + kernelModules = [ "uinput" ]; + + services.udev.packages = [ + (pkgs.writeTextDir "lib/udev/rules.d/70-steam-deck-controller.rules" '' + ACTION=="add", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="28de", ENV{ID_MODEL_ID}=="1205", ENV{PRODUCT}=="?*", ENV{ID_INPUT_JOYSTICK}=="1", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/class/input/input_steam_deck_controller" + '') + ]; + + systemd = { + storePaths = with pkgs; [ deckbd ]; # https://github.com/NixOS/nixpkgs/issues/309316 + services.deckbd = { + description = "Steam Deck controller keymapper"; + unitConfig.DefaultDependencies = false; + wantedBy = cfg.fde.deckbd.bindsTo; + before = cfg.fde.deckbd.bindsTo; + inherit (cfg.fde.deckbd) bindsTo; + requires = [ "sys-class-input-input_steam_deck_controller.device" ]; + after = [ "sys-class-input-input_steam_deck_controller.device" ]; + path = with pkgs; [ deckbd ]; + environment.G_MESSAGES_DEBUG = lib.mkIf cfg.fde.deckbd.debug "all"; + # Note: The lizard_mode parameter does not work as intended. The + # Steam Deck must also be manually put into gamepad mode by holding + # the menu button (≡) for a second. + preStart = "echo 0 > /sys/module/hid_steam/parameters/lizard_mode"; + script = "deckbd"; + postStop = "echo 1 > /sys/module/hid_steam/parameters/lizard_mode"; + }; + }; + }; + }) + ]; +} diff --git a/modules/devices/steamdeck/hw-support.nix b/modules/devices/steamdeck/hw-support.nix index 88ca3015..4b96a6ba 100644 --- a/modules/devices/steamdeck/hw-support.nix +++ b/modules/devices/steamdeck/hw-support.nix @@ -46,6 +46,7 @@ in # Gamepad "usbhid" + "hid-steam" ]; boot.initrd.availableKernelModules = [ "nvme" diff --git a/overlay.nix b/overlay.nix index fb71a71c..0a6543b8 100644 --- a/overlay.nix +++ b/overlay.nix @@ -93,4 +93,6 @@ rec { decky-loader = final.callPackage ./pkgs/decky-loader { }; decky-loader-prerelease = final.callPackage ./pkgs/decky-loader/prerelease.nix { }; + + deckbd = final.callPackage ./pkgs/deckbd { }; } diff --git a/pkgs/deckbd/default.nix b/pkgs/deckbd/default.nix new file mode 100644 index 00000000..14046f60 --- /dev/null +++ b/pkgs/deckbd/default.nix @@ -0,0 +1,33 @@ +{ lib +, stdenv +, fetchFromGitHub +, pkg-config +, glib +, libevdev +}: + +stdenv.mkDerivation { + pname = "deckbd"; + version = "0-unstable-2024-07-01"; + + src = fetchFromGitHub { + owner = "Ninlives"; + repo = "deckbd"; + rev = "1d2c71f2c096fbfa42624dd820a9d11a35c64826"; + hash = "sha256-Svp/5Mo/XkiptbTM3E4QhSRxC6rMeF0t3eTq9BUjLbs="; + }; + + nativeBuildInputs = [ pkg-config ]; + + buildInputs = [ glib libevdev ]; + + makeFlags = [ "PREFIX=$(out)" ]; + + meta = { + description = "Steam Deck controller keymapper"; + homepage = "https://github.com/Ninlives/deckbd"; + license = lib.licenses.gpl3Only; + mainProgram = "deckbd"; + platforms = lib.platforms.linux; + }; +}