mirror of
https://github.com/ayufan/steam-deck-tools.git
synced 2026-03-15 09:24:12 +01:00
Add initial FanControl
This commit is contained in:
parent
0cbff4171b
commit
573a8e2f4a
22
FanControl/FanControl.csproj
Normal file
22
FanControl/FanControl.csproj
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<StartupObject>FanControl.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="inpoutx64.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
55
FanControl/InpOut.cs
Normal file
55
FanControl/InpOut.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FanControl
|
||||
{
|
||||
internal class InpOut
|
||||
{
|
||||
[DllImport("inpoutx64.dll", EntryPoint = "MapPhysToLin", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern IntPtr MapPhysToLin(IntPtr pbPhysAddr, uint dwPhysSize, out IntPtr pPhysicalMemoryHandle);
|
||||
|
||||
[DllImport("inpoutx64.dll", EntryPoint = "UnmapPhysicalMemory", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, IntPtr pbLinAddr);
|
||||
|
||||
[DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUchar", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static extern byte DlPortReadPortUchar(ushort port);
|
||||
|
||||
[DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUchar", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern byte DlPortWritePortUchar(ushort port, byte vlaue);
|
||||
|
||||
public static byte[] ReadMemory(IntPtr baseAddress, uint size)
|
||||
{
|
||||
IntPtr pdwLinAddr = MapPhysToLin(baseAddress, size, out IntPtr pPhysicalMemoryHandle);
|
||||
if (pdwLinAddr != IntPtr.Zero)
|
||||
{
|
||||
byte[] bytes = new byte[size];
|
||||
Marshal.Copy(pdwLinAddr, bytes, 0, bytes.Length);
|
||||
UnmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool WriteMemory(IntPtr baseAddress, byte[] data)
|
||||
{
|
||||
IntPtr pdwLinAddr = MapPhysToLin(baseAddress, (uint)data.Length, out IntPtr pPhysicalMemoryHandle);
|
||||
if (pdwLinAddr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Copy(data, 0, pdwLinAddr, data.Length);
|
||||
UnmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
FanControl/Program.cs
Normal file
82
FanControl/Program.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LibreHardwareMonitor.Hardware;
|
||||
|
||||
namespace FanControl
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
public class UpdateVisitor : IVisitor
|
||||
{
|
||||
public void VisitComputer(IComputer computer)
|
||||
{
|
||||
computer.Traverse(this);
|
||||
}
|
||||
public void VisitHardware(IHardware hardware)
|
||||
{
|
||||
hardware.Update();
|
||||
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
|
||||
}
|
||||
public void VisitSensor(ISensor sensor) { }
|
||||
public void VisitParameter(IParameter parameter) { }
|
||||
}
|
||||
|
||||
public static void Monitor()
|
||||
{
|
||||
Computer computer = new Computer
|
||||
{
|
||||
IsCpuEnabled = true,
|
||||
IsGpuEnabled = true,
|
||||
IsMemoryEnabled = true,
|
||||
IsMotherboardEnabled = true,
|
||||
IsControllerEnabled = true,
|
||||
IsNetworkEnabled = true,
|
||||
IsStorageEnabled = true
|
||||
};
|
||||
|
||||
computer.Open();
|
||||
computer.Accept(new UpdateVisitor());
|
||||
|
||||
foreach (IHardware hardware in computer.Hardware)
|
||||
{
|
||||
Console.WriteLine("Hardware: {0}", hardware.Name);
|
||||
|
||||
foreach (IHardware subhardware in hardware.SubHardware)
|
||||
{
|
||||
Console.WriteLine("\tSubhardware: {0}", subhardware.Name);
|
||||
|
||||
foreach (ISensor sensor in subhardware.Sensors)
|
||||
{
|
||||
Console.WriteLine("\t\tSensor: {0}, value: {1}", sensor.Name, sensor.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ISensor sensor in hardware.Sensors)
|
||||
{
|
||||
Console.WriteLine("\tSensor: {0}, value: {1}", sensor.Name, sensor.Value);
|
||||
}
|
||||
}
|
||||
|
||||
computer.Close();
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Monitor();
|
||||
|
||||
while (true)
|
||||
{
|
||||
Thread.Sleep(300);
|
||||
|
||||
Vlv0100.SetFanControl(false);
|
||||
Vlv0100.SetFanDesiredRPM(6000);
|
||||
|
||||
Console.WriteLine("Fan RPM: {0}", Vlv0100.GetFanRPM());
|
||||
Console.WriteLine("Fan Desired RPM: {0}", Vlv0100.GetFanDesiredRPM());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
FanControl/Vlv0100.cs
Normal file
66
FanControl/Vlv0100.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FanControl
|
||||
{
|
||||
internal class Vlv0100
|
||||
{
|
||||
// Those addresses are taken from DSDT for VLV0100
|
||||
// and might change at any time with a BIOS update
|
||||
static IntPtr FSLO_FSHI = new IntPtr(0xFE700B00 + 0x92);
|
||||
static IntPtr GNLO_GNHI = new IntPtr(0xFE700B00 + 0x95);
|
||||
static IntPtr FRPR = new IntPtr(0xFE700B00 + 0x97);
|
||||
static IntPtr FNRL_FNRH = new IntPtr(0xFE700300 + 0xB0);
|
||||
static IntPtr FNCK = new IntPtr(0xFE700300 + 0x9F);
|
||||
static ushort IO6C = 0x6C;
|
||||
|
||||
public static ushort GetFanDesiredRPM()
|
||||
{
|
||||
byte[] data = InpOut.ReadMemory(FSLO_FSHI, 2);
|
||||
return BitConverter.ToUInt16(data);
|
||||
}
|
||||
|
||||
public static ushort GetFanRPM()
|
||||
{
|
||||
byte[] data = InpOut.ReadMemory(FNRL_FNRH, 2);
|
||||
return BitConverter.ToUInt16(data);
|
||||
}
|
||||
public static void SetFanControl(Boolean userControlled)
|
||||
{
|
||||
SetGain(10);
|
||||
SetRampRate(userControlled ? (byte)10 : (byte)20);
|
||||
|
||||
InpOut.DlPortWritePortUchar(IO6C, userControlled ? (byte)0xCC : (byte)0xCD);
|
||||
}
|
||||
|
||||
public static void SetFanDesiredRPM(ushort rpm)
|
||||
{
|
||||
if (rpm > 0x1C84)
|
||||
rpm = 0x1C84;
|
||||
|
||||
byte[] data = BitConverter.GetBytes(rpm);
|
||||
InpOut.WriteMemory(FSLO_FSHI, data);
|
||||
}
|
||||
|
||||
public static bool GetFanCheck()
|
||||
{
|
||||
byte[] data = InpOut.ReadMemory(FNCK, 1);
|
||||
return (data[0] & 0x1) != 0;
|
||||
}
|
||||
|
||||
private static void SetGain(ushort gain)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(gain);
|
||||
InpOut.WriteMemory(GNLO_GNHI, data);
|
||||
}
|
||||
private static void SetRampRate(byte rampRate)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(rampRate);
|
||||
InpOut.WriteMemory(FRPR, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
FanControl/inpoutx64.dll
Normal file
BIN
FanControl/inpoutx64.dll
Normal file
Binary file not shown.
25
SteamDeckTools.sln
Normal file
25
SteamDeckTools.sln
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32901.215
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FanControl", "FanControl\FanControl.csproj", "{A0D9B170-89BA-4F7A-9331-BE6A721E8D5B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A0D9B170-89BA-4F7A-9331-BE6A721E8D5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A0D9B170-89BA-4F7A-9331-BE6A721E8D5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A0D9B170-89BA-4F7A-9331-BE6A721E8D5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A0D9B170-89BA-4F7A-9331-BE6A721E8D5B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FCAAD784-C54A-40A3-AE4A-ED9DD2299E6E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Loading…
Reference in a new issue