diff --git a/README.md b/README.md index c9b80cb95..133a06e41 100644 --- a/README.md +++ b/README.md @@ -375,6 +375,7 @@ See code for all available configurations. | [Microsoft Surface Pro 9](microsoft/surface-pro/9) | `` | `microsoft-surface-pro-9` | | [Morefine M600](morefine/m600) | `` | `morefine-m600` | | [Minisforum V3](minisforum/v3) | `` | `minisforum-v3` | +| [MNT Reform with RK3588 module](mnt/reform/rk3588) | `` | `mechrevo-gm5hg0a` | | [NXP iMX8 MPlus Evaluation Kit](nxp/imx8mp-evk) | `` | `nxp-imx8mp-evk` | | [NXP iMX8 MQuad Evaluation Kit](nxp/imx8mq-evk) | `` | `nxp-imx8mq-evk` | diff --git a/flake.nix b/flake.nix index 7cfe53df3..cc71ee369 100644 --- a/flake.nix +++ b/flake.nix @@ -312,6 +312,7 @@ microsoft-surface-pro-9 = import ./microsoft/surface-pro/9; milkv-pioneer = import ./milkv/pioneer; minisforum-v3 = import ./minisforum/v3; + mnt-reform-rk3588 = import ./mnt/reform/rk3588; morefine-m600 = import ./morefine/m600; msi-b350-tomahawk = import ./msi/b350-tomahawk; msi-b550-a-pro = import ./msi/b550-a-pro; diff --git a/mnt/reform/default.nix b/mnt/reform/default.nix new file mode 100644 index 000000000..6681a9689 --- /dev/null +++ b/mnt/reform/default.nix @@ -0,0 +1,10 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + boot.kernelPackages = pkgs.callPackage ./kernel.nix { }; + boot.extraModulePackages = [ (config.boot.kernelPackages.callPackage ./lpc.nix { }) ]; +} diff --git a/mnt/reform/dtsPatch.nix b/mnt/reform/dtsPatch.nix new file mode 100644 index 000000000..3cb77cb76 --- /dev/null +++ b/mnt/reform/dtsPatch.nix @@ -0,0 +1,48 @@ +{ + stdenv, + reformDebianPackages, + kernelSource, + quilt, +}: +stdenv.mkDerivation { + name = "mnt-dts-patch"; + nativeBuildInputs = [ quilt ]; + buildCommand = '' + cp -r --reflink=auto ${reformDebianPackages}/linux/* . + mkdir -p linux/debian/patches/reform + cp -r --reflink=auto ${kernelSource}/* linux + chmod +w -R . + env --chdir=linux QUILT_PATCHES=debian/patches quilt new reform/dts.patch + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/freescale/fsl-ls1028a-mnt-reform2.dts + cp fsl-ls1028a-mnt-reform2.dts linux/arch/arm64/boot/dts/freescale/fsl-ls1028a-mnt-reform2.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2-hdmi.dts + cp imx8mq-mnt-reform2-hdmi.dts linux/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2-hdmi.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/freescale/Makefile + sed -i '/fsl-ls1028a-rdb.dtb/a dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-mnt-reform2.dtb' linux/arch/arm64/boot/dts/freescale/Makefile + sed -i '/imx8mq-mnt-reform2.dtb/a dtb-$(CONFIG_ARCH_MXC) += imx8mq-mnt-reform2-hdmi.dtb' linux/arch/arm64/boot/dts/freescale/Makefile + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/freescale/imx8mp-mnt-pocket-reform.dts + cp imx8mp-mnt-pocket-reform.dts linux/arch/arm64/boot/dts/freescale/imx8mp-mnt-pocket-reform.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/freescale/imx8mp-mnt-reform2.dts + cp imx8mp-mnt-reform2.dts linux/arch/arm64/boot/dts/freescale/imx8mp-mnt-reform2.dts + sed -i '/imx8mq-mnt-reform2.dtb/a dtb-$(CONFIG_ARCH_MXC) += imx8mp-mnt-pocket-reform.dtb' linux/arch/arm64/boot/dts/freescale/Makefile + sed -i '/imx8mq-mnt-reform2.dtb/a dtb-$(CONFIG_ARCH_MXC) += imx8mp-mnt-reform2.dtb' linux/arch/arm64/boot/dts/freescale/Makefile + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-pocket-reform.dts + cp meson-g12b-bananapi-cm4-mnt-pocket-reform.dts linux/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-pocket-reform.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/amlogic/Makefile + sed -i '/meson-g12b-bananapi-cm4-mnt-reform2.dtb/a dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-mnt-pocket-reform.dtb' linux/arch/arm64/boot/dts/amlogic/Makefile + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/rockchip/rk3588-mnt-reform2.dts + cp rk3588-mnt-reform2.dts linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform2.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/rockchip/rk3588-mnt-reform2-dsi.dts + cp rk3588-mnt-reform2-dsi.dts linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform2-dsi.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/rockchip/rk3588-mnt-pocket-reform.dts + cp rk3588-mnt-pocket-reform.dts linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-pocket-reform.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/rockchip/rk3588-mnt-reform-next.dts + cp rk3588-mnt-reform-next.dts linux/arch/arm64/boot/dts/rockchip/rk3588-mnt-reform-next.dts + env --chdir=linux QUILT_PATCHES=debian/patches quilt add arch/arm64/boot/dts/rockchip/Makefile + sed -i '/rk3588-mnt-reform2.dtb/a dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform2-dsi.dtb' linux/arch/arm64/boot/dts/rockchip/Makefile + sed -i '/rk3588-mnt-reform2-dsi.dtb/a dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform-next.dtb' linux/arch/arm64/boot/dts/rockchip/Makefile + sed -i '/rk3588-mnt-reform-next.dtb/a dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-pocket-reform.dtb' linux/arch/arm64/boot/dts/rockchip/Makefile + env --chdir=linux QUILT_PATCHES=debian/patches quilt refresh + cp linux/debian/patches/reform/dts.patch $out + ''; +} diff --git a/mnt/reform/kernel.nix b/mnt/reform/kernel.nix new file mode 100644 index 000000000..7b742b233 --- /dev/null +++ b/mnt/reform/kernel.nix @@ -0,0 +1,148 @@ +{ + lib, + callPackage, + linuxPackagesFor, + kernelPatches, + fetchFromGitLab, + ... +}: +let + modDirVersion = "6.16.5"; + reformDebianPackages = fetchFromGitLab { + domain = "source.mnt.re"; + owner = "reform"; + repo = "reform-debian-packages"; + rev = "830c94db42beef876dc58ea56711659ae7bd415d"; + hash = "sha256-mdORgTOM7RJnEjY5G/iWMHf69wQkql11yRpQ/DrQKb4="; + }; + linuxPkg = + { + lib, + fetchzip, + buildLinux, + callPackage, + ... + }@args: + buildLinux ( + args + // rec { + version = "${modDirVersion}-mnt-reform"; + inherit modDirVersion; + + src = fetchzip { + url = "mirror://kernel/linux/kernel/v${lib.versions.major modDirVersion}.x/linux-${modDirVersion}.tar.xz"; + hash = "sha256-XiTuH40b3VJqzwygZzU0FcvMDj41Rq6IsMbm+3+QxDY="; + }; + + kernelPatches = + (map (patch: { inherit patch; }) ( + lib.filesystem.listFilesRecursive "${reformDebianPackages}/linux/patches${lib.versions.majorMinor modDirVersion}" + )) + ++ [ + { + patch = callPackage ./dtsPatch.nix { + inherit reformDebianPackages; + kernelSource = src; + }; + } + ]; + + structuredExtraConfig = with lib.kernel; { + # configuration options from https://source.mnt.re/reform/reform-debian-packages/-/blob/7f31ba3a6742d60d8d502c1d86e63ef5df3916bf/linux/config + DRM_LVDS_CODEC = module; + DRM_CDNS_MHDP8546 = module; + DRM_CDNS_HDMI_CEC = module; + DRM_IMX_CDNS_MHDP = module; + DRM_IMX_DCSS = module; + # PHY_FSL_IMX8MQ_HDPTX = module; # configuration option does not exist + DRM_PANEL_LVDS = module; + I2C_IMX_LPI2C = module; + I2C_MUX_REG = module; + INTERCONNECT_IMX = yes; + INTERCONNECT_IMX8MQ = yes; + MFD_WM8994 = module; + MUX_GPIO = module; + MUX_MMIO = module; + RTC_DRV_PCF8523 = module; + USB_EHCI_FSL = module; + # NO_HZ_IDLE = yes; # conflicts with NO_HZ_FULL + SND_SOC_FSL_MICFIL = module; + SND_IMX_SOC = module; + SND_SOC_FSL_ASOC_CARD = module; + SND_SOC_IMX_AUDMIX = module; + SND_SOC_IMX_HDMI = module; + INPUT_JOYSTICK = yes; + JOYSTICK_XPAD = module; + JOYSTICK_XPAD_FF = yes; + JOYSTICK_XPAD_LEDS = yes; + + INTERCONNECT_IMX8MP = yes; + SND_SOC_FSL_ASRC = yes; + DRM_IMX_LCDIF = yes; + DRM_IMX8MP_DW_HDMI_BRIDGE = yes; + DRM_IMX8MP_HDMI_PVI = yes; + IMX8MM_THERMAL = yes; + IMX2_WDT = yes; + DRM_SAMSUNG_DSIM = yes; + PHY_FSL_SAMSUNG_HDMI_PHY = yes; + DRM = yes; + DRM_PANEL_MNT_POCKET_REFORM = module; + IMX8M_BLK_CTRL = yes; + IMX_GPCV2_PM_DOMAINS = yes; + DRM_DISPLAY_CONNECTOR = yes; + DRM_FSL_LDB = yes; + BACKLIGHT_CLASS_DEVICE = yes; + BACKLIGHT_PWM = yes; + BACKLIGHT_GPIO = yes; + BACKLIGHT_LED = yes; + CPU_FREQ_GOV_PERFORMANCE = yes; + CPU_FREQ_GOV_POWERSAVE = yes; + CPU_FREQ_GOV_USERSPACE = yes; + CPU_FREQ_GOV_ONDEMAND = yes; + CPU_FREQ_GOV_CONSERVATIVE = yes; + CPU_FREQ_GOV_SCHEDUTIL = yes; + ARM_IMX_CPUFREQ_DT = yes; + ARM_IMX_BUS_DEVFREQ = yes; + IMX_IRQSTEER = yes; + + PCI_MESON = yes; + DWMAC_MESON = module; + MDIO_BUS_MUX_MESON_G12A = yes; + I2C_MESON = yes; + PWM_MESON = yes; + USB_DWC3_MESON_G12A = yes; + MMC_MESON_GX = yes; + MMC_MESON_MX_SDIO = yes; + MESON_DDR_PMU = yes; + RTW88_8822CS = module; + + PWM_FSL_FTM = yes; + FSL_RCPM = yes; + + ARCH_ROCKCHIP = yes; + # ARM_ROCKCHIP_CPUFREQ = module; # configuration option does not exist + DRM_PANTHOR = module; + NVMEM_ROCKCHIP_OTP = yes; + PHY_ROCKCHIP_SAMSUNG_HDPTX = module; + PHY_ROCKCHIP_USBDP = module; + REGULATOR = yes; + # ROCKCHIP_REGULATOR_COUPLER = yes; # configuration option does not exist + SPI_ROCKCHIP = yes; + SPI_ROCKCHIP_SFC = module; + ARM_SCMI_CPUFREQ = module; + VIDEO_ROCKCHIP_VDEC2 = module; + ROCKCHIP_DW_HDMI_QP = yes; + ROCKCHIP_DW_MIPI_DSI2 = yes; + PHY_ROCKCHIP_SAMSUNG_DCPHY = yes; + REGULATOR_FIXED_VOLTAGE = yes; + GPIO_ROCKCHIP = yes; + PL330_DMA = yes; + + DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW = no; # patches for 6.16 break this driver + }; + } + // (args.argsOverride or { }) + ); + +in +lib.recurseIntoAttrs (linuxPackagesFor (callPackage linuxPkg { })) diff --git a/mnt/reform/lpc.nix b/mnt/reform/lpc.nix new file mode 100644 index 000000000..ad1ef3d82 --- /dev/null +++ b/mnt/reform/lpc.nix @@ -0,0 +1,36 @@ +{ + stdenv, + lib, + fetchFromGitLab, + kernel, + kernelModuleMakeFlags, + kmod, +}: + +stdenv.mkDerivation rec { + name = "lpc"; + + src = fetchFromGitLab { + domain = "source.mnt.re"; + owner = "reform"; + repo = "reform-tools"; + rev = "45f930403492aa2156522bfe30edb02e33494b69"; + hash = "sha256-no33CsV69nu1TR0cqxQDd1bFXqhjqOW9IUDxds0fyxE="; + }; + + sourceRoot = "source/lpc"; + hardeningDisable = [ + "pic" + "format" + ]; + nativeBuildInputs = kernel.moduleBuildDependencies; + + installPhase = '' + make -C "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" M="$(pwd)" INSTALL_MOD_PATH=$out modules_install $makeFlags + ''; + + makeFlags = kernelModuleMakeFlags ++ [ + "KERNEL_DIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + "INSTALL_MOD_PATH=${placeholder "out"}" + ]; +} diff --git a/mnt/reform/rk3588/README.md b/mnt/reform/rk3588/README.md new file mode 100644 index 000000000..ec6da6b6b --- /dev/null +++ b/mnt/reform/rk3588/README.md @@ -0,0 +1,48 @@ +# MNT Reform Laptop with RK3588 CPU module + +## Creating an installer SD-Image + +Create and configure the `flake.nix` file: +``` nix +{ + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + inputs.nixos-hardware.url = "github:nixos/nixos-hardware"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, nixos-hardware, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + rec { + packages.default = packages.installer; + packages.installer = (import "${nixpkgs}/nixos" { + configuration = + { config, ... }: { + imports = [ + "${nixos-hardware}/mnt/reform/rk3588/installer.nix" + ]; + + # If you want to use ssh set a password + # users.users.nixos.password = "super secure password"; + # OR add your public ssh key + # users.users.nixos.openssh.authorizedKeys.keys = [ "ssh-rsa ..." ]; + + # Additional configuration goes here + + # Only used when cross compiling + nixpkgs.crossSystem = { + config = "aarch64-unknown-linux-gnu"; + system = "aarch64-linux"; + }; + + system.stateVersion = "23.05"; + }; + inherit system; + }).config.system.build.image;; + }); +} +``` + +Build the installer image. + +``` sh +nix build .# +``` diff --git a/mnt/reform/rk3588/default.nix b/mnt/reform/rk3588/default.nix new file mode 100644 index 000000000..f0bea6d48 --- /dev/null +++ b/mnt/reform/rk3588/default.nix @@ -0,0 +1,35 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + imports = [ ../. ]; + boot = { + # kernelParams = [ "console=ttyS2,1500000n8" ]; + kernelParams = [ + "no_console_suspend" + "console=tty1" + ]; + # kernel modules needed for the virtual console + initrd.availableKernelModules = [ + "panel-edp" + "phy-rockchip-samsung-hdptx" + "rockchipdrm" + "ti-sn65dsi86" + ]; + + }; + boot.loader = { + grub.enable = false; + generic-extlinux-compatible.enable = true; + }; + hardware.alsa.enablePersistence = true; + system.activationScripts.asound = '' + if [ ! -e "/var/lib/alsa/asound.state" ]; then + mkdir -p /var/lib/alsa + cp ${./initial-asound.state} /var/lib/alsa/asound.state + fi + ''; +} diff --git a/mnt/reform/rk3588/firmware.nix b/mnt/reform/rk3588/firmware.nix new file mode 100644 index 000000000..6d97991f0 --- /dev/null +++ b/mnt/reform/rk3588/firmware.nix @@ -0,0 +1,25 @@ +{ + runCommand, + uboot, + fetchFromGitHub, +}: +# script from https://source.mnt.re/reform/reform-rk3588-uboot/-/blob/b530d65f4a878c0329a594fa248ba8da59d2e05f/build.sh +runCommand "mnt-reform-firmware-rk3855${uboot.variant}" { } '' + mkdir $out + cp -r ${uboot} u-boot + cp -r ${uboot.rkbin} rkbin + chmod -R +rw u-boot + chmod -R +rw rkbin + cd u-boot + mkdir spl + mv u-boot-spl.bin spl + ../rkbin/tools/boot_merger rock5b-rk3588.ini + cd .. + # rkbin stuff + cd rkbin + ./tools/boot_merger RKBOOT/RK3588MINIALL.ini + # concatenate + cd .. + cp u-boot/idbloader.img $out/mnt-reform2-rk3588${uboot.variant}-flash.bin + dd if=u-boot/u-boot.itb of=$out/mnt-reform2-rk3588${uboot.variant}-flash.bin seek=16320 +'' diff --git a/mnt/reform/rk3588/initial-asound.state b/mnt/reform/rk3588/initial-asound.state new file mode 100644 index 000000000..2f595a820 --- /dev/null +++ b/mnt/reform/rk3588/initial-asound.state @@ -0,0 +1,702 @@ +state.rk3588wm8960 { + control.1 { + iface MIXER + name 'Capture Volume' + value.0 39 + value.1 39 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 63' + dbmin -1725 + dbmax 3000 + dbvalue.0 1200 + dbvalue.1 1200 + } + } + control.2 { + iface MIXER + name 'Capture Volume ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.3 { + iface MIXER + name 'Capture Switch' + value.0 true + value.1 true + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.4 { + iface MIXER + name 'Left Input Boost Mixer LINPUT3 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.5 { + iface MIXER + name 'Left Input Boost Mixer LINPUT2 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.6 { + iface MIXER + name 'Right Input Boost Mixer RINPUT3 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.7 { + iface MIXER + name 'Right Input Boost Mixer RINPUT2 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + } + } + control.8 { + iface MIXER + name 'Right Input Boost Mixer RINPUT1 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + dbmin 0 + dbmax 2900 + dbvalue.0 0 + } + } + control.9 { + iface MIXER + name 'Left Input Boost Mixer LINPUT1 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + dbmin 0 + dbmax 2900 + dbvalue.0 0 + } + } + control.10 { + iface MIXER + name 'Playback Volume' + value.0 215 + value.1 215 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -9999999 + dbmax 0 + dbvalue.0 -2000 + dbvalue.1 -2000 + } + } + control.11 { + iface MIXER + name 'Headphone Playback Volume' + value.0 0 + value.1 0 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 127' + dbmin -9999999 + dbmax 600 + dbvalue.0 -9999999 + dbvalue.1 -9999999 + } + } + control.12 { + iface MIXER + name 'Headphone Playback ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.13 { + iface MIXER + name 'Speaker Playback Volume' + value.0 109 + value.1 109 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 127' + dbmin -9999999 + dbmax 600 + dbvalue.0 -1200 + dbvalue.1 -1200 + } + } + control.14 { + iface MIXER + name 'Speaker Playback ZC Switch' + value.0 false + value.1 false + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.15 { + iface MIXER + name 'Speaker DC Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 5' + } + } + control.16 { + iface MIXER + name 'Speaker AC Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 5' + } + } + control.17 { + iface MIXER + name 'PCM Playback -6dB Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.18 { + iface MIXER + name 'ADC Polarity' + value 'No Inversion' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No Inversion' + item.1 'Left Inverted' + item.2 'Right Inverted' + item.3 'Stereo Inversion' + } + } + control.19 { + iface MIXER + name 'ADC High Pass Filter Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.20 { + iface MIXER + name 'DAC Polarity' + value 'No Inversion' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'No Inversion' + item.1 'Left Inverted' + item.2 'Right Inverted' + item.3 'Stereo Inversion' + } + } + control.21 { + iface MIXER + name 'DAC Deemphasis Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.22 { + iface MIXER + name '3D Filter Upper Cut-Off' + value High + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 High + item.1 Low + } + } + control.23 { + iface MIXER + name '3D Filter Lower Cut-Off' + value Low + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Low + item.1 High + } + } + control.24 { + iface MIXER + name '3D Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.25 { + iface MIXER + name '3D Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.26 { + iface MIXER + name 'ALC Function' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 Right + item.2 Left + item.3 Stereo + } + } + control.27 { + iface MIXER + name 'ALC Max Gain' + value 7 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.28 { + iface MIXER + name 'ALC Target' + value 4 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.29 { + iface MIXER + name 'ALC Min Gain' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.30 { + iface MIXER + name 'ALC Hold Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.31 { + iface MIXER + name 'ALC Mode' + value ALC + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 ALC + item.1 Limiter + } + } + control.32 { + iface MIXER + name 'ALC Decay' + value 3 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.33 { + iface MIXER + name 'ALC Attack' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.34 { + iface MIXER + name 'Noise Gate Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + } + } + control.35 { + iface MIXER + name 'Noise Gate Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.36 { + iface MIXER + name 'ADC PCM Capture Volume' + value.0 195 + value.1 195 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 255' + dbmin -9999999 + dbmax 3000 + dbvalue.0 0 + dbvalue.1 0 + } + } + control.37 { + iface MIXER + name 'Left Output Mixer Boost Bypass Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.38 { + iface MIXER + name 'Left Output Mixer LINPUT3 Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.39 { + iface MIXER + name 'Right Output Mixer Boost Bypass Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.40 { + iface MIXER + name 'Right Output Mixer RINPUT3 Volume' + value 2 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + dbmin -2100 + dbmax 0 + dbvalue.0 -1500 + } + } + control.41 { + iface MIXER + name 'ADC Data Output Select' + value 'Left Data = Left ADC; Right Data = Right ADC' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 'Left Data = Left ADC; Right Data = Right ADC' + item.1 'Left Data = Left ADC; Right Data = Left ADC' + item.2 'Left Data = Right ADC; Right Data = Right ADC' + item.3 'Left Data = Right ADC; Right Data = Left ADC' + } + } + control.42 { + iface MIXER + name 'DAC Mono Mix' + value Stereo + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Stereo + item.1 Mono + } + } + control.43 { + iface MIXER + name 'DAC Filter Characteristics' + value Normal + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Normal + item.1 Sloping + } + } + control.44 { + iface MIXER + name 'Left Boost Mixer LINPUT2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.45 { + iface MIXER + name 'Left Boost Mixer LINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.46 { + iface MIXER + name 'Left Boost Mixer LINPUT1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.47 { + iface MIXER + name 'Right Boost Mixer RINPUT2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.48 { + iface MIXER + name 'Right Boost Mixer RINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.49 { + iface MIXER + name 'Right Boost Mixer RINPUT1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.50 { + iface MIXER + name 'Left Input Mixer Boost Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.51 { + iface MIXER + name 'Right Input Mixer Boost Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.52 { + iface MIXER + name 'Left Output Mixer PCM Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.53 { + iface MIXER + name 'Left Output Mixer LINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.54 { + iface MIXER + name 'Left Output Mixer Boost Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.55 { + iface MIXER + name 'Right Output Mixer PCM Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.56 { + iface MIXER + name 'Right Output Mixer RINPUT3 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.57 { + iface MIXER + name 'Right Output Mixer Boost Bypass Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.58 { + iface MIXER + name 'Mono Output Mixer Left Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.59 { + iface MIXER + name 'Mono Output Mixer Right Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } +} diff --git a/mnt/reform/rk3588/installer.nix b/mnt/reform/rk3588/installer.nix new file mode 100644 index 000000000..af7c5580e --- /dev/null +++ b/mnt/reform/rk3588/installer.nix @@ -0,0 +1,238 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +{ + imports = [ + "${modulesPath}/image/file-options.nix" + "${modulesPath}/profiles/installation-device.nix" + ./. + ]; + + options.installerImage = { + compressImage = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether the installer image should be compressed using + {command}`zstd`. + ''; + }; + squashfsCompression = lib.mkOption { + default = "zstd -Xcompression-level 19"; + type = lib.types.nullOr lib.types.str; + description = '' + Compression settings to use for the squashfs nix store. + `null` disables compression. + ''; + example = "zstd -Xcompression-level 6"; + }; + storeContents = lib.mkOption { + example = lib.literalExpression "[ pkgs.stdenv ]"; + description = '' + This option lists additional derivations to be included in the + Nix store in the generated installer image. + ''; + }; + }; + config = + let + squashfs = pkgs.callPackage "${modulesPath}/../lib/make-squashfs.nix" { + storeContents = config.installerImage.storeContents; + comp = config.installerImage.squashfsCompression; + }; + uboot = pkgs.callPackage ./uboot.nix { }; + firmware = pkgs.callPackage ./firmware.nix { inherit uboot; }; + content = pkgs.callPackage ( + { + stdenv, + e2fsprogs, + libfaketime, + fakeroot, + }: + stdenv.mkDerivation { + name = "ext4-fs.img"; + nativeBuildInputs = [ + e2fsprogs.bin + libfaketime + fakeroot + ]; + buildCommand = '' + img=$out + mkdir -p ./files + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./rootImage/boot + ( + GLOBIGNORE=".:.." + shopt -u dotglob + + for f in ./files/*; do + cp -a --reflink=auto -t ./rootImage/ "$f" + done + ) + cp -a --reflink=auto ${squashfs} ./rootImage/nix-store.squashfs + + + # Make a crude approximation of the size of the target image. + # If the script starts failing, increase the fudge factors here. + numInodes=$(find ./rootImage | wc -l) + numDataBlocks=$(du -s -c -B 4096 --apparent-size ./rootImage | tail -1 | awk '{ print int($1 * 1.20) }') + bytes=$((2 * 4096 * $numInodes + 4096 * $numDataBlocks)) + echo "Creating an EXT4 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks)" + + mebibyte=$(( 1024 * 1024 )) + # Round up to the nearest mebibyte. + # This ensures whole 512 bytes sector sizes in the disk image + # and helps towards aligning partitions optimally. + if (( bytes % mebibyte )); then + bytes=$(( ( bytes / mebibyte + 1) * mebibyte )) + fi + + truncate -s $bytes $img + + faketime -f "1970-01-01 00:00:01" fakeroot mkfs.ext4 -L NIXOS_ROOT -U 44444444-4444-4444-8888-888888888888 -d ./rootImage $img + + export EXT2FS_NO_MTAB_OK=yes + # I have ended up with corrupted images sometimes, I suspect that happens when the build machine's disk gets full during the build. + if ! fsck.ext4 -n -f $img; then + echo "--- Fsck failed for EXT4 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks) ---" + cat errorlog + return 1 + fi + + # We may want to shrink the file system and resize the image to + # get rid of the unnecessary slack here--but see + # https://github.com/NixOS/nixpkgs/issues/125121 for caveats. + + # shrink to fit + resize2fs -M $img + + # Add 16 MebiByte to the current_size + new_size=$(dumpe2fs -h $img | awk -F: \ + '/Block count/{count=$2} /Block size/{size=$2} END{print (count*size+16*2**20)/size}') + + resize2fs $img $new_size + ''; + } + ) { }; + in + { + fileSystems = { + "/" = lib.mkImageMediaOverride { + fsType = "tmpfs"; + options = [ "mode=0755" ]; + }; + + "/iso" = lib.mkImageMediaOverride { + device = "/dev/disk/by-label/NIXOS_ROOT"; + neededForBoot = true; + noCheck = true; + options = [ "ro" ]; + }; + + # In stage 1, mount a tmpfs on top of /nix/store (the squashfs + # image) to make this a live CD. + "/nix/.ro-store" = lib.mkImageMediaOverride { + fsType = "squashfs"; + device = "/iso/nix-store.squashfs"; + options = [ + "loop" + ] ++ lib.optional (config.boot.kernelPackages.kernel.kernelAtLeast "6.2") "threads=multi"; + neededForBoot = true; + }; + + "/nix/.rw-store" = lib.mkImageMediaOverride { + fsType = "tmpfs"; + options = [ "mode=0755" ]; + neededForBoot = true; + }; + + "/nix/store" = lib.mkImageMediaOverride { + fsType = "overlay"; + device = "overlay"; + options = [ + "lowerdir=/nix/.ro-store" + "upperdir=/nix/.rw-store/store" + "workdir=/nix/.rw-store/work" + ]; + depends = [ + "/nix/.ro-store" + "/nix/.rw-store/store" + "/nix/.rw-store/work" + ]; + }; + }; + + boot = { + initrd.availableKernelModules = [ + "squashfs" + "uas" + "overlay" + ]; + initrd.kernelModules = [ + "loop" + "overlay" + ]; + loader.timeout = 0; + }; + + image.extension = if config.installerImage.compressImage then "img.zst" else "img"; + image.filePath = "installer-image/${config.image.fileName}"; + + installerImage.storeContents = [ config.system.build.toplevel ]; + + system.build.image = pkgs.callPackage ( + { stdenv, util-linux }: + stdenv.mkDerivation { + name = config.image.fileName; + nativeBuildInputs = [ util-linux ]; + inherit (config.installerImage) compressImage; + buildCommand = '' + mkdir -p $out/nix-support $out/installer-image + img=$out/installer-image/${config.image.baseName}.img + + echo "${stdenv.buildPlatform.system}" > $out/nix-support/system + if test -n "$compressImage"; then + echo "file installer-image $img.zst" >> $out/nix-support/hydra-build-products + else + echo "file installer-image $img" >> $out/nix-support/hydra-build-products + fi + + sectors=$((($(stat -c '%s' ${content})+511)/512)) + # create disk image + truncate -s $((($sectors + 32768 + 2048)*512)) $img + sfdisk $img <