mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-08-28 21:07:47 +00:00
Added first experimental support for fan control on the NCT677X super I/O chips.
This commit is contained in:
parent
454962a72e
commit
14f60c38e3
@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael Möller <m.moeller@gmx.ch>.
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2011
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
@ -47,6 +47,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
private readonly float?[] voltages;
|
||||
private readonly float?[] temperatures;
|
||||
private readonly float?[] fans;
|
||||
private readonly float?[] controls;
|
||||
|
||||
// Hardware Monitor
|
||||
private const byte ADDRESS_REGISTER_OFFSET = 0x05;
|
||||
@ -71,6 +72,8 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
|
||||
public void WriteGPIO(int index, byte value) { }
|
||||
|
||||
public void SetControl(int index, byte? value) { }
|
||||
|
||||
public F718XX(Chip chip, ushort address) {
|
||||
this.address = address;
|
||||
this.chip = chip;
|
||||
@ -78,12 +81,14 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
voltages = new float?[chip == Chip.F71858 ? 3 : 9];
|
||||
temperatures = new float?[3];
|
||||
fans = new float?[chip == Chip.F71882 || chip == Chip.F71858? 4 : 3];
|
||||
controls = new float?[0];
|
||||
}
|
||||
|
||||
public Chip Chip { get { return chip; } }
|
||||
public float?[] Voltages { get { return voltages; } }
|
||||
public float?[] Temperatures { get { return temperatures; } }
|
||||
public float?[] Fans { get { return fans; } }
|
||||
public float?[] Controls { get { return controls; } }
|
||||
|
||||
public string GetReport() {
|
||||
StringBuilder r = new StringBuilder();
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael Möller <m.moeller@gmx.ch>.
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2011
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
@ -40,14 +40,21 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
|
||||
Chip Chip { get; }
|
||||
|
||||
// get voltage, temperature, fan and control channel values
|
||||
float?[] Voltages { get; }
|
||||
float?[] Temperatures { get; }
|
||||
float?[] Fans { get; }
|
||||
float?[] Controls { get; }
|
||||
|
||||
// set control value, null = auto
|
||||
void SetControl(int index, byte? value);
|
||||
|
||||
// read and write GPIO
|
||||
byte? ReadGPIO(int index);
|
||||
void WriteGPIO(int index, byte value);
|
||||
|
||||
string GetReport();
|
||||
|
||||
void Update();
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
private readonly float?[] voltages = new float?[0];
|
||||
private readonly float?[] temperatures = new float?[0];
|
||||
private readonly float?[] fans = new float?[0];
|
||||
private readonly float?[] controls = new float?[0];
|
||||
|
||||
private readonly float voltageGain;
|
||||
private readonly bool has16bitFanCounter;
|
||||
@ -103,6 +104,8 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
Ring0.WriteIoPort((ushort)(gpioAddress + index), value);
|
||||
}
|
||||
|
||||
public void SetControl(int index, byte? value) { }
|
||||
|
||||
public IT87XX(Chip chip, ushort address, ushort gpioAddress, byte version) {
|
||||
|
||||
this.address = address;
|
||||
@ -166,6 +169,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
public float?[] Voltages { get { return voltages; } }
|
||||
public float?[] Temperatures { get { return temperatures; } }
|
||||
public float?[] Fans { get { return fans; } }
|
||||
public float?[] Controls { get { return controls; } }
|
||||
|
||||
public string GetReport() {
|
||||
StringBuilder r = new StringBuilder();
|
||||
|
@ -116,6 +116,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
private readonly float?[] voltages;
|
||||
private readonly float?[] temperatures;
|
||||
private readonly float?[] fans;
|
||||
private readonly float?[] controls;
|
||||
|
||||
private readonly FileStream[] voltageStreams;
|
||||
private readonly FileStream[] temperatureStreams;
|
||||
@ -125,7 +126,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
public float?[] Voltages { get { return voltages; } }
|
||||
public float?[] Temperatures { get { return temperatures; } }
|
||||
public float?[] Fans { get { return fans; } }
|
||||
|
||||
public float?[] Controls { get { return controls; } }
|
||||
|
||||
public LMChip(Chip chip, string path) {
|
||||
this.path = path;
|
||||
@ -151,6 +152,8 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
for (int i = 0; i < fanPaths.Length; i++)
|
||||
fanStreams[i] = new FileStream(fanPaths[i],
|
||||
FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
this.controls = new float?[0];
|
||||
}
|
||||
|
||||
public byte? ReadGPIO(int index) {
|
||||
@ -163,6 +166,8 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetControl(int index, byte? value) { }
|
||||
|
||||
private string ReadFirstLine(Stream stream) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
|
@ -49,6 +49,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
private readonly float?[] voltages = new float?[9];
|
||||
private readonly float?[] temperatures = new float?[4];
|
||||
private readonly float?[] fans = new float?[0];
|
||||
private readonly float?[] controls = new float?[3];
|
||||
|
||||
// Hardware Monitor
|
||||
private const uint ADDRESS_REGISTER_OFFSET = 0x05;
|
||||
@ -62,6 +63,15 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, bank);
|
||||
Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, register);
|
||||
return Ring0.ReadIoPort(port + DATA_REGISTER_OFFSET);
|
||||
}
|
||||
|
||||
private void WriteByte(ushort address, byte value) {
|
||||
byte bank = (byte)(address >> 8);
|
||||
byte register = (byte)(address & 0xFF);
|
||||
Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, BANK_SELECT_REGISTER);
|
||||
Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, bank);
|
||||
Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, register);
|
||||
Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, value);
|
||||
}
|
||||
|
||||
// Consts
|
||||
@ -84,9 +94,19 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
{ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551 };
|
||||
private readonly ushort[] FAN_RPM_REG =
|
||||
{ 0x656, 0x658, 0x65A, 0x65C, 0x65E};
|
||||
private readonly ushort[] FAN_PWM_OUT_REG =
|
||||
{ 0x001, 0x003, 0x011 };
|
||||
private readonly ushort[] FAN_PWM_COMMAND_REG =
|
||||
{ 0x109, 0x209, 0x309 };
|
||||
private readonly ushort[] FAN_CONTROL_MODE_REG =
|
||||
{ 0x102, 0x202, 0x302 };
|
||||
|
||||
private readonly int minFanRPM;
|
||||
|
||||
private bool[] restoreDefaultFanControlRequired = { false, false, false };
|
||||
private byte[] initialFanControlMode = new byte[3];
|
||||
private byte[] initialFanPwmCommand = new byte[3];
|
||||
|
||||
private enum SourceNCT6771F : byte {
|
||||
SYSTIN = 1,
|
||||
CPUTIN = 2,
|
||||
@ -168,10 +188,47 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
|
||||
public void WriteGPIO(int index, byte value) { }
|
||||
|
||||
|
||||
private void SaveDefaultFanControl(int index) {
|
||||
if (!restoreDefaultFanControlRequired[index]) {
|
||||
initialFanControlMode[index] = ReadByte(FAN_CONTROL_MODE_REG[index]);
|
||||
initialFanPwmCommand[index] = ReadByte(FAN_PWM_COMMAND_REG[index]);
|
||||
restoreDefaultFanControlRequired[index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreDefaultFanControl(int index) {
|
||||
if (restoreDefaultFanControlRequired[index]) {
|
||||
WriteByte(FAN_CONTROL_MODE_REG[index], initialFanControlMode[index]);
|
||||
WriteByte(FAN_PWM_COMMAND_REG[index], initialFanPwmCommand[index]);
|
||||
restoreDefaultFanControlRequired[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetControl(int index, byte? value) {
|
||||
if (!Ring0.WaitIsaBusMutex(10))
|
||||
return;
|
||||
|
||||
if (value.HasValue) {
|
||||
SaveDefaultFanControl(index);
|
||||
|
||||
// set manual mode
|
||||
WriteByte(FAN_CONTROL_MODE_REG[index], 0);
|
||||
|
||||
// set output value
|
||||
WriteByte(FAN_PWM_COMMAND_REG[index], value.Value);
|
||||
} else {
|
||||
RestoreDefaultFanControl(index);
|
||||
}
|
||||
|
||||
Ring0.ReleaseIsaBusMutex();
|
||||
}
|
||||
|
||||
public Chip Chip { get { return chip; } }
|
||||
public float?[] Voltages { get { return voltages; } }
|
||||
public float?[] Temperatures { get { return temperatures; } }
|
||||
public float?[] Fans { get { return fans; } }
|
||||
public float?[] Controls { get { return controls; } }
|
||||
|
||||
public void Update() {
|
||||
if (!Ring0.WaitIsaBusMutex(10))
|
||||
@ -228,6 +285,11 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
fans[i] = value > minFanRPM ? value : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < controls.Length; i++) {
|
||||
int value = ReadByte(FAN_PWM_OUT_REG[i]);
|
||||
controls[i] = value / 2.55f;
|
||||
}
|
||||
|
||||
Ring0.ReleaseIsaBusMutex();
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael Möller <m.moeller@gmx.ch>.
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2011
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
@ -50,6 +50,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
private readonly float?[] voltages = new float?[0];
|
||||
private readonly float?[] temperatures = new float?[0];
|
||||
private readonly float?[] fans = new float?[0];
|
||||
private readonly float?[] controls = new float?[0];
|
||||
|
||||
private readonly bool[] peciTemperature = new bool[0];
|
||||
private readonly byte[] voltageRegister = new byte[0];
|
||||
@ -110,7 +111,9 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
}
|
||||
|
||||
public void WriteGPIO(int index, byte value) { }
|
||||
|
||||
|
||||
public void SetControl(int index, byte? value) { }
|
||||
|
||||
public W836XX(Chip chip, byte revision, ushort address) {
|
||||
this.address = address;
|
||||
this.revision = revision;
|
||||
@ -201,6 +204,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
public float?[] Voltages { get { return voltages; } }
|
||||
public float?[] Temperatures { get { return temperatures; } }
|
||||
public float?[] Fans { get { return fans; } }
|
||||
public float?[] Controls { get { return controls; } }
|
||||
|
||||
public void Update() {
|
||||
if (!Ring0.WaitIsaBusMutex(10))
|
||||
|
@ -50,6 +50,7 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
private readonly List<Sensor> voltages = new List<Sensor>();
|
||||
private readonly List<Sensor> temperatures = new List<Sensor>();
|
||||
private readonly List<Sensor> fans = new List<Sensor>();
|
||||
private readonly List<Sensor> controls = new List<Sensor>();
|
||||
|
||||
private delegate float? ReadValueDelegate(int index);
|
||||
private delegate void UpdateDelegate();
|
||||
@ -58,6 +59,7 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
private readonly ReadValueDelegate readVoltage;
|
||||
private readonly ReadValueDelegate readTemperature;
|
||||
private readonly ReadValueDelegate readFan;
|
||||
private readonly ReadValueDelegate readControl;
|
||||
|
||||
// delegate for post update mainboard specific code
|
||||
private readonly UpdateDelegate postUpdate;
|
||||
@ -77,12 +79,14 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
this.readVoltage = (index) => superIO.Voltages[index];
|
||||
this.readTemperature = (index) => superIO.Temperatures[index];
|
||||
this.readFan = (index) => superIO.Fans[index];
|
||||
this.readControl = (index) => superIO.Controls[index];
|
||||
|
||||
this.postUpdate = () => { };
|
||||
|
||||
List<Voltage> v = new List<Voltage>();
|
||||
List<Temperature> t = new List<Temperature>();
|
||||
List<Fan> f = new List<Fan>();
|
||||
List<Ctrl> c = new List<Ctrl>();
|
||||
|
||||
switch (superIO.Chip) {
|
||||
case Chip.IT8712F:
|
||||
@ -870,6 +874,9 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
f.Add(new Fan("CPU Fan", 1));
|
||||
f.Add(new Fan("Power Fan", 2));
|
||||
f.Add(new Fan("Chassis Fan #2", 3));
|
||||
c.Add(new Ctrl("Chassis Fan #2", 0));
|
||||
c.Add(new Ctrl("CPU Fan", 1));
|
||||
c.Add(new Ctrl("Chassis Fan #1", 2));
|
||||
break;
|
||||
case Model.P8P67_M_PRO: // NCT6776F
|
||||
v.Add(new Voltage("CPU VCore", 0));
|
||||
@ -934,6 +941,8 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
t.Add(new Temperature("Temperature #" + (i + 1), i));
|
||||
for (int i = 0; i < superIO.Fans.Length; i++)
|
||||
f.Add(new Fan("Fan #" + (i + 1), i));
|
||||
for (int i = 0; i < superIO.Controls.Length; i++)
|
||||
c.Add(new Ctrl("Fan Control #" + (i + 1), i));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -967,6 +976,30 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
this, settings);
|
||||
fans.Add(sensor);
|
||||
}
|
||||
|
||||
foreach (Ctrl ctrl in c) {
|
||||
int index = ctrl.Index;
|
||||
if (index < superIO.Controls.Length) {
|
||||
Sensor sensor = new Sensor(ctrl.Name, index, SensorType.Control,
|
||||
this, settings);
|
||||
Control control = new Control(sensor, settings, 0, 100);
|
||||
control.ControlModeChanged += (cc) => {
|
||||
if (cc.ControlMode == ControlMode.Default) {
|
||||
superIO.SetControl(index, null);
|
||||
} else {
|
||||
superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
|
||||
}
|
||||
};
|
||||
control.SoftwareControlValueChanged += (cc) => {
|
||||
if (cc.ControlMode == ControlMode.Software)
|
||||
superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
|
||||
};
|
||||
if (control.ControlMode == ControlMode.Software)
|
||||
superIO.SetControl(index, (byte)(control.SoftwareValue * 2.55));
|
||||
sensor.Control = control;
|
||||
controls.Add(sensor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override HardwareType HardwareType {
|
||||
@ -1011,9 +1044,25 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Sensor sensor in controls) {
|
||||
float? value = readControl(sensor.Index);
|
||||
if (value.HasValue) {
|
||||
sensor.Value = value;
|
||||
ActivateSensor(sensor);
|
||||
}
|
||||
}
|
||||
|
||||
postUpdate();
|
||||
}
|
||||
|
||||
public override void Close() {
|
||||
foreach (Sensor sensor in controls) {
|
||||
// restore all controls back to default
|
||||
superIO.SetControl(sensor.Index, null);
|
||||
}
|
||||
base.Close();
|
||||
}
|
||||
|
||||
private class Voltage {
|
||||
public readonly string Name;
|
||||
public readonly int Index;
|
||||
@ -1064,5 +1113,15 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
this.Index = index;
|
||||
}
|
||||
}
|
||||
|
||||
private class Ctrl {
|
||||
public readonly string Name;
|
||||
public readonly int Index;
|
||||
|
||||
public Ctrl(string name, int index) {
|
||||
this.Name = name;
|
||||
this.Index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user