#!/bin/bash
#
# MNT Reform Power Daemon
#
# A prototype daemon for managing power consumption on MNT Pocket Reform, with the goals of:
#
# - avoiding SoC resets due to current spikes causing voltage dips on 5V rail, on low battery voltage
# - prolonging runtime on battery
#

set -e

if ! grep "MNT Pocket Reform with RCORE RK3588 Module" /proc/device-tree/model; then
	echo "Fatal: reform-power-daemon currently supports only MNT Pocket Reform with RCORE RK3588 Module." >&2
	exit 2
fi

if ! lsmod | grep reform2_lpc; then
	echo "Fatal: reform2_lpc module not loaded. Please reinstall reform2-lpc-dkms and reboot." >&2
	exit 2
fi

min_sys_ver=20251030
min_kbd_ver=20251118
sys_ver="$(reform-mcu-tool list --json | jq 'map(select(.device.name == "pocket-sysctl-1.0")) | .[] | .version')"
kbd_ver="$(reform-mcu-tool list --json | jq 'map(select(.device.name == "pocket-input-1.0")) | .[] | .version')"

echo "System Controller firmware version: $sys_ver"
echo "Keyboard firmware version: $kbd_ver"

if (( $sys_ver < $min_sys_ver )); then
	echo "Warning: Please upgrade your System Controller firmware using gnome-firmware (at least version $min_sys_ver required)." >&2
fi

if (( $kbd_ver < $min_kbd_ver )); then
	echo "Warning: Please upgrade your Keyboard firmware using gnome-firmware (at least version $min_kbd_ver required)." >&2
fi

bat_path="/sys/class/power_supply/BAT0"
gpu_path="/sys/devices/platform/fb000000.gpu/devfreq/fb000000.gpu"
cpu_path="/sys/devices/system/cpu/cpufreq"
min_gpu_freq="300000000"
prev_status=""

# Policy when powered by batteries
bat_display_backlight_level="40%"
bat_max_gpu_freq="300000000"
bat_cpu_governor="powersave"
bat_keyboard_backlight='xLBRT\x05'

# Policy when powered by AC adapter
ac_display_backlight_level="70%"
ac_max_gpu_freq="1000000000"
ac_cpu_governor="schedutil" # TODO could also be: "performance", especially on Classic Reform
ac_keyboard_backlight='xLBRT\x30'

while sleep 1; do
	bat_status=$(cat $bat_path/status)

	if [ "$bat_status" = "$prev_status" ]; then
		continue
	fi

	echo "Battery status changed to $bat_status."

	# on AC power?
	if [ "$bat_status" == "Charging" ]; then
		echo "Charging"
		echo "simple_ondemand" > "$gpu_path/governor"
		echo "$min_gpu_freq" > "$gpu_path/min_freq"
		echo "$ac_max_gpu_freq" > "$gpu_path/max_freq"
		# FIXME this triggers a bug in the panel driver when panel v1 is turned off (i.e. on HDMI)
		# that makes everything crash/freeze, so commented out for now
		#brightnessctl set "$ac_display_backlight_level"

		# apply keyboard brightness. requires firmware 20251118+
		for hidraw in /dev/input/by-id/usb-MNT_Pocket_Reform_Input_*hidraw; do
			printf "$ac_keyboard_backlight" > "$hidraw"
		done

		for i in 0 4 6; do
			echo "$ac_cpu_governor" > "$cpu_path/policy$i/scaling_governor"
		done
	fi

	# on battery power?
	if [ "$bat_status" == "Discharging" ]; then
		echo "Discharging"
		echo "userspace" > "$gpu_path/governor"
		echo "$min_gpu_freq" > "$gpu_path/min_freq"
		echo "$bat_max_gpu_freq" > "$gpu_path/max_freq"
		# FIXME this triggers a bug in the panel driver when panel v1 is turned off (i.e. on HDMI)
		# that makes everything crash/freeze, so commented out for now
		#brightnessctl set "$bat_display_backlight_level"

		# apply keyboard brightness. requires firmware 20251118+
		for hidraw in /dev/input/by-id/usb-MNT_Pocket_Reform_Input_*hidraw; do
			printf "$bat_keyboard_backlight" > "$hidraw"
		done

		for i in 0 4 6; do
			echo "powersave" > "$cpu_path/policy$i/scaling_governor"
		done
	fi

	prev_status="$bat_status"
done
