The Ryzen 7 3700U (Zen+) lacks CPPC, and the laptop exposes no ACPI platform_profile, so power-profiles-daemon has no real backend and only shows placeholder profiles. Swap the ppd widget for a custom waybar module backed by a small `cpugov` helper that reads and toggles the cpufreq governor directly. Left-click cycles schedutil <-> performance via a NOPASSWD sudo rule scoped to the wrapper path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
80 lines
2.3 KiB
Nix
80 lines
2.3 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
# CPU governor toggle for hosts without a power-profiles-daemon backend
|
|
# (e.g. Zen+ CPUs that lack CPPC and laptops with no ACPI platform_profile).
|
|
# Installs a `cpugov` helper used by the waybar custom/cpugov widget and
|
|
# allows wheel users to write the governor without a password prompt.
|
|
|
|
let
|
|
cpugov = pkgs.writeShellApplication {
|
|
name = "cpugov";
|
|
text = ''
|
|
cur() {
|
|
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
|
|
}
|
|
|
|
apply() {
|
|
local gov="$1"
|
|
case "$gov" in
|
|
performance|schedutil|powersave|ondemand|conservative|userspace) ;;
|
|
*) echo "Unsupported governor: $gov" >&2; exit 1 ;;
|
|
esac
|
|
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
|
|
printf '%s\n' "$gov" > "$f"
|
|
done
|
|
}
|
|
|
|
cycle() {
|
|
case "$(cur)" in
|
|
schedutil) apply performance ;;
|
|
performance) apply schedutil ;;
|
|
*) apply schedutil ;;
|
|
esac
|
|
}
|
|
|
|
status() {
|
|
local gov
|
|
gov=$(cur)
|
|
case "$gov" in
|
|
performance) printf '{"text":" perf ","tooltip":"CPU governor: performance","class":"performance"}\n' ;;
|
|
schedutil) printf '{"text":" sched ","tooltip":"CPU governor: schedutil","class":"schedutil"}\n' ;;
|
|
*) printf '{"text":" ⚙ %s ","tooltip":"CPU governor: %s","class":"other"}\n' "$gov" "$gov" ;;
|
|
esac
|
|
}
|
|
|
|
case "''${1:-status}" in
|
|
status) status ;;
|
|
cycle) cycle ;;
|
|
set) apply "''${2:-}" ;;
|
|
*) echo "Usage: cpugov [status|cycle|set <gov>]" >&2; exit 1 ;;
|
|
esac
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
config = lib.mkIf config.custom.isLaptop {
|
|
environment.systemPackages = [ cpugov ];
|
|
|
|
# Writing scaling_governor requires root; allow wheel members to call
|
|
# the helper without a password so the waybar widget can toggle on click.
|
|
# Sudo matches command paths literally (no symlink canonicalization), so
|
|
# use the stable wrapper path instead of the per-build store path.
|
|
security.sudo.extraRules = [
|
|
{
|
|
groups = [ "wheel" ];
|
|
commands = [
|
|
{
|
|
command = "/run/current-system/sw/bin/cpugov";
|
|
options = [ "NOPASSWD" ];
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
}
|