diff --git a/README.md b/README.md index 0d782a8..3978d37 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,6 @@ There is also experimental flake support. In your `/etc/nixos/flake.nix` add the } ``` - ### Using fetchGit You can fetch the git repository directly: @@ -66,7 +65,7 @@ you can easily pin to a particular revision if you desire more stability. See code for all available configurations. | Model | Path | -|---------------------------------------------------------------------|----------------------------------------------------| +| ------------------------------------------------------------------- | -------------------------------------------------- | | [Acer Aspire 4810T](acer/aspire/4810t) | `` | | [Airis N990](airis/n990) | `` | | [Apple MacBook Air 3,X](apple/macbook-air/3) | `` | @@ -110,7 +109,7 @@ See code for all available configurations. | [Intel NUC 8i7BEH](intel/nuc/8i7beh/) | `` | | [Lenovo IdeaPad Z510](lenovo/ideapad/z510) | `` | | [Lenovo Legion 5 15arh05h](lenovo/legion/15arh05h) | `` | -| [Lenovo Legion 7 Slim 15ach6](lenovo/legion/15ach6) | `` | +| [Lenovo Legion 7 Slim 15ach6](lenovo/legion/15ach6) | `` | | [Lenovo ThinkPad E14 (AMD)](lenovo/thinkpad/e14/amd) | `` | | [Lenovo ThinkPad E14 (Intel)](lenovo/thinkpad/e14/intel) | `` | | [Lenovo ThinkPad E470](lenovo/thinkpad/e470) | `` | @@ -162,6 +161,7 @@ See code for all available configurations. | [Microsoft Surface Range](microsoft/surface) | `` | | [One-Netbook OneNetbook 4](onenetbook/4) | `` | | [PC Engines APU](pcengines/apu) | `` | +| [PINE64 Pinebook Pro](pine64/pinebook-pro/) | `` | | [Purism Librem 13v3](purism/librem/13v3) | `` | | [Purism Librem 15v3](purism/librem/13v3) | `` | | [Raspberry Pi 2](raspberry-pi/2) | `` | diff --git a/flake.nix b/flake.nix index cf698b5..990f44f 100644 --- a/flake.nix +++ b/flake.nix @@ -103,6 +103,7 @@ msi-gs60 = import ./msi/gs60; onenetbook-4 = import ./onenetbook/4; pcengines-apu = import ./pcengines/apu; + pine64-pinebook-pro = import ./pine64/pinebook-pro; purism-librem-13v3 = import ./purism/librem/13v3; purism-librem-15v3 = import ./purism/librem/15v3; raspberry-pi-2 = import ./raspberry-pi/2; diff --git a/pine64/pinebook-pro/README.md b/pine64/pinebook-pro/README.md new file mode 100644 index 0000000..b6c0811 --- /dev/null +++ b/pine64/pinebook-pro/README.md @@ -0,0 +1,100 @@ +> **NOTE**: This is an attempt to port [samueldr](https://github.com/samueldr/)'s [wip-pinebookpro](https://github.com/samueldr/wip-pinebook-pro) to [nixos-hardware](https://github.com/NixOS/nixos-hardware). Credit for the work done goes to the original authors. + +## Using in your configuration + +To use this configuration simply add this module to your configuration. + +```nix +{ + imports = [ + ${nixos-hardware}/pine64/pinebook-pro + ]; +} +``` + +That entry point will try to maximize the hardware compatibility. + +## Current state + +Currently everything seems to work but this is not guaranteed it will be forever. + +### Kernel + +This module defaults to the latest upstream kernel. Attempts have been made to +use manjaro's kernel that makes the DP alt mode available over Type-C, but it +turns out that the kernel is unstable and some sporadic kernel panics may occur. +If you want to this kernel, you can grab the nix expression from this commit: +https://github.com/NixOS/nixos-hardware/blob/6d1bd5bc2e8b9992a3f57e416ba50fbed5516db6/pine64/pinebook-pro/kernel/default.nix + +### Known issues + +#### HDMI over Type-C + +HDMI over Type-C works only for the custom kernel and the audio dosen't work (it's an upstream problem). + +#### `rockchipdrm` and `efifb` + +This can be worked around by booting with the `efifb=off` kernel command-line. + +This is already handled for you by this configuration. If using the generic +UEFI AArch64 iso, you will need to add the option yourself to the command-line +using GRUB. + +#### _EFI_ and poweroff + +When booted using EFI, the system will not power off. It will stay seemingly +stuck with the LED and display turned off. + +A [workaround exists](https://github.com/Tow-Boot/Tow-Boot/commit/818cae1b84a7702f2a509927f2819900c2881979#diff-20f50d9d8d5d6c059b87ad66fbc5df26d9fc46251763547ca9bdcc75564a4368), +and is built in recent Tow-Boot (make sure your release is 2021.10-004 or more recent). + +### _Tow-Boot_ + +We highly suggest installing _Tow-Boot_ to the SPI Flash. + +- https://github.com/Tow-Boot/Tow-Boot + +Having the firmware installed to SPI makes the device act basically like a +normal computer. No need for weird incantations to setup the platform boot +firmware. + +Alternatively, starting from the _Tow-Boot_ disk image on eMMC is easier to +deal with and understand than having to deal with _U-Boot_ manually. + +### Mainline _U-Boot_ + +Mainline U-Boot has full support for graphics since 2021.04. The current +unstable relases of Nixpkgs are at 2021.04 at least. + +``` + $ nix-build -A pkgs.ubootPinebookPro +``` + +Note that the default U-Boot build does not do anything with LED on startup. + +## Keyboard firmware + +> **WARNING**: Some hardware batches for the Pinebook Pro ship with the +> wrong chip for the keyboard controller. While it will work with the +> firmware it ships with, it _may brick_ while flashing the updated +> firmware. [See this comment on the firmware repository](https://github.com/jackhumbert/pinebook-pro-keyboard-updater/issues/33#issuecomment-850889285). +> +> It is unclear how to identify said hardware from a running system. + +To determine which keyboard controller you have, you will need to disassemble +the Pinebook Pro as per [the Pine64 +wiki](https://wiki.pine64.org/wiki/Pinebook_Pro#Keyboard), and make sure that +the IC next to the U23 marking on the main board is an **SH68F83**. + +```sh + $ nix-build -A pkgs.pinebookpro-keyboard-updater + $ sudo ./result/bin/updater step-1 + $ sudo poweroff + # ... + $ sudo ./result/bin/updater step-2 + $ sudo poweroff + # ... + $ sudo ./result/bin/updater flash-kb-revised +``` + +Note: poweroff must be used, reboot does not turn the hardware "off" enough. diff --git a/pine64/pinebook-pro/default.nix b/pine64/pinebook-pro/default.nix new file mode 100644 index 0000000..799596c --- /dev/null +++ b/pine64/pinebook-pro/default.nix @@ -0,0 +1,90 @@ +# This configuration file can be safely imported in your system configuration. +{ config, pkgs, lib, ... }: + +{ + nixpkgs.overlays = [ + (import ./overlay.nix) + ]; + + boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; + + # This list of modules is not entirely minified, but represents + # a set of modules that is required for the display to work in stage-1. + # Further minification can be done, but requires trial-and-error mainly. + boot.initrd.kernelModules = [ + # Rockchip modules + "rockchip_rga" + "rockchip_saradc" + "rockchip_thermal" + "rockchipdrm" + + # GPU/Display modules + "analogix_dp" + "cec" + "drm" + "drm_kms_helper" + "dw_hdmi" + "dw_mipi_dsi" + "gpu_sched" + "panel_edp" + "panel_simple" + "panfrost" + "pwm_bl" + + # USB / Type-C related modules + "fusb302" + "tcpm" + "typec" + + # Misc. modules + "cw2015_battery" + "gpio_charger" + "rtc_rk808" + ]; + + services.udev.extraHwdb = lib.mkMerge [ + # https://gitlab.manjaro.org/manjaro-arm/packages/community/pinebookpro-post-install/blob/master/10-usb-kbd.hwdb + '' + evdev:input:b0003v258Ap001E* + KEYBOARD_KEY_700a5=brightnessdown + KEYBOARD_KEY_700a6=brightnessup + KEYBOARD_KEY_70066=sleep + '' + + # https://github.com/elementary/os/blob/05a5a931806d4ed8bc90396e9e91b5ac6155d4d4/build-pinebookpro.sh#L253-L257 + # Disable the "keyboard mouse" in libinput. This is reported by the keyboard firmware + # and is probably a placeholder for a TrackPoint style mouse that doesn't exist + '' + evdev:input:b0003v258Ap001Ee0110-e0,1,2,4,k110,111,112,r0,1,am4,lsfw + ID_INPUT=0 + ID_INPUT_MOUSE=0 + '' + ]; + + # https://github.com/elementary/os/blob/05a5a931806d4ed8bc90396e9e91b5ac6155d4d4/build-pinebookpro.sh#L253-L257 + # Mark the keyboard as internal, so that "disable when typing" works for the touchpad + environment.etc."libinput/local-overrides.quirks".text = '' + [Pinebook Pro Keyboard] + MatchUdevType=keyboard + MatchBus=usb + MatchVendor=0x258A + MatchProduct=0x001E + AttrKeyboardIntegration=internal + ''; + + hardware.enableRedistributableFirmware = true; + hardware.firmware = [ + (pkgs.callPackage ./firmware/ap6256-firmware { }) + ]; + + systemd.tmpfiles.rules = [ + # Tweak the minimum frequencies of the GPU and CPU governors to get a bit more performance + # https://github.com/elementary/os/blob/05a5a931806d4ed8bc90396e9e91b5ac6155d4d4/build-pinebookpro.sh#L288-L294 + "w- /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq - - - - 1200000" + "w- /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq - - - - 1008000" + "w- /sys/class/devfreq/ff9a0000.gpu/min_freq - - - - 600000000" + ]; + + # The default powersave makes the wireless connection unusable. + networking.networkmanager.wifi.powersave = lib.mkDefault false; +} diff --git a/pine64/pinebook-pro/firmware/ap6256-firmware/default.nix b/pine64/pinebook-pro/firmware/ap6256-firmware/default.nix new file mode 100644 index 0000000..2c66766 --- /dev/null +++ b/pine64/pinebook-pro/firmware/ap6256-firmware/default.nix @@ -0,0 +1,39 @@ +{ lib +, fetchFromGitHub +, runCommandNoCC +}: + +let + src = fetchFromGitHub { + owner = "nix-community"; + repo = "rkwifibt"; + rev = "421b7dd8f3c67f66910710838a0be03f3575a3c9"; + sha256 = "175qcjfaz7nhpyh0hxiih53k3hly407lkpxgissvldghxrw01ccn"; + }; +in +runCommandNoCC "pinebookpro-ap6256-firmware" +{ + meta = with lib; { + license = licenses.unfreeRedistributable; + }; +} '' + (PS4=" $ "; set -x + cp ${src}/"BCM4345C5.hcd" "BCM4345C5.hcd" + cp ${src}/"fw_bcm43456c5_ag.bin" "fw_bcm43456c5_ag.bin" + cp ${src}/"brcmfmac43456-sdio.clm_blob" "brcmfmac43456-sdio.clm_blob" + cp ${src}/"nvram_ap6256.txt" "nvram_ap6256.txt" + mkdir -p $out/lib/firmware/brcm + # Bluetooth firmware + install -Dm644 "BCM4345C5.hcd" -t "$out/lib/firmware/" + install -Dm644 "BCM4345C5.hcd" "$out/lib/firmware/brcm/BCM.hcd" + install -Dm644 "BCM4345C5.hcd" -t "$out/lib/firmware/brcm/" + # Wifi firmware + install -Dm644 "nvram_ap6256.txt" -t "$out/lib/firmware/" + install -Dm644 "fw_bcm43456c5_ag.bin" "$out/lib/firmware/brcm/brcmfmac43456-sdio.bin" + install -Dm644 "brcmfmac43456-sdio.clm_blob" "$out/lib/firmware/brcm/brcmfmac43456-sdio.clm_blob" + install -Dm644 "nvram_ap6256.txt" "$out/lib/firmware/brcm/brcmfmac43456-sdio.radxa,rockpi4b.txt" + install -Dm644 "nvram_ap6256.txt" "$out/lib/firmware/brcm/brcmfmac43456-sdio.radxa,rockpi4c.txt" + install -Dm644 "nvram_ap6256.txt" "$out/lib/firmware/brcm/brcmfmac43456-sdio.pine64,pinebook-pro.txt" + install -Dm644 "nvram_ap6256.txt" "$out/lib/firmware/brcm/brcmfmac43456-sdio.pine64,rockpro64-v2.1.txt" + ) +'' diff --git a/pine64/pinebook-pro/keyboard-updater/default.nix b/pine64/pinebook-pro/keyboard-updater/default.nix new file mode 100644 index 0000000..3f3cf71 --- /dev/null +++ b/pine64/pinebook-pro/keyboard-updater/default.nix @@ -0,0 +1,26 @@ +{ stdenv, fetchFromGitHub, xxd, libusb }: + +stdenv.mkDerivation { + pname = "pinebook-pro-keyboard-updater"; + version = "2021-07-28"; + + nativeBuildInputs = [ + xxd + ]; + + buildInputs = [ + libusb + ]; + + installPhase = '' + mkdir -p $out/bin + cp -v updater $out/bin + ''; + + src = fetchFromGitHub { + owner = "dragan-simic"; + repo = "pinebook-pro-keyboard-updater"; + rev = "bd8d2ea48992b3e6ddd0b9435d21b74cdcf97224"; + hash = "sha256-3+Qsa5lk1EJrLvPSyWthqBMTqJCigbJSmnsS6hdu+w8="; + }; +} diff --git a/pine64/pinebook-pro/overlay.nix b/pine64/pinebook-pro/overlay.nix new file mode 100644 index 0000000..8d140f0 --- /dev/null +++ b/pine64/pinebook-pro/overlay.nix @@ -0,0 +1,8 @@ +final: super: + +let + inherit (final) callPackage; +in +{ + pinebookpro-keyboard-updater = callPackage ./keyboard-updater { }; +} diff --git a/pine64/pinebook-pro/sound/reset-sound.rb b/pine64/pinebook-pro/sound/reset-sound.rb new file mode 100644 index 0000000..d92c2b7 --- /dev/null +++ b/pine64/pinebook-pro/sound/reset-sound.rb @@ -0,0 +1,227 @@ +#!/usr/bin/env nix-shell +#! nix-shell -p ruby alsaUtils -i ruby + +# This script resets the sound state to the minimum required for it to work. +# It will set the control that pulseaudio uses to 20%, everything else to the +# level expected for it to work. The rest will be off or to their default. + +require "open3" +require "shellwords" + +def run(*cmd) + puts " $ #{cmd.shelljoin}" + system(*cmd) +end + +FINAL_STATE = { + ## Simple mixer control 'Headphone',0 + ## Capabilities: pvolume + ## Playback channels: Front Left - Front Right + ## Limits: Playback 0 - 3 + ## Mono: + ## Front Left: Playback 0 [0%] [-48.00dB] + ## Front Right: Playback 0 [0%] [-48.00dB] + "Headphone,0" => "20%", + ## Simple mixer control 'Headphone Mixer',0 + ## Capabilities: volume + ## Playback channels: Front Left - Front Right + ## Capture channels: Front Left - Front Right + ## Limits: 0 - 11 + ## Front Left: 0 [0%] [-12.00dB] + ## Front Right: 0 [0%] [-12.00dB] + "Headphone Mixer,0" => "0", + ## Simple mixer control 'Mic Boost',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [on] + "Mic Boost,0" => "off", + ## Simple mixer control 'Playback Polarity',0 + ## Capabilities: enum + ## Items: 'Normal' 'R Invert' 'L Invert' 'L + R Invert' + ## Item0: 'Normal' + "Playback Polarity,0" => "L Invert", + ## Simple mixer control 'Capture Polarity',0 + ## Capabilities: enum + ## Items: 'Normal' 'Invert' + ## Item0: 'Normal' + "Capture Polarity,0" => "Normal", + ## Simple mixer control 'ADC',0 + ## Capabilities: cvolume cvolume-joined + ## Capture channels: Mono + ## Limits: Capture 0 - 192 + ## Mono: Capture 0 [0%] [-99999.99dB] + "ADC,0" => "0", + ## Simple mixer control 'ADC Double Fs',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "ADC Double Fs,0" => "off", + ## Simple mixer control 'ADC PGA Gain',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 10 + ## Mono: 0 [0%] + "ADC PGA Gain,0" => "0", + ## Simple mixer control 'ADC Soft Ramp',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [on] + "ADC Soft Ramp,0" => "on", + ## Simple mixer control 'ALC',0 + ## Capabilities: cswitch cswitch-joined + ## Capture channels: Mono + ## Mono: Capture [off] + "ALC,0" => "nocap", + ## Simple mixer control 'ALC Capture Attack Time',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 10 + ## Mono: 0 [0%] + "ALC Capture Attack Time,0" => "0", + ## Simple mixer control 'ALC Capture Decay Time',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 10 + ## Mono: 0 [0%] + "ALC Capture Decay Time,0" => "0", + ## Simple mixer control 'ALC Capture Hold Time',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 10 + ## Mono: 0 [0%] + "ALC Capture Hold Time,0" => "0", + ## Simple mixer control 'ALC Capture Max',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 28 + ## Mono: 0 [0%] [-6.50dB] + "ALC Capture Max,0" => "0", + ## Simple mixer control 'ALC Capture Min',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 28 + ## Mono: 0 [0%] [-12.00dB] + "ALC Capture Min,0" => "0", + ## Simple mixer control 'ALC Capture Noise Gate',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "ALC Capture Noise Gate,0" => "off", + ## Simple mixer control 'ALC Capture Noise Gate Threshold',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 31 + ## Mono: 0 [0%] + "ALC Capture Noise Gate Threshold,0" => "0", + ## Simple mixer control 'ALC Capture Noise Gate Type',0 + ## Capabilities: enum + ## Items: 'Constant PGA Gain' 'Mute ADC Output' + ## Item0: 'Constant PGA Gain' + "ALC Capture Noise Gate Type,0" => "Constant PGA Gain", + ## Simple mixer control 'ALC Capture Target',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 10 + ## Mono: 0 [0%] [-16.50dB] + "ALC Capture Target,0" => "0", + ## Simple mixer control 'DAC',0 + ## Capabilities: pvolume + ## Playback channels: Front Left - Front Right + ## Limits: Playback 0 - 192 + ## Mono: + ## Front Left: Playback 0 [0%] [-99999.99dB] + ## Front Right: Playback 0 [0%] [-99999.99dB] + "DAC,0" => "100%", + ## Simple mixer control 'DAC Double Fs',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "DAC Double Fs,0" => "off", + ## Simple mixer control 'DAC Mono Mix',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "DAC Mono Mix,0" => "off", + ## Simple mixer control 'DAC Notch Filter',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "DAC Notch Filter,0" => "off", + ## Simple mixer control 'DAC Soft Ramp',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [on] + "DAC Soft Ramp,0" => "on", + ## Simple mixer control 'DAC Soft Ramp Rate',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 4 + ## Mono: 0 [0%] + "DAC Soft Ramp Rate,0" => "0", + ## Simple mixer control 'DAC Source Mux',0 + ## Capabilities: enum + ## Items: 'LDATA TO LDAC, RDATA TO RDAC' 'LDATA TO LDAC, LDATA TO RDAC' 'RDATA TO LDAC, RDATA TO RDAC' 'RDATA TO LDAC, LDATA TO RDAC' + ## Item0: 'LDATA TO LDAC, RDATA TO RDAC' + "DAC Source Mux,0" => "LDATA TO LDAC, RDATA TO RDAC", + ## Simple mixer control 'DAC Stereo Enhancement',0 + ## Capabilities: volume volume-joined + ## Playback channels: Mono + ## Capture channels: Mono + ## Limits: 0 - 7 + ## Mono: 0 [0%] + "DAC Stereo Enhancement,0" => "0", + ## Simple mixer control 'Differential Mux',0 + ## Capabilities: enum + ## Items: 'lin1-rin1' 'lin2-rin2' 'lin1-rin1 with 20db Boost' 'lin2-rin2 with 20db Boost' + ## Item0: 'lin1-rin1' + "Differential Mux,0" => "lin1-rin1", + ## Simple mixer control 'Digital Mic Mux',0 + ## Capabilities: enum + ## Items: 'dmic disable' 'dmic data at high level' 'dmic data at low level' + ## Item0: 'dmic disable' + "Digital Mic Mux,0" => "dmic disable", + ## Simple mixer control 'Left Headphone Mixer LLIN',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "Left Headphone Mixer LLIN,0" => "off", + ## Simple mixer control 'Left Headphone Mixer Left DAC',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "Left Headphone Mixer Left DAC,0" => "on", + ## Simple mixer control 'Left Headphone Mux',0 + ## Capabilities: enum + ## Items: 'lin1-rin1' 'lin2-rin2' 'lin-rin with Boost' 'lin-rin with Boost and PGA' + ## Item0: 'lin1-rin1' + "Left Headphone Mux,0" => "lin1-rin1", + ## Simple mixer control 'Right Headphone Mixer RLIN',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "Right Headphone Mixer RLIN,0" => "off", + ## Simple mixer control 'Right Headphone Mixer Right DAC',0 + ## Capabilities: pswitch pswitch-joined + ## Playback channels: Mono + ## Mono: Playback [off] + "Right Headphone Mixer Right DAC,0" => "on", + ## Simple mixer control 'Right Headphone Mux',0 + ## Capabilities: enum + ## Items: 'lin1-rin1' 'lin2-rin2' 'lin-rin with Boost' 'lin-rin with Boost and PGA' + ## Item0: 'lin1-rin1' + "Right Headphone Mux,0" => "lin1-rin1", +} + +FINAL_STATE.each do |name, value| + run("amixer", "-c0", "sset", name, value.to_s) + raise "Error setting #{name} to #{value}" unless $?.success? +end