feat(nix): add tejo hardware support and per-model auto-upgrade

- Add tejo-specific udev rules for both UP Board and UP4000 variants
  (serial symlinks ttyJ4/J5/J7, camera, LED SPI, I2C, USB autosuspend)
- Add USB serial kernel modules (usbserial, ftdi_sio, cp210x) for tejo
- Add tejo serial console kernel params (ttyS4 debug UART)
- Fix upboard.nix: hardware.graphics → hardware.opengl (NixOS 24.05)
- Add tejo-installed nixosConfiguration with model-specific auto-upgrade
- Parameterize auto-upgrade flake URL per machine model

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-03-06 08:54:50 -05:00
commit 143ae9ff0b
3 changed files with 121 additions and 51 deletions

View file

@ -82,6 +82,10 @@ in
"kvm-intel"
"i2c-dev"
"spi-dev"
] ++ lib.optionals (machineModel == "tejo") [
"usbserial" # USB-to-serial adapters (ttyUSB0/1 for validator/printer)
"ftdi_sio" # FTDI USB serial (common in ATM peripherals)
"cp210x" # CP210x USB serial (alternative adapter)
];
kernelParams = [
@ -91,6 +95,10 @@ in
] ++ lib.optionals (machineModel == "douro") [
# Bay Trail: preserve BIOS display init (matches working kernel 5.4 config)
"vt.handoff=7"
] ++ lib.optionals (machineModel == "tejo") [
# UP Board debug UART for serial console
"console=ttyS4,115200n8"
"console=tty0"
];
};
@ -194,10 +202,53 @@ in
# Allow SSH with password for initial setup on the live system
services.openssh.settings.PasswordAuthentication = lib.mkForce true;
# Serial port udev rules (from hardware/upboard.nix)
services.udev.extraRules = lib.mkAfter ''
# Serial port udev rules — generic permissions for all models
services.udev.extraRules = lib.mkAfter (''
KERNEL=="ttyS[0-9]*", MODE="0666"
KERNEL=="ttyUSB[0-9]*", MODE="0666"
KERNEL=="ttyACM[0-9]*", MODE="0666"
'';
'' + lib.optionalString (machineModel == "tejo") ''
# ── Tejo serial port symlinks ──────────────────────────────────────
# Both UP Board and UP4000 rules are included so one ISO works on either.
# Rules match different kernel paths so they don't conflict.
# Printer (ttyJ4): UP Board via USB hub path, UP4000 via ttyUSB0
KERNELS=="1-7.2:1.0", SYMLINK+="ttyJ4"
KERNEL=="ttyUSB0", SYMLINK+="ttyJ4"
# Validator (ttyJ5): UP Board via USB hub path, UP4000 via ttyUSB1
KERNELS=="1-7.3:1.0", SYMLINK+="ttyJ5"
KERNEL=="ttyUSB1", SYMLINK+="ttyJ5"
# Dispenser (ttyJ7): UP Board uses ttyS1, UP4000 uses ttyS5
KERNEL=="ttyS1", SYMLINK+="ttyJ7"
KERNEL=="ttyS5", SYMLINK+="ttyJ7"
# Legacy ttyAMA0 alias
SUBSYSTEM=="tty", KERNEL=="ttyS1", SYMLINK+="ttyAMA0", GROUP="dialout"
# ── Camera devices ─────────────────────────────────────────────────
# QR scanner camera (A4tech USB, vendor 0ac8:0345)
SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-5", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-scan"
SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-2", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-scan"
# Front-facing camera
SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-6", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-front"
SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-3", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-front"
# ── LED SPI / peripherals ──────────────────────────────────────────
KERNEL=="spidev1.0", SYMLINK+="ledspi"
KERNEL=="spidev2.0", SYMLINK+="ledspi"
# SPI and I2C group permissions
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
# UP Board FPGA LED permissions
SUBSYSTEM=="leds", KERNEL=="upboard:*", ACTION=="add|change", RUN+="${pkgs.findutils}/bin/find /sys$devpath -type f -exec ${pkgs.coreutils}/bin/chmod g+u {} + -exec ${pkgs.coreutils}/bin/chown :leds {} +"
# Disable USB autosuspend (prevents serial adapters from sleeping)
ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="on"
'');
}