Hardware/LPC/IT87XX.cs
changeset 382 ba6abd47a80c
parent 353 b4e37f5b2669
     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    }