#!/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 -q "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 --raw-output 'map(select(.device.name == "pocket-sysctl-1.0")) | .[] | .version')"
kbd_ver="$(reform-mcu-tool list --json | jq --raw-output '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
      [ -e "$hidraw" ] || continue
      printf "%b" "$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
      [ -e "$hidraw" ] || continue
      printf "%b" "$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
