diff --git a/CommonHelpers/Vlv0100.cs b/CommonHelpers/Vlv0100.cs index 7b6798e..f39eee7 100644 --- a/CommonHelpers/Vlv0100.cs +++ b/CommonHelpers/Vlv0100.cs @@ -15,6 +15,7 @@ public class Vlv0100 : IDisposable static IntPtr PDFV = new IntPtr(0xFE700C00 + 0x4C); static IntPtr XBID = new IntPtr(0xFE700300 + 0xBD); static IntPtr PDCT = new IntPtr(0xFE700C00 + 0x01); + static IntPtr MCBL = new IntPtr(0xFE700B00 + 0x9F); static ushort IO6C = 0x6C; public const ushort MAX_FAN_RPM = 0x1C84; @@ -26,6 +27,7 @@ public struct DeviceVersion public byte PDCS { get; set; } public bool BatteryTempLE { get; set; } + public bool MaxBatteryCharge { get; set; } public bool IsSupported(ushort deviceFirmware, byte deviceBoardID, byte devicePDCS) { @@ -42,11 +44,11 @@ public bool IsSupported(ushort deviceFirmware, byte deviceBoardID, byte devicePD private static readonly DeviceVersion[] deviceVersions = { // Steam Deck - LCD version new DeviceVersion() { Firmware = 0xB030, BoardID = 0x6, PDCS = 0 /* 0x2B */, BatteryTempLE = false }, - new DeviceVersion() { Firmware = 0xB030, BoardID = 0xA, PDCS = 0 /* 0x2B */, BatteryTempLE = false }, + new DeviceVersion() { Firmware = 0xB030, BoardID = 0xA, PDCS = 0 /* 0x2B */, BatteryTempLE = false, MaxBatteryCharge = true }, // Steam Deck - OLED version // new DeviceVersion() { Firmware = 0x1030, BoardID = 0x5, PDCS = 0 /* 0x2F */, BatteryTempLE = true }, - new DeviceVersion() { Firmware = 0x1050, BoardID = 0x5, PDCS = 0 /* 0x2F */, BatteryTempLE = true } + new DeviceVersion() { Firmware = 0x1050, BoardID = 0x5, PDCS = 0 /* 0x2F */, BatteryTempLE = true, MaxBatteryCharge = true } }; public static Vlv0100 Instance = new Vlv0100(); @@ -178,6 +180,27 @@ public float GetBattTemperature() return (float)(value - 0x0AAC) / 10.0f; } + public int? GetMaxBatteryCharge() + { + if (SupportedDevice?.MaxBatteryCharge != true) + return null; + var data = inpOut?.ReadMemory(MCBL, 1); + if (data is null) + return null; + if (data[0] > 100) + return null; + return data[0]; + } + public void SetMaxBatteryCharge(int chargeLimit) + { + if (SupportedDevice?.MaxBatteryCharge != true) + return; + if (chargeLimit < 0 || chargeLimit > 100) + return; + byte[] data = BitConverter.GetBytes(chargeLimit); + inpOut?.WriteMemory(MCBL, data); + } + private void SetGain(ushort gain) { byte[] data = BitConverter.GetBytes(gain); diff --git a/PowerControl/MenuStack.cs b/PowerControl/MenuStack.cs index abf30bc..c8c0639 100644 --- a/PowerControl/MenuStack.cs +++ b/PowerControl/MenuStack.cs @@ -36,7 +36,8 @@ internal class MenuStack Options.PerformanceOverlay.ModeInstance, Options.PerformanceOverlay.KernelDriversInstance, Options.FanControl.Instance, - Options.SteamController.Instance + Options.SteamController.Instance, + Options.BatteryChargeLimit.Instance } }; diff --git a/PowerControl/Options/BatteryChargeLimit.cs b/PowerControl/Options/BatteryChargeLimit.cs new file mode 100644 index 0000000..b949b66 --- /dev/null +++ b/PowerControl/Options/BatteryChargeLimit.cs @@ -0,0 +1,32 @@ +using CommonHelpers; + +namespace PowerControl.Options +{ + public static class BatteryChargeLimit + { + public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions() + { + Name = "Charge Limit", + ApplyDelay = 1000, + Options = { "70%", "80%", "90%", "100%" }, + ActiveOption = "?", + ApplyValue = (selected) => + { + var value = int.Parse(selected.ToString().TrimEnd('%')); + + using (var vlv0100 = new Vlv0100()) + { + if (!vlv0100.Open()) + return null; + + vlv0100.SetMaxBatteryCharge(value); + + var newValue = vlv0100.GetMaxBatteryCharge(); + if (newValue is null) + return null; + return newValue.ToString() + "%"; + } + } + }; + } +} diff --git a/RELEASE.md b/RELEASE.md index 0e7ad06..098b2e9 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,6 +6,8 @@ ## #{GIT_TAG_NAME} +- PowerControl: Add Charge Limit (70%, 80%, 90%, 100%) + ## 0.7.1 - SteamDeck OLED: Support BIOS 107 with temperature readings