1.1 --- a/Hardware/LPC/IT87XX.cs Mon Oct 01 17:10:09 2012 +0000
1.2 +++ b/Hardware/LPC/IT87XX.cs Sun Oct 21 14:24:03 2012 +0000
1.3 @@ -10,6 +10,7 @@
1.4
1.5 using System.Globalization;
1.6 using System.Text;
1.7 +using System;
1.8
1.9 namespace OpenHardwareMonitor.Hardware.LPC {
1.10 internal class IT87XX : ISuperIO {
1.11 @@ -45,10 +46,14 @@
1.12 private const byte VENDOR_ID_REGISTER = 0x58;
1.13 private const byte FAN_TACHOMETER_DIVISOR_REGISTER = 0x0B;
1.14 private readonly byte[] FAN_TACHOMETER_REG =
1.15 - new byte[] { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
1.16 + { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
1.17 private readonly byte[] FAN_TACHOMETER_EXT_REG =
1.18 - new byte[] { 0x18, 0x19, 0x1a, 0x81, 0x83 };
1.19 + { 0x18, 0x19, 0x1a, 0x81, 0x83 };
1.20 private const byte VOLTAGE_BASE_REG = 0x20;
1.21 + private readonly byte[] FAN_PWM_CTRL_REG = { 0x15, 0x16, 0x17 };
1.22 +
1.23 + private bool[] restoreDefaultFanPwmControlRequired = new bool[3];
1.24 + private byte[] initialFanPwmControl = new byte[3];
1.25
1.26 private byte ReadByte(byte register, out bool valid) {
1.27 Ring0.WriteIoPort(addressReg, register);
1.28 @@ -77,7 +82,40 @@
1.29 Ring0.WriteIoPort((ushort)(gpioAddress + index), value);
1.30 }
1.31
1.32 - public void SetControl(int index, byte? value) { }
1.33 + private void SaveDefaultFanPwmControl(int index) {
1.34 + bool valid;
1.35 + if (!restoreDefaultFanPwmControlRequired[index]) {
1.36 + initialFanPwmControl[index] =
1.37 + ReadByte(FAN_PWM_CTRL_REG[index], out valid);
1.38 + restoreDefaultFanPwmControlRequired[index] = true;
1.39 + }
1.40 + }
1.41 +
1.42 + private void RestoreDefaultFanPwmControl(int index) {
1.43 + if (restoreDefaultFanPwmControlRequired[index]) {
1.44 + WriteByte(FAN_PWM_CTRL_REG[index], initialFanPwmControl[index]);
1.45 + restoreDefaultFanPwmControlRequired[index] = false;
1.46 + }
1.47 + }
1.48 +
1.49 + public void SetControl(int index, byte? value) {
1.50 + if (index < 0 || index >= controls.Length)
1.51 + throw new ArgumentOutOfRangeException("index");
1.52 +
1.53 + if (!Ring0.WaitIsaBusMutex(10))
1.54 + return;
1.55 +
1.56 + if (value.HasValue) {
1.57 + SaveDefaultFanPwmControl(index);
1.58 +
1.59 + // set output value
1.60 + WriteByte(FAN_PWM_CTRL_REG[index], (byte)(value.Value >> 1));
1.61 + } else {
1.62 + RestoreDefaultFanPwmControl(index);
1.63 + }
1.64 +
1.65 + Ring0.ReleaseIsaBusMutex();
1.66 + }
1.67
1.68 public IT87XX(Chip chip, ushort address, ushort gpioAddress, byte version) {
1.69
1.70 @@ -103,6 +141,7 @@
1.71 voltages = new float?[9];
1.72 temperatures = new float?[3];
1.73 fans = new float?[chip == Chip.IT8705F ? 3 : 5];
1.74 + controls = new float?[3];
1.75
1.76 // IT8721F, IT8728F and IT8772E use a 12mV resultion ADC, all others 16mV
1.77 if (chip == Chip.IT8721F || chip == Chip.IT8728F || chip == Chip.IT8771E
1.78 @@ -270,6 +309,21 @@
1.79 }
1.80 }
1.81
1.82 + for (int i = 0; i < controls.Length; i++) {
1.83 + bool valid;
1.84 + byte value = ReadByte(FAN_PWM_CTRL_REG[i], out valid);
1.85 + if (!valid)
1.86 + continue;
1.87 +
1.88 + if ((value & 0x80) > 0) {
1.89 + // automatic operation (value can't be read)
1.90 + controls[i] = null;
1.91 + } else {
1.92 + // software operation
1.93 + controls[i] = (float)Math.Round((value & 0x7F) * 100.0f / 0x7F);
1.94 + }
1.95 + }
1.96 +
1.97 Ring0.ReleaseIsaBusMutex();
1.98 }
1.99 }