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 }