Added a minimal control interface to allow manual fan control and implemented the interface for ATI GPUs.
1.1 --- a/GUI/MainForm.cs Wed Dec 08 19:23:13 2010 +0000
1.2 +++ b/GUI/MainForm.cs Thu Jan 20 21:31:54 2011 +0000
1.3 @@ -461,6 +461,34 @@
1.4 };
1.5 sensorContextMenu.MenuItems.Add(item);
1.6 }
1.7 + if (node.Sensor.Control != null) {
1.8 + IControl control = node.Sensor.Control;
1.9 + MenuItem controlItem = new MenuItem("Control");
1.10 + MenuItem defaultItem = new MenuItem("Default");
1.11 + defaultItem.Checked = control.ControlMode == ControlMode.Default;
1.12 + controlItem.MenuItems.Add(defaultItem);
1.13 + defaultItem.Click += delegate(object obj, EventArgs args) {
1.14 + control.SetDefault();
1.15 + };
1.16 + MenuItem manualItem = new MenuItem("Manual");
1.17 + controlItem.MenuItems.Add(manualItem);
1.18 + manualItem.Checked = control.ControlMode == ControlMode.Software;
1.19 + for (int i = 0; i <= 100; i += 5) {
1.20 + if (i <= control.MaxSoftwareValue &&
1.21 + i >= control.MinSoftwareValue)
1.22 + {
1.23 + MenuItem item = new MenuItem(i + " %");
1.24 + manualItem.MenuItems.Add(item);
1.25 + item.Checked = control.ControlMode == ControlMode.Software &&
1.26 + Math.Round(control.SoftwareValue) == i;
1.27 + int softwareValue = i;
1.28 + item.Click += delegate(object obj, EventArgs args) {
1.29 + control.SetSoftware(softwareValue);
1.30 + };
1.31 + }
1.32 + }
1.33 + sensorContextMenu.MenuItems.Add(controlItem);
1.34 + }
1.35
1.36 sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
1.37 }
2.1 --- a/Hardware/ATI/ADL.cs Wed Dec 08 19:23:13 2010 +0000
2.2 +++ b/Hardware/ATI/ADL.cs Thu Jan 20 21:31:54 2011 +0000
2.3 @@ -122,6 +122,7 @@
2.4 public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
2.5 public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
2.6 public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
2.7 + public const int ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED = 1;
2.8
2.9 public const int ATI_VENDOR_ID1 = 1002;
2.10 public const int ATI_VENDOR_ID2 = 0x1002;
2.11 @@ -149,6 +150,10 @@
2.12 public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
2.13 int adapterIndex, int thermalControllerIndex,
2.14 ref ADLFanSpeedInfo fanSpeedInfo);
2.15 + public delegate int ADL_Overdrive5_FanSpeedToDefault_SetDelegate(
2.16 + int adapterIndex, int thermalControllerIndex);
2.17 + public delegate int ADL_Overdrive5_FanSpeed_SetDelegate(int adapterIndex,
2.18 + int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue);
2.19
2.20 private static ADL_Main_Control_CreateDelegate
2.21 _ADL_Main_Control_Create;
2.22 @@ -173,6 +178,10 @@
2.23 ADL_Overdrive5_FanSpeed_Get;
2.24 public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
2.25 ADL_Overdrive5_FanSpeedInfo_Get;
2.26 + public static ADL_Overdrive5_FanSpeedToDefault_SetDelegate
2.27 + ADL_Overdrive5_FanSpeedToDefault_Set;
2.28 + public static ADL_Overdrive5_FanSpeed_SetDelegate
2.29 + ADL_Overdrive5_FanSpeed_Set;
2.30
2.31 private static string dllName;
2.32
2.33 @@ -215,6 +224,10 @@
2.34 out ADL_Overdrive5_FanSpeed_Get);
2.35 GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
2.36 out ADL_Overdrive5_FanSpeedInfo_Get);
2.37 + GetDelegate("ADL_Overdrive5_FanSpeedToDefault_Set",
2.38 + out ADL_Overdrive5_FanSpeedToDefault_Set);
2.39 + GetDelegate("ADL_Overdrive5_FanSpeed_Set",
2.40 + out ADL_Overdrive5_FanSpeed_Set);
2.41 }
2.42
2.43 static ADL() {
3.1 --- a/Hardware/ATI/ATIGPU.cs Wed Dec 08 19:23:13 2010 +0000
3.2 +++ b/Hardware/ATI/ATIGPU.cs Thu Jan 20 21:31:54 2011 +0000
3.3 @@ -51,7 +51,10 @@
3.4 private readonly Sensor memoryClock;
3.5 private readonly Sensor coreVoltage;
3.6 private readonly Sensor coreLoad;
3.7 - private readonly Sensor fanControl;
3.8 + private readonly Sensor controlSensor;
3.9 + private readonly Control fanControl;
3.10 +
3.11 + private ADLFanSpeedValue initialFanSpeedValue;
3.12
3.13 public ATIGPU(string name, int adapterIndex, int busNumber,
3.14 int deviceNumber, ISettings settings)
3.15 @@ -61,16 +64,61 @@
3.16 this.busNumber = busNumber;
3.17 this.deviceNumber = deviceNumber;
3.18
3.19 + this.initialFanSpeedValue = new ADLFanSpeedValue();
3.20 + this.initialFanSpeedValue.SpeedType =
3.21 + ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
3.22 + ADL.ADL_Overdrive5_FanSpeed_Get(adapterIndex, 0,
3.23 + ref this.initialFanSpeedValue);
3.24 +
3.25 this.temperature = new Sensor("GPU Core", 0, SensorType.Temperature, this, settings);
3.26 this.fan = new Sensor("GPU Fan", 0, SensorType.Fan, this, settings);
3.27 this.coreClock = new Sensor("GPU Core", 0, SensorType.Clock, this, settings);
3.28 this.memoryClock = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings);
3.29 this.coreVoltage = new Sensor("GPU Core", 0, SensorType.Voltage, this, settings);
3.30 this.coreLoad = new Sensor("GPU Core", 0, SensorType.Load, this, settings);
3.31 - this.fanControl = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
3.32 + this.controlSensor = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
3.33 +
3.34 + ADLFanSpeedInfo afsi = new ADLFanSpeedInfo();
3.35 + if (ADL.ADL_Overdrive5_FanSpeedInfo_Get(adapterIndex, 0, ref afsi)
3.36 + != ADL.ADL_OK)
3.37 + {
3.38 + afsi.MaxPercent = 100;
3.39 + afsi.MinPercent = 0;
3.40 + }
3.41 +
3.42 + this.fanControl = new Control(controlSensor, settings, afsi.MinPercent,
3.43 + afsi.MaxPercent);
3.44 + this.fanControl.ControlModeChanged += ControlModeChanged;
3.45 + this.fanControl.SoftwareControlValueChanged +=
3.46 + SoftwareControlValueChanged;
3.47 + ControlModeChanged(fanControl);
3.48 + this.controlSensor.Control = fanControl;
3.49 Update();
3.50 }
3.51
3.52 + private void SoftwareControlValueChanged(IControl control) {
3.53 + if (control.ControlMode == ControlMode.Software) {
3.54 + ADLFanSpeedValue adlf = new ADLFanSpeedValue();
3.55 + adlf.SpeedType = ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
3.56 + adlf.Flags = ADL.ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED;
3.57 + adlf.FanSpeed = (int)control.SoftwareValue;
3.58 + ADL.ADL_Overdrive5_FanSpeed_Set(adapterIndex, 0, ref adlf);
3.59 + }
3.60 + }
3.61 +
3.62 + private void ControlModeChanged(IControl control) {
3.63 + if (control.ControlMode == ControlMode.Default) {
3.64 + ADL.ADL_Overdrive5_FanSpeed_Set(adapterIndex, 0,
3.65 + ref this.initialFanSpeedValue);
3.66 + } else {
3.67 + ADLFanSpeedValue adlf = new ADLFanSpeedValue();
3.68 + adlf.SpeedType = ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
3.69 + adlf.Flags = ADL.ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED;
3.70 + adlf.FanSpeed = (int)control.SoftwareValue;
3.71 + ADL.ADL_Overdrive5_FanSpeed_Set(adapterIndex, 0, ref adlf);
3.72 + }
3.73 + }
3.74 +
3.75 public int BusNumber { get { return busNumber; } }
3.76
3.77 public int DeviceNumber { get { return deviceNumber; } }
3.78 @@ -116,10 +164,10 @@
3.79 adlf.SpeedType = ADL.ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
3.80 if (ADL.ADL_Overdrive5_FanSpeed_Get(adapterIndex, 0, ref adlf)
3.81 == ADL.ADL_OK) {
3.82 - fanControl.Value = adlf.FanSpeed;
3.83 - ActivateSensor(fanControl);
3.84 + controlSensor.Value = adlf.FanSpeed;
3.85 + ActivateSensor(controlSensor);
3.86 } else {
3.87 - fanControl.Value = null;
3.88 + controlSensor.Value = null;
3.89 }
3.90
3.91 ADLPMActivity adlp = new ADLPMActivity();
3.92 @@ -150,5 +198,14 @@
3.93 coreLoad.Value = null;
3.94 }
3.95 }
3.96 +
3.97 + public void Close() {
3.98 + this.fanControl.ControlModeChanged -= ControlModeChanged;
3.99 + this.fanControl.SoftwareControlValueChanged -=
3.100 + SoftwareControlValueChanged;
3.101 +
3.102 + ADL.ADL_Overdrive5_FanSpeed_Set(adapterIndex, 0,
3.103 + ref this.initialFanSpeedValue);
3.104 + }
3.105 }
3.106 }
4.1 --- a/Hardware/ATI/ATIGroup.cs Wed Dec 08 19:23:13 2010 +0000
4.2 +++ b/Hardware/ATI/ATIGroup.cs Thu Jan 20 21:31:54 2011 +0000
4.3 @@ -144,6 +144,8 @@
4.4
4.5 public void Close() {
4.6 try {
4.7 + foreach (ATIGPU gpu in hardware)
4.8 + gpu.Close();
4.9 ADL.ADL_Main_Control_Destroy();
4.10 } catch (Exception) { }
4.11 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/Hardware/Control.cs Thu Jan 20 21:31:54 2011 +0000
5.3 @@ -0,0 +1,143 @@
5.4 +/*
5.5 +
5.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
5.7 +
5.8 + The contents of this file are subject to the Mozilla Public License Version
5.9 + 1.1 (the "License"); you may not use this file except in compliance with
5.10 + the License. You may obtain a copy of the License at
5.11 +
5.12 + http://www.mozilla.org/MPL/
5.13 +
5.14 + Software distributed under the License is distributed on an "AS IS" basis,
5.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
5.16 + for the specific language governing rights and limitations under the License.
5.17 +
5.18 + The Original Code is the Open Hardware Monitor code.
5.19 +
5.20 + The Initial Developer of the Original Code is
5.21 + Michael Möller <m.moeller@gmx.ch>.
5.22 + Portions created by the Initial Developer are Copyright (C) 2010
5.23 + the Initial Developer. All Rights Reserved.
5.24 +
5.25 + Contributor(s):
5.26 +
5.27 + Alternatively, the contents of this file may be used under the terms of
5.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
5.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
5.30 + in which case the provisions of the GPL or the LGPL are applicable instead
5.31 + of those above. If you wish to allow use of your version of this file only
5.32 + under the terms of either the GPL or the LGPL, and not to allow others to
5.33 + use your version of this file under the terms of the MPL, indicate your
5.34 + decision by deleting the provisions above and replace them with the notice
5.35 + and other provisions required by the GPL or the LGPL. If you do not delete
5.36 + the provisions above, a recipient may use your version of this file under
5.37 + the terms of any one of the MPL, the GPL or the LGPL.
5.38 +
5.39 +*/
5.40 +
5.41 +using System;
5.42 +using System.Globalization;
5.43 +
5.44 +namespace OpenHardwareMonitor.Hardware {
5.45 +
5.46 + internal delegate void ControlEventHandler(Control control);
5.47 +
5.48 + internal class Control : IControl {
5.49 +
5.50 + private readonly Identifier identifier;
5.51 + private readonly ISettings settings;
5.52 + private ControlMode mode;
5.53 + private float softwareValue;
5.54 + private float minSoftwareValue;
5.55 + private float maxSoftwareValue;
5.56 +
5.57 + public Control(ISensor sensor, ISettings settings, float minSoftwareValue,
5.58 + float maxSoftwareValue)
5.59 + {
5.60 + this.identifier = new Identifier(sensor.Identifier, "control");
5.61 + this.settings = settings;
5.62 + this.minSoftwareValue = minSoftwareValue;
5.63 + this.maxSoftwareValue = maxSoftwareValue;
5.64 +
5.65 + if (!float.TryParse(settings.GetValue(
5.66 + new Identifier(identifier, "value").ToString(), "0"),
5.67 + NumberStyles.Float, CultureInfo.InvariantCulture,
5.68 + out this.softwareValue))
5.69 + {
5.70 + this.softwareValue = 0;
5.71 + }
5.72 + int mode;
5.73 + if (!int.TryParse(settings.GetValue(
5.74 + new Identifier(identifier, "mode").ToString(),
5.75 + ((int)ControlMode.Default).ToString(CultureInfo.InvariantCulture)),
5.76 + NumberStyles.Integer, CultureInfo.InvariantCulture,
5.77 + out mode))
5.78 + {
5.79 + this.mode = ControlMode.Default;
5.80 + } else {
5.81 + this.mode = (ControlMode)mode;
5.82 + }
5.83 + }
5.84 +
5.85 + public Identifier Identifier {
5.86 + get {
5.87 + return identifier;
5.88 + }
5.89 + }
5.90 +
5.91 + public ControlMode ControlMode {
5.92 + get {
5.93 + return mode;
5.94 + }
5.95 + private set {
5.96 + if (mode != value) {
5.97 + mode = value;
5.98 + if (ControlModeChanged != null)
5.99 + ControlModeChanged(this);
5.100 + this.settings.SetValue(new Identifier(identifier, "mode").ToString(),
5.101 + ((int)mode).ToString(CultureInfo.InvariantCulture));
5.102 + }
5.103 + }
5.104 + }
5.105 +
5.106 + public float SoftwareValue {
5.107 + get {
5.108 + return softwareValue;
5.109 + }
5.110 + private set {
5.111 + if (softwareValue != value) {
5.112 + softwareValue = value;
5.113 + if (SoftwareControlValueChanged != null)
5.114 + SoftwareControlValueChanged(this);
5.115 + this.settings.SetValue(new Identifier(identifier,
5.116 + "value").ToString(),
5.117 + value.ToString(CultureInfo.InvariantCulture));
5.118 + }
5.119 + }
5.120 + }
5.121 +
5.122 + public void SetDefault() {
5.123 + ControlMode = ControlMode.Default;
5.124 + }
5.125 +
5.126 + public float MinSoftwareValue {
5.127 + get {
5.128 + return minSoftwareValue;
5.129 + }
5.130 + }
5.131 +
5.132 + public float MaxSoftwareValue {
5.133 + get {
5.134 + return maxSoftwareValue;
5.135 + }
5.136 + }
5.137 +
5.138 + public void SetSoftware(float value) {
5.139 + ControlMode = ControlMode.Software;
5.140 + SoftwareValue = value;
5.141 + }
5.142 +
5.143 + internal event ControlEventHandler ControlModeChanged;
5.144 + internal event ControlEventHandler SoftwareControlValueChanged;
5.145 + }
5.146 +}
6.1 --- a/Hardware/Hardware.cs Wed Dec 08 19:23:13 2010 +0000
6.2 +++ b/Hardware/Hardware.cs Thu Jan 20 21:31:54 2011 +0000
6.3 @@ -55,13 +55,13 @@
6.4 get { return active.ToArray(); }
6.5 }
6.6
6.7 - protected void ActivateSensor(Sensor sensor) {
6.8 + protected void ActivateSensor(ISensor sensor) {
6.9 if (active.Add(sensor))
6.10 if (SensorAdded != null)
6.11 SensorAdded(sensor);
6.12 }
6.13
6.14 - protected void DeactivateSensor(Sensor sensor) {
6.15 + protected void DeactivateSensor(ISensor sensor) {
6.16 if (active.Remove(sensor))
6.17 if (SensorRemoved != null)
6.18 SensorRemoved(sensor);
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/Hardware/IControl.cs Thu Jan 20 21:31:54 2011 +0000
7.3 @@ -0,0 +1,61 @@
7.4 +/*
7.5 +
7.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
7.7 +
7.8 + The contents of this file are subject to the Mozilla Public License Version
7.9 + 1.1 (the "License"); you may not use this file except in compliance with
7.10 + the License. You may obtain a copy of the License at
7.11 +
7.12 + http://www.mozilla.org/MPL/
7.13 +
7.14 + Software distributed under the License is distributed on an "AS IS" basis,
7.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7.16 + for the specific language governing rights and limitations under the License.
7.17 +
7.18 + The Original Code is the Open Hardware Monitor code.
7.19 +
7.20 + The Initial Developer of the Original Code is
7.21 + Michael Möller <m.moeller@gmx.ch>.
7.22 + Portions created by the Initial Developer are Copyright (C) 2010
7.23 + the Initial Developer. All Rights Reserved.
7.24 +
7.25 + Contributor(s):
7.26 +
7.27 + Alternatively, the contents of this file may be used under the terms of
7.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
7.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
7.30 + in which case the provisions of the GPL or the LGPL are applicable instead
7.31 + of those above. If you wish to allow use of your version of this file only
7.32 + under the terms of either the GPL or the LGPL, and not to allow others to
7.33 + use your version of this file under the terms of the MPL, indicate your
7.34 + decision by deleting the provisions above and replace them with the notice
7.35 + and other provisions required by the GPL or the LGPL. If you do not delete
7.36 + the provisions above, a recipient may use your version of this file under
7.37 + the terms of any one of the MPL, the GPL or the LGPL.
7.38 +
7.39 +*/
7.40 +
7.41 +namespace OpenHardwareMonitor.Hardware {
7.42 +
7.43 + public enum ControlMode {
7.44 + Default,
7.45 + Software
7.46 + }
7.47 +
7.48 + public interface IControl {
7.49 +
7.50 + Identifier Identifier { get; }
7.51 +
7.52 + ControlMode ControlMode { get; }
7.53 +
7.54 + float SoftwareValue { get; }
7.55 +
7.56 + void SetDefault();
7.57 +
7.58 + float MinSoftwareValue { get; }
7.59 + float MaxSoftwareValue { get; }
7.60 +
7.61 + void SetSoftware(float value);
7.62 +
7.63 + }
7.64 +}
8.1 --- a/Hardware/ISensor.cs Wed Dec 08 19:23:13 2010 +0000
8.2 +++ b/Hardware/ISensor.cs Thu Jan 20 21:31:54 2011 +0000
8.3 @@ -87,6 +87,8 @@
8.4 void ResetMax();
8.5
8.6 IEnumerable<SensorValue> Values { get; }
8.7 +
8.8 + IControl Control { get; }
8.9 }
8.10
8.11 }
9.1 --- a/Hardware/LPC/IT87XX.cs Wed Dec 08 19:23:13 2010 +0000
9.2 +++ b/Hardware/LPC/IT87XX.cs Thu Jan 20 21:31:54 2011 +0000
9.3 @@ -82,6 +82,12 @@
9.4 return value;
9.5 }
9.6
9.7 + private bool WriteByte(byte register, byte value) {
9.8 + Ring0.WriteIoPort(addressReg, register);
9.9 + Ring0.WriteIoPort(dataReg, value);
9.10 + return register == Ring0.ReadIoPort(addressReg);
9.11 + }
9.12 +
9.13 public byte? ReadGPIO(int index) {
9.14 if (index >= gpioCount)
9.15 return null;
10.1 --- a/Hardware/Sensor.cs Wed Dec 08 19:23:13 2010 +0000
10.2 +++ b/Hardware/Sensor.cs Thu Jan 20 21:31:54 2011 +0000
10.3 @@ -57,6 +57,7 @@
10.4 private readonly Queue<SensorValue> values =
10.5 new Queue<SensorValue>(MAX_MINUTES * 15);
10.6 private readonly ISettings settings;
10.7 + private IControl control;
10.8
10.9 private float sum;
10.10 private int count;
10.11 @@ -186,5 +187,14 @@
10.12 foreach (IParameter parameter in parameters)
10.13 parameter.Accept(visitor);
10.14 }
10.15 +
10.16 + public IControl Control {
10.17 + get {
10.18 + return control;
10.19 + }
10.20 + internal set {
10.21 + this.control = value;
10.22 + }
10.23 + }
10.24 }
10.25 }
11.1 --- a/OpenHardwareMonitorLib.csproj Wed Dec 08 19:23:13 2010 +0000
11.2 +++ b/OpenHardwareMonitorLib.csproj Thu Jan 20 21:31:54 2011 +0000
11.3 @@ -59,6 +59,8 @@
11.4 <Compile Include="Hardware\ATI\ADL.cs" />
11.5 <Compile Include="Hardware\ATI\ATIGPU.cs" />
11.6 <Compile Include="Hardware\ATI\ATIGroup.cs" />
11.7 + <Compile Include="Hardware\Control.cs" />
11.8 + <Compile Include="Hardware\IControl.cs" />
11.9 <Compile Include="Hardware\IOControlCode.cs" />
11.10 <Compile Include="Hardware\Computer.cs" />
11.11 <Compile Include="Hardware\CPU\AMDCPU.cs" />