diff --git a/README.md b/README.md index 29e22f7a0..273ca628a 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,7 @@ See code for all available configurations. | [Lenovo ThinkPad X1 Extreme Gen 3](lenovo/thinkpad/x1-extreme/gen3) | `` | | [Lenovo ThinkPad X1 Extreme Gen 4](lenovo/thinkpad/x1-extreme/gen4) | `` | | [Lenovo ThinkPad X1 Nano Gen 1](lenovo/thinkpad/x1-nano/gen1) | `` | +| [Lenovo ThinkPad X13s](lenovo/thinkpad/x13s) | `` | | [Lenovo ThinkPad X13 Yoga](lenovo/thinkpad/x13/yoga) | `` | | [Lenovo ThinkPad X13 Yoga (3th Gen)](lenovo/thinkpad/x13/yoga/3th-gen) | `` | | [Lenovo ThinkPad X13 (Intel)](lenovo/thinkpad/x13/intel) | `` | diff --git a/flake.nix b/flake.nix index 629d8f71b..848265ca0 100644 --- a/flake.nix +++ b/flake.nix @@ -244,6 +244,7 @@ lenovo-thinkpad-x13-amd = import ./lenovo/thinkpad/x13/amd; lenovo-thinkpad-x13-yoga = import ./lenovo/thinkpad/x13/yoga; lenovo-thinkpad-x13-yoga-3th-gen = import ./lenovo/thinkpad/x13/yoga/3th-gen; + lenovo-thinkpad-x13s = import ./lenovo/thinkpad/x13s; lenovo-thinkpad-x140e = import ./lenovo/thinkpad/x140e; lenovo-thinkpad-x200s = import ./lenovo/thinkpad/x200s; lenovo-thinkpad-x220 = import ./lenovo/thinkpad/x220; diff --git a/lenovo/thinkpad/x13s/README.md b/lenovo/thinkpad/x13s/README.md new file mode 100644 index 000000000..f46081852 --- /dev/null +++ b/lenovo/thinkpad/x13s/README.md @@ -0,0 +1,10 @@ +# Lenovo X13s + +[Debian](https://wiki.debian.org/InstallingDebianOn/Thinkpad/X13s) +[PostmarketOS](https://wiki.postmarketos.org/wiki/Lenovo_ThinkPad_X13s_(lenovo-21bx)) + +## Camera +The MIPI camera does work, however, it's not accelerated by the ISP and therefore image processing is done on CPU. + +## Wifi and Bluetooth MAC addresses +Currently they need to be set manually diff --git a/lenovo/thinkpad/x13s/default.nix b/lenovo/thinkpad/x13s/default.nix new file mode 100644 index 000000000..161d3891e --- /dev/null +++ b/lenovo/thinkpad/x13s/default.nix @@ -0,0 +1,101 @@ +{ lib, pkgs, ... }: + +let + dtbName = "sc8280xp-lenovo-thinkpad-x13s.dtb"; + dtb = "${pkgs.linux}/dtbs/qcom/${dtbName}"; + # Version the dtb based on the kernel + dtbEfiPath = "dtbs/x13s-${pkgs.linux.version}.dtb"; + cfg = { + wifiMac = "e4:65:38:52:22:a9"; + bluetoothMac = "E4:25:18:22:44:AA"; + }; + inherit (lib) mkDefault; +in +{ + imports = [ + ../. + ../../../common/pc/laptop + ]; + + boot = { + loader.systemd-boot.extraFiles = { + "${dtbEfiPath}" = dtb; + }; + + kernelParams = mkDefault [ + # needed to boot + "dtb=${dtbEfiPath}" + + # jhovold recommended + "clk_ignore_unused" + "pd_ignore_unused" + "arm64.nopauth" + ]; + + kernelModules = mkDefault [ + "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" + ]; + }; + + hardware.enableRedistributableFirmware = mkDefault true; + + systemd.services.bluetooth-x13s-mac = lib.mkIf (cfg.bluetoothMac != null) { + wantedBy = [ "multi-user.target" ]; + before = [ "bluetooth.service" ]; + requiredBy = [ "bluetooth.service" ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.util-linux}/bin/script -q -c '${pkgs.bluez}/bin/btmgmt --index 0 public-addr ${cfg.bluetoothMac}'"; + }; + }; + + # https://github.com/jhovold/linux/wiki/X13s#modem + networking.networkmanager.fccUnlockScripts = [ + + { + id = "105b:e0c3"; + path = "${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/105b"; + } + ]; + + # https://github.com/jhovold/linux/wiki/X13s#camera + services.udev.extraRules = lib.strings.concatLines ( + [ + '' + ACTION=="add", SUBSYSTEM=="dma_heap", KERNEL=="linux,cma", GROUP="video", MODE="0660" + ACTION=="add", SUBSYSTEM=="dma_heap", KERNEL=="system", GROUP="video", MODE="0660" + '' + ] + ++ ( + if cfg.wifiMac != null then + [ + '' + ACTION=="add", SUBSYSTEM=="net", KERNELS=="0006:01:00.0", RUN+="${pkgs.iproute2}/bin/ip link set dev $name address ${cfg.wifiMac}" + '' + ] + else + [ ] + ) + ); +}