Hardware/LPC/W836XX.cs
changeset 130 80065ab20b84
parent 122 3ef997c53b50
child 152 98187e7a08b2
     1.1 --- a/Hardware/LPC/W836XX.cs	Sat May 29 13:49:20 2010 +0000
     1.2 +++ b/Hardware/LPC/W836XX.cs	Thu Jun 03 22:40:18 2010 +0000
     1.3 @@ -37,23 +37,24 @@
     1.4  
     1.5  using System;
     1.6  using System.Collections.Generic;
     1.7 -using System.Drawing;
     1.8  using System.Text;
     1.9  
    1.10  namespace OpenHardwareMonitor.Hardware.LPC {
    1.11 -  public class W836XX : LPCHardware, IHardware {
    1.12 +  public class W836XX : ISuperIO {
    1.13  
    1.14      private ushort address;
    1.15      private byte revision;
    1.16  
    1.17 -    private bool available;
    1.18 +    private Chip chip;
    1.19  
    1.20 -    private Sensor[] temperatures;
    1.21 -    private Sensor[] fans;
    1.22 -    private Sensor[] voltages;
    1.23 +    private float?[] voltages = new float?[0];
    1.24 +    private float?[] temperatures = new float?[0];    
    1.25 +    private float?[] fans = new float?[0];
    1.26  
    1.27 -    private float[] voltageGains;
    1.28 -    private string[] fanNames;
    1.29 +    private bool[] peciTemperature = new bool[0];
    1.30 +    private byte[] voltageRegister = new byte[0];
    1.31 +    private byte[] voltageBank = new byte[0];
    1.32 +    private float voltageGain = 0.008f;
    1.33  
    1.34      // Consts 
    1.35      private const ushort WINBOND_VENDOR_ID = 0x5CA3;
    1.36 @@ -64,13 +65,11 @@
    1.37      private const byte DATA_REGISTER_OFFSET = 0x06;
    1.38  
    1.39      // Hardware Monitor Registers
    1.40 -    private const byte VOLTAGE_BASE_REG = 0x20;
    1.41 +    private const byte VOLTAGE_VBAT_REG = 0x51;
    1.42      private const byte BANK_SELECT_REGISTER = 0x4E;
    1.43      private const byte VENDOR_ID_REGISTER = 0x4F;
    1.44      private const byte TEMPERATURE_SOURCE_SELECT_REG = 0x49;
    1.45  
    1.46 -    private string[] TEMPERATURE_NAME = 
    1.47 -      new string[] {"CPU", "Auxiliary", "System"};
    1.48      private byte[] TEMPERATURE_REG = new byte[] { 0x50, 0x50, 0x27 };
    1.49      private byte[] TEMPERATURE_BANK = new byte[] { 1, 2, 0 };
    1.50  
    1.51 @@ -90,7 +89,7 @@
    1.52           (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
    1.53        return WinRing0.ReadIoPortByte(
    1.54          (ushort)(address + DATA_REGISTER_OFFSET));
    1.55 -    }
    1.56 +    } 
    1.57  
    1.58      private void WriteByte(byte bank, byte register, byte value) {
    1.59        WinRing0.WriteIoPortByte(
    1.60 @@ -103,90 +102,73 @@
    1.61           (ushort)(address + DATA_REGISTER_OFFSET), value); 
    1.62      }
    1.63     
    1.64 -    public W836XX(Chip chip, byte revision, ushort address) 
    1.65 -      : base(chip)
    1.66 -    {
    1.67 +    public W836XX(Chip chip, byte revision, ushort address) {
    1.68        this.address = address;
    1.69        this.revision = revision;
    1.70 +      this.chip = chip;
    1.71  
    1.72 -      available = IsWinbondVendor();
    1.73 -
    1.74 -      ParameterDescription[] parameter = new ParameterDescription[] {
    1.75 -        new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
    1.76 -      };
    1.77 -      List<Sensor> list = new List<Sensor>();
    1.78 +      if (!IsWinbondVendor())
    1.79 +        return;
    1.80 +      
    1.81 +      temperatures = new float?[3];
    1.82 +      peciTemperature = new bool[3];
    1.83        switch (chip) {
    1.84          case Chip.W83667HG:
    1.85          case Chip.W83667HGB:
    1.86 -          // do not add temperature sensor registers that read PECI
    1.87 +          // note temperature sensor registers that read PECI
    1.88            byte flag = ReadByte(0, TEMPERATURE_SOURCE_SELECT_REG);
    1.89 -          if ((flag & 0x04) == 0)
    1.90 -            list.Add(new Sensor(TEMPERATURE_NAME[0], 0, null,
    1.91 -              SensorType.Temperature, this, parameter));
    1.92 -          if ((flag & 0x40) == 0)
    1.93 -            list.Add(new Sensor(TEMPERATURE_NAME[1], 1, null,
    1.94 -              SensorType.Temperature, this, parameter));
    1.95 -          list.Add(new Sensor(TEMPERATURE_NAME[2], 2, null,
    1.96 -            SensorType.Temperature, this, parameter));
    1.97 +          peciTemperature[0] = (flag & 0x04) != 0;
    1.98 +          peciTemperature[1] = (flag & 0x40) != 0;
    1.99 +          peciTemperature[2] = false;
   1.100            break;
   1.101          case Chip.W83627DHG:        
   1.102          case Chip.W83627DHGP:
   1.103            // do not add temperature sensor registers that read PECI
   1.104            byte sel = ReadByte(0, TEMPERATURE_SOURCE_SELECT_REG);
   1.105 -          if ((sel & 0x07) == 0)
   1.106 -            list.Add(new Sensor(TEMPERATURE_NAME[0], 0, null,
   1.107 -              SensorType.Temperature, this, parameter));
   1.108 -          if ((sel & 0x70) == 0)
   1.109 -            list.Add(new Sensor(TEMPERATURE_NAME[1], 1, null,
   1.110 -              SensorType.Temperature, this, parameter));
   1.111 -          list.Add(new Sensor(TEMPERATURE_NAME[2], 2, null,
   1.112 -            SensorType.Temperature, this, parameter));
   1.113 +          peciTemperature[0] = (sel & 0x07) != 0;
   1.114 +          peciTemperature[1] = (sel & 0x70) != 0;
   1.115 +          peciTemperature[2] = false;
   1.116            break;
   1.117          default:
   1.118 -          // no PECI support, add all sensors
   1.119 -          for (int i = 0; i < TEMPERATURE_NAME.Length; i++)
   1.120 -            list.Add(new Sensor(TEMPERATURE_NAME[i], i, null,
   1.121 -              SensorType.Temperature, this, parameter));
   1.122 +          // no PECI support
   1.123 +          peciTemperature[0] = false;
   1.124 +          peciTemperature[1] = false;
   1.125 +          peciTemperature[2] = false;
   1.126            break;
   1.127        }
   1.128 -      temperatures = list.ToArray();
   1.129  
   1.130        switch (chip) {
   1.131 +        case Chip.W83627EHF:
   1.132 +          voltages = new float?[10];
   1.133 +          voltageRegister = new byte[] { 
   1.134 +            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x50, 0x51, 0x52 };
   1.135 +          voltageBank = new byte[] { 0, 0, 0, 0, 0, 0, 0, 5, 5, 5 };
   1.136 +          voltageGain = 0.008f;
   1.137 +          fans = new float?[5];
   1.138 +          break;
   1.139          case Chip.W83627DHG:
   1.140 -        case Chip.W83627DHGP:
   1.141 -        case Chip.W83627EHF:
   1.142 +        case Chip.W83627DHGP:        
   1.143          case Chip.W83667HG:
   1.144 -        case Chip.W83667HGB: 
   1.145 -          fanNames = new string[] { "System", "CPU", "Auxiliary", 
   1.146 -            "CPU #2", "Auxiliary #2" };
   1.147 -          voltageGains = new float[] { 1, 1, 1, 2, 1, 1, 1, 2 };
   1.148 -          voltages = new Sensor[3];
   1.149 -          voltages[0] = new Sensor("CPU VCore", 0, SensorType.Voltage, this);
   1.150 -          voltages[1] = new Sensor("+3.3V", 3, SensorType.Voltage, this);
   1.151 -          voltages[2] = new Sensor("Battery", 7, SensorType.Voltage, this);
   1.152 +        case Chip.W83667HGB:
   1.153 +          voltages = new float?[9];
   1.154 +          voltageRegister = new byte[] { 
   1.155 +            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x50, 0x51 };
   1.156 +          voltageBank = new byte[] { 0, 0, 0, 0, 0, 0, 0, 5, 5 };
   1.157 +          voltageGain = 0.008f;
   1.158 +          fans = new float?[5];
   1.159            break;
   1.160          case Chip.W83627HF:
   1.161          case Chip.W83627THF:
   1.162          case Chip.W83687THF:
   1.163 -          fanNames = new string[] { "System", "CPU", "Auxiliary" };
   1.164 -          voltageGains = new float[] { 2, 1, 2, 1, 1, 1, 1, 2 };
   1.165 -          voltages = new Sensor[3];
   1.166 -          voltages[0] = new Sensor("CPU VCore", 0, SensorType.Voltage, this);
   1.167 -          voltages[1] = new Sensor("+3.3V", 2, SensorType.Voltage, this);
   1.168 -          voltages[2] = new Sensor("Battery", 7, SensorType.Voltage, this);
   1.169 -          break;
   1.170 -        default: fanNames = new string[0];
   1.171 +          voltages = new float?[7];
   1.172 +          voltageRegister = new byte[] { 
   1.173 +            0x20, 0x21, 0x22, 0x23, 0x24, 0x50, 0x51 };
   1.174 +          voltageBank = new byte[] { 0, 0, 0, 0, 0, 5, 5 };
   1.175 +          voltageGain = 0.016f;
   1.176 +          fans = new float?[3];         
   1.177            break;
   1.178        }
   1.179 -      
   1.180 -      fans = new Sensor[fanNames.Length];
   1.181 -      for (int i = 0; i < fanNames.Length; i++)
   1.182 -        fans[i] = new Sensor(fanNames[i], i, SensorType.Fan, this);
   1.183 -    }
   1.184 -
   1.185 -    public bool IsAvailable {
   1.186 -      get { return available; }
   1.187 -    }        
   1.188 +    }    
   1.189  
   1.190      private bool IsWinbondVendor() {
   1.191        ushort vendorId =
   1.192 @@ -206,52 +188,57 @@
   1.193        return value > 0 ? target | mask : target & ~mask;
   1.194      }
   1.195  
   1.196 -    public override void Update() {
   1.197 +    public Chip Chip { get { return chip; } }
   1.198 +    public float?[] Voltages { get { return voltages; } }
   1.199 +    public float?[] Temperatures { get { return temperatures; } }
   1.200 +    public float?[] Fans { get { return fans; } }
   1.201  
   1.202 -      foreach (Sensor sensor in voltages) {
   1.203 -        if (sensor.Index < 7) {
   1.204 +    public void Update() {
   1.205 +
   1.206 +      for (int i = 0; i < voltages.Length; i++) {
   1.207 +        if (voltageRegister[i] != VOLTAGE_VBAT_REG) {
   1.208            // two special VCore measurement modes for W83627THF
   1.209 +          float fvalue;
   1.210            if ((chip == Chip.W83627HF || chip == Chip.W83627THF || 
   1.211 -            chip == Chip.W83687THF) && sensor.Index == 0) 
   1.212 +            chip == Chip.W83687THF) && i == 0) 
   1.213            {
   1.214              byte vrmConfiguration = ReadByte(0, 0x18);
   1.215 -            int value = ReadByte(0, VOLTAGE_BASE_REG);
   1.216 +            int value = ReadByte(voltageBank[i], voltageRegister[i]);
   1.217              if ((vrmConfiguration & 0x01) == 0)
   1.218 -              sensor.Value = 0.016f * value; // VRM8 formula
   1.219 +              fvalue = 0.016f * value; // VRM8 formula
   1.220              else
   1.221 -              sensor.Value = 0.00488f * value + 0.69f; // VRM9 formula
   1.222 +              fvalue = 0.00488f * value + 0.69f; // VRM9 formula
   1.223            } else {
   1.224 -            int value = ReadByte(0, (byte)(VOLTAGE_BASE_REG + sensor.Index));
   1.225 -            sensor.Value = 0.008f * voltageGains[sensor.Index] * value;
   1.226 +            int value = ReadByte(voltageBank[i], voltageRegister[i]);
   1.227 +            fvalue = voltageGain * value;
   1.228            }
   1.229 -          if (sensor.Value > 0)
   1.230 -            ActivateSensor(sensor);
   1.231 +          if (fvalue > 0)
   1.232 +            voltages[i] = fvalue;
   1.233 +          else
   1.234 +            voltages[i] = null;
   1.235          } else {
   1.236            // Battery voltage
   1.237            bool valid = (ReadByte(0, 0x5D) & 0x01) > 0;
   1.238            if (valid) {
   1.239 -            sensor.Value =
   1.240 -              0.008f * voltageGains[sensor.Index] * ReadByte(5, 0x51);
   1.241 -            ActivateSensor(sensor);
   1.242 +            voltages[i] = voltageGain * ReadByte(5, VOLTAGE_VBAT_REG);
   1.243            } else {
   1.244 -            sensor.Value = null;
   1.245 +            voltages[i] = null;
   1.246            }
   1.247          }
   1.248        }
   1.249  
   1.250 -      foreach (Sensor sensor in temperatures) {
   1.251 -        int value = ((sbyte)ReadByte(TEMPERATURE_BANK[sensor.Index],
   1.252 -          TEMPERATURE_REG[sensor.Index])) << 1;
   1.253 -        if (TEMPERATURE_BANK[sensor.Index] > 0) 
   1.254 -          value |= ReadByte(TEMPERATURE_BANK[sensor.Index],
   1.255 -            (byte)(TEMPERATURE_REG[sensor.Index] + 1)) >> 7;
   1.256 +      for (int i = 0; i < temperatures.Length; i++) {
   1.257 +        int value = ((sbyte)ReadByte(TEMPERATURE_BANK[i], 
   1.258 +          TEMPERATURE_REG[i])) << 1;
   1.259 +        if (TEMPERATURE_BANK[i] > 0) 
   1.260 +          value |= ReadByte(TEMPERATURE_BANK[i],
   1.261 +            (byte)(TEMPERATURE_REG[i] + 1)) >> 7;
   1.262  
   1.263          float temperature = value / 2.0f;
   1.264 -        if (temperature <= 125 && temperature >= -55) {
   1.265 -          sensor.Value = temperature + sensor.Parameters[0].Value;
   1.266 -          ActivateSensor(sensor);
   1.267 +        if (temperature <= 125 && temperature >= -55 && !peciTemperature[i]) {
   1.268 +          temperatures[i] = temperature;
   1.269          } else {
   1.270 -          sensor.Value = null;
   1.271 +          temperatures[i] = null;
   1.272          }
   1.273        }
   1.274  
   1.275 @@ -259,21 +246,18 @@
   1.276        for (int i = 0; i < FAN_BIT_REG.Length; i++)
   1.277          bits = (bits << 8) | ReadByte(0, FAN_BIT_REG[i]);
   1.278        ulong newBits = bits;
   1.279 -      foreach (Sensor sensor in fans) {
   1.280 -        int count = ReadByte(FAN_TACHO_BANK[sensor.Index], 
   1.281 -          FAN_TACHO_REG[sensor.Index]);
   1.282 +      for (int i = 0; i < fans.Length; i++) {
   1.283 +        int count = ReadByte(FAN_TACHO_BANK[i], FAN_TACHO_REG[i]);
   1.284          
   1.285          // assemble fan divisor
   1.286          int divisorBits = (int)(
   1.287 -          (((bits >> FAN_DIV_BIT2[sensor.Index]) & 1) << 2) |
   1.288 -          (((bits >> FAN_DIV_BIT1[sensor.Index]) & 1) << 1) |
   1.289 -           ((bits >> FAN_DIV_BIT0[sensor.Index]) & 1));
   1.290 +          (((bits >> FAN_DIV_BIT2[i]) & 1) << 2) |
   1.291 +          (((bits >> FAN_DIV_BIT1[i]) & 1) << 1) |
   1.292 +           ((bits >> FAN_DIV_BIT0[i]) & 1));
   1.293          int divisor = 1 << divisorBits;
   1.294         
   1.295          float value = (count < 0xff) ? 1.35e6f / (count * divisor) : 0;
   1.296 -        sensor.Value = value;
   1.297 -        if (value > 0)
   1.298 -          ActivateSensor(sensor);
   1.299 +        fans[i] = value;
   1.300  
   1.301          // update fan divisor
   1.302          if (count > 192 && divisorBits < 7) 
   1.303 @@ -281,12 +265,9 @@
   1.304          if (count < 96 && divisorBits > 0)
   1.305            divisorBits--;
   1.306  
   1.307 -        newBits = SetBit(newBits, FAN_DIV_BIT2[sensor.Index], 
   1.308 -          (divisorBits >> 2) & 1);
   1.309 -        newBits = SetBit(newBits, FAN_DIV_BIT1[sensor.Index], 
   1.310 -          (divisorBits >> 1) & 1);
   1.311 -        newBits = SetBit(newBits, FAN_DIV_BIT0[sensor.Index], 
   1.312 -          divisorBits & 1);
   1.313 +        newBits = SetBit(newBits, FAN_DIV_BIT2[i], (divisorBits >> 2) & 1);
   1.314 +        newBits = SetBit(newBits, FAN_DIV_BIT1[i], (divisorBits >> 1) & 1);
   1.315 +        newBits = SetBit(newBits, FAN_DIV_BIT0[i], divisorBits & 1);
   1.316        }
   1.317       
   1.318        // write new fan divisors 
   1.319 @@ -300,7 +281,7 @@
   1.320        }
   1.321      }
   1.322  
   1.323 -    public override string GetReport() {
   1.324 +    public string GetReport() {
   1.325        StringBuilder r = new StringBuilder();
   1.326  
   1.327        r.AppendLine("LPC " + this.GetType().Name);
   1.328 @@ -337,5 +318,5 @@
   1.329  
   1.330        return r.ToString();
   1.331      }
   1.332 -  }
   1.333 +  } 
   1.334  }