diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml
index 8938004ad03..a14ca76cf9b 100644
--- a/nixos/doc/manual/release-notes/rl-2009.xml
+++ b/nixos/doc/manual/release-notes/rl-2009.xml
@@ -135,6 +135,11 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
The various documented workarounds to use steam have been converted to a module. programs.steam.enable enables steam, controller support and the workarounds.
+
+
+ Support for built-in LCDs in various pieces of Logitech hardware (keyboards and USB speakers). hardware.logitech.lcd.enable enables support for all hardware supported by the g15daemon project.
+
+
diff --git a/nixos/modules/hardware/logitech.nix b/nixos/modules/hardware/logitech.nix
index d6f43bdddcc..3ebe6aacf5d 100644
--- a/nixos/modules/hardware/logitech.nix
+++ b/nixos/modules/hardware/logitech.nix
@@ -5,24 +5,92 @@ with lib;
let
cfg = config.hardware.logitech;
-in {
- options.hardware.logitech = {
- enable = mkEnableOption "Logitech Devices";
+ vendor = "046d";
- enableGraphical = mkOption {
- type = types.bool;
- default = false;
- description = "Enable graphical support applications.";
+ daemon = "g15daemon";
+
+in
+{
+ imports = [
+ (mkRenamedOptionModule [ "hardware" "logitech" "enable" ] [ "hardware" "logitech" "wireless" "enable" ])
+ (mkRenamedOptionModule [ "hardware" "logitech" "enableGraphical" ] [ "hardware" "logitech" "wireless" "enableGraphical" ])
+ ];
+
+ options.hardware.logitech = {
+
+ lcd = {
+ enable = mkEnableOption "Logitech LCD Devices";
+
+ startWhenNeeded = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Only run the service when an actual supported device is plugged.
+ '';
+ };
+
+ devices = mkOption {
+ type = types.listOf types.str;
+ default = [ "0a07" "c222" "c225" "c227" "c251" ];
+ description = ''
+ List of USB device ids supported by g15daemon.
+
+
+ You most likely do not need to change this.
+ '';
+ };
+ };
+
+ wireless = {
+ enable = mkEnableOption "Logitech Wireless Devices";
+
+ enableGraphical = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enable graphical support applications.";
+ };
};
};
- config = lib.mkIf cfg.enable {
- environment.systemPackages = [
- pkgs.ltunify
- ] ++ lib.optional cfg.enableGraphical pkgs.solaar;
+ config = lib.mkIf (cfg.wireless.enable || cfg.lcd.enable) {
+ environment.systemPackages = []
+ ++ lib.optional cfg.wireless.enable pkgs.ltunify
+ ++ lib.optional cfg.wireless.enableGraphical pkgs.solaar;
- # ltunifi and solaar both provide udev rules but the most up-to-date have been split
- # out into a dedicated derivation
- services.udev.packages = with pkgs; [ logitech-udev-rules ];
+ services.udev = {
+ # ltunifi and solaar both provide udev rules but the most up-to-date have been split
+ # out into a dedicated derivation
+
+ packages = []
+ ++ lib.optional cfg.wireless.enable pkgs.logitech-udev-rules
+ ++ lib.optional cfg.lcd.enable pkgs.g15daemon;
+
+ extraRules = ''
+ # nixos: hardware.logitech.lcd
+ '' + lib.concatMapStringsSep "\n" (
+ dev:
+ ''ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="${vendor}", ATTRS{idProduct}=="${dev}", TAG+="systemd", ENV{SYSTEMD_WANTS}+="${daemon}.service"''
+ ) cfg.lcd.devices;
+ };
+
+ systemd.services."${daemon}" = lib.mkIf cfg.lcd.enable {
+ description = "Logitech LCD Support Daemon";
+ documentation = [ "man:g15daemon(1)" ];
+ wantedBy = lib.mkIf (! cfg.lcd.startWhenNeeded) "multi-user.target";
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${pkgs.g15daemon}/bin/g15daemon";
+ # we patch it to write to /run/g15daemon/g15daemon.pid instead of
+ # /run/g15daemon.pid so systemd will do the cleanup for us.
+ PIDFile = "/run/${daemon}/g15daemon.pid";
+ PrivateTmp = true;
+ PrivateNetwork = true;
+ ProtectHome = "tmpfs";
+ ProtectSystem = "full"; # strict doesn't work
+ RuntimeDirectory = daemon;
+ Restart = "on-failure";
+ };
+ };
};
}