Added experimental support for Nuvoton NCT6779D super I/O chips.
1.1 --- a/Hardware/LPC/Chip.cs Sun Jun 24 16:16:46 2012 +0000
1.2 +++ b/Hardware/LPC/Chip.cs Sun Jul 01 21:44:07 2012 +0000
1.3 @@ -37,6 +37,7 @@
1.4
1.5 NCT6771F = 0xB470,
1.6 NCT6776F = 0xC330,
1.7 + NCT6779D = 0xC560,
1.8
1.9 W83627DHG = 0xA020,
1.10 W83627DHGP = 0xB070,
1.11 @@ -78,6 +79,7 @@
1.12
1.13 case Chip.NCT6771F: return "Nuvoton NCT6771F";
1.14 case Chip.NCT6776F: return "Nuvoton NCT6776F";
1.15 + case Chip.NCT6779D: return "Nuvoton NCT6779D";
1.16
1.17 case Chip.W83627DHG: return "Winbond W83627DHG";
1.18 case Chip.W83627DHGP: return "Winbond W83627DHG-P";
2.1 --- a/Hardware/LPC/LPCIO.cs Sun Jun 24 16:16:46 2012 +0000
2.2 +++ b/Hardware/LPC/LPCIO.cs Sun Jul 01 21:44:07 2012 +0000
2.3 @@ -211,6 +211,13 @@
2.4 logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.5 break;
2.6 } break;
2.7 + case 0xC5:
2.8 + switch (revision & 0xF0) {
2.9 + case 0x60:
2.10 + chip = Chip.NCT6779D;
2.11 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.12 + break;
2.13 + } break;
2.14 }
2.15 if (chip == Chip.Unknown) {
2.16 if (id != 0 && id != 0xff) {
2.17 @@ -271,6 +278,7 @@
2.18 break;
2.19 case Chip.NCT6771F:
2.20 case Chip.NCT6776F:
2.21 + case Chip.NCT6779D:
2.22 superIOs.Add(new NCT677X(chip, revision, address));
2.23 break;
2.24 case Chip.F71858:
3.1 --- a/Hardware/LPC/NCT677X.cs Sun Jun 24 16:16:46 2012 +0000
3.2 +++ b/Hardware/LPC/NCT677X.cs Sun Jul 01 21:44:07 2012 +0000
3.3 @@ -4,10 +4,11 @@
3.4 License, v. 2.0. If a copy of the MPL was not distributed with this
3.5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
3.6
3.7 - Copyright (C) 2010-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
3.8 + Copyright (C) 2010-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
3.9
3.10 */
3.11
3.12 +using System;
3.13 using System.Globalization;
3.14 using System.Text;
3.15
3.16 @@ -19,10 +20,10 @@
3.17
3.18 private readonly Chip chip;
3.19
3.20 - private readonly float?[] voltages = new float?[9];
3.21 - private readonly float?[] temperatures = new float?[4];
3.22 - private readonly float?[] fans = new float?[0];
3.23 - private readonly float?[] controls = new float?[3];
3.24 + private readonly float?[] voltages;
3.25 + private readonly float?[] temperatures;
3.26 + private readonly float?[] fans ;
3.27 + private readonly float?[] controls;
3.28
3.29 // Hardware Monitor
3.30 private const uint ADDRESS_REGISTER_OFFSET = 0x05;
3.31 @@ -52,33 +53,33 @@
3.32
3.33 // Hardware Monitor Registers
3.34 private const ushort VENDOR_ID_HIGH_REGISTER = 0x804F;
3.35 - private const ushort VENDOR_ID_LOW_REGISTER = 0x004F;
3.36 - private const ushort VOLTAGE_VBAT_REG = 0x0551;
3.37 + private const ushort VENDOR_ID_LOW_REGISTER = 0x004F;
3.38 +
3.39 + private readonly ushort[] FAN_PWM_OUT_REG =
3.40 + { 0x001, 0x003, 0x011, 0x013, 0x015 };
3.41 + private readonly ushort[] FAN_PWM_COMMAND_REG =
3.42 + { 0x109, 0x209, 0x309, 0x809, 0x909 };
3.43 + private readonly ushort[] FAN_CONTROL_MODE_REG =
3.44 + { 0x102, 0x202, 0x302, 0x802, 0x902 };
3.45
3.46 - private readonly ushort[] TEMPERATURE_REG =
3.47 - { 0x027, 0x73, 0x75, 0x77, 0x150, 0x250, 0x62B, 0x62C, 0x62D };
3.48 - private readonly ushort[] TEMPERATURE_HALF_REG =
3.49 - { 0, 0x74, 0x76, 0x78, 0x151, 0x251, 0x62E, 0x62E, 0x62E };
3.50 - private readonly ushort[] TEMPERATURE_SRC_REG =
3.51 - { 0x621, 0x100, 0x200, 0x300, 0x622, 0x623, 0x624, 0x625, 0x626 };
3.52 - private readonly int[] TEMPERATURE_HALF_BIT =
3.53 - { -1, 7, 7, 7, 7, 7, 0, 1, 2 };
3.54 - private readonly ushort[] VOLTAGE_REG =
3.55 - { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551 };
3.56 - private readonly ushort[] FAN_RPM_REG =
3.57 - { 0x656, 0x658, 0x65A, 0x65C, 0x65E};
3.58 - private readonly ushort[] FAN_PWM_OUT_REG =
3.59 - { 0x001, 0x003, 0x011 };
3.60 - private readonly ushort[] FAN_PWM_COMMAND_REG =
3.61 - { 0x109, 0x209, 0x309 };
3.62 - private readonly ushort[] FAN_CONTROL_MODE_REG =
3.63 - { 0x102, 0x202, 0x302 };
3.64 -
3.65 + private readonly ushort fanRpmBaseRegister;
3.66 private readonly int minFanRPM;
3.67
3.68 - private bool[] restoreDefaultFanControlRequired = { false, false, false };
3.69 - private byte[] initialFanControlMode = new byte[3];
3.70 - private byte[] initialFanPwmCommand = new byte[3];
3.71 + private bool[] restoreDefaultFanControlRequired = new bool[5];
3.72 + private byte[] initialFanControlMode = new byte[5];
3.73 + private byte[] initialFanPwmCommand = new byte[5];
3.74 +
3.75 + private readonly ushort[] voltageRegisters;
3.76 + private readonly ushort voltageVBatRegister;
3.77 +
3.78 + private readonly byte[] temperaturesSource;
3.79 +
3.80 + private readonly ushort[] temperatureRegister;
3.81 + private readonly ushort[] temperatureHalfRegister;
3.82 + private readonly int[] temperatureHalfBit;
3.83 + private readonly ushort[] temperatureSourceRegister;
3.84 +
3.85 + private readonly ushort?[] alternateTemperatureRegister;
3.86
3.87 private enum SourceNCT6771F : byte {
3.88 SYSTIN = 1,
3.89 @@ -128,6 +129,34 @@
3.90 BYTE_TEMP = 22
3.91 }
3.92
3.93 + private enum SourceNCT6779D : byte {
3.94 + SYSTIN = 1,
3.95 + CPUTIN = 2,
3.96 + AUXTIN0 = 3,
3.97 + AUXTIN1 = 4,
3.98 + AUXTIN2 = 5,
3.99 + AUXTIN3 = 6,
3.100 + SMBUSMASTER_0 = 8,
3.101 + SMBUSMASTER_1 = 9,
3.102 + SMBUSMASTER_2 = 10,
3.103 + SMBUSMASTER_3 = 11,
3.104 + SMBUSMASTER_4 = 12,
3.105 + SMBUSMASTER_5 = 13,
3.106 + SMBUSMASTER_6 = 14,
3.107 + SMBUSMASTER_7 = 15,
3.108 + PECI_0 = 16,
3.109 + PECI_1 = 17,
3.110 + PCH_CHIP_CPU_MAX_TEMP = 18,
3.111 + PCH_CHIP_TEMP = 19,
3.112 + PCH_CPU_TEMP = 20,
3.113 + PCH_MCH_TEMP = 21,
3.114 + PCH_DIM0_TEMP = 22,
3.115 + PCH_DIM1_TEMP = 23,
3.116 + PCH_DIM2_TEMP = 24,
3.117 + PCH_DIM3_TEMP = 25,
3.118 + BYTE_TEMP = 26
3.119 + }
3.120 +
3.121 public NCT677X(Chip chip, byte revision, ushort port) {
3.122 this.chip = chip;
3.123 this.revision = revision;
3.124 @@ -137,15 +166,93 @@
3.125 return;
3.126
3.127 switch (chip) {
3.128 - case LPC.Chip.NCT6771F:
3.129 - fans = new float?[4];
3.130 - // min value RPM value with 16-bit fan counter
3.131 - minFanRPM = (int)(1.35e6 / 0xFFFF);
3.132 + case Chip.NCT6771F:
3.133 + case Chip.NCT6776F:
3.134 + if (chip == Chip.NCT6771F) {
3.135 + fans = new float?[4];
3.136 +
3.137 + // min value RPM value with 16-bit fan counter
3.138 + minFanRPM = (int)(1.35e6 / 0xFFFF);
3.139 +
3.140 + temperaturesSource = new byte[] {
3.141 + (byte)SourceNCT6771F.PECI_0,
3.142 + (byte)SourceNCT6771F.CPUTIN,
3.143 + (byte)SourceNCT6771F.AUXTIN,
3.144 + (byte)SourceNCT6771F.SYSTIN
3.145 + };
3.146 + } else {
3.147 + fans = new float?[5];
3.148 +
3.149 + // min value RPM value with 13-bit fan counter
3.150 + minFanRPM = (int)(1.35e6 / 0x1FFF);
3.151 +
3.152 + temperaturesSource = new byte[] {
3.153 + (byte)SourceNCT6776F.PECI_0,
3.154 + (byte)SourceNCT6776F.CPUTIN,
3.155 + (byte)SourceNCT6776F.AUXTIN,
3.156 + (byte)SourceNCT6776F.SYSTIN
3.157 + };
3.158 + }
3.159 + fanRpmBaseRegister = 0x656;
3.160 +
3.161 + controls = new float?[3];
3.162 +
3.163 + voltages = new float?[9];
3.164 + voltageRegisters = new ushort[]
3.165 + { 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x550, 0x551 };
3.166 + voltageVBatRegister = 0x551;
3.167 +
3.168 + temperatures = new float?[4];
3.169 + temperatureRegister = new ushort[]
3.170 + { 0x027, 0x073, 0x075, 0x077, 0x150, 0x250, 0x62B, 0x62C, 0x62D };
3.171 + temperatureHalfRegister = new ushort[]
3.172 + { 0, 0x074, 0x076, 0x078, 0x151, 0x251, 0x62E, 0x62E, 0x62E };
3.173 + temperatureHalfBit = new int[]
3.174 + { -1, 7, 7, 7, 7, 7, 0, 1, 2 };
3.175 + temperatureSourceRegister = new ushort[]
3.176 + { 0x621, 0x100, 0x200, 0x300, 0x622, 0x623, 0x624, 0x625, 0x626 };
3.177 +
3.178 + alternateTemperatureRegister = new ushort?[]
3.179 + { null, null, null, null };
3.180 break;
3.181 - case LPC.Chip.NCT6776F:
3.182 + case Chip.NCT6779D:
3.183 fans = new float?[5];
3.184 + fanRpmBaseRegister = 0x4C0;
3.185 +
3.186 // min value RPM value with 13-bit fan counter
3.187 minFanRPM = (int)(1.35e6 / 0x1FFF);
3.188 +
3.189 + controls = new float?[5];
3.190 +
3.191 + voltages = new float?[15];
3.192 + voltageRegisters = new ushort[]
3.193 + { 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487, 0x488,
3.194 + 0x489, 0x48A, 0x48B, 0x48C, 0x48D, 0x48E };
3.195 + voltageVBatRegister = 0x488;
3.196 +
3.197 + temperatures = new float?[7];
3.198 + temperaturesSource = new byte[] {
3.199 + (byte)SourceNCT6779D.PECI_0,
3.200 + (byte)SourceNCT6779D.CPUTIN,
3.201 + (byte)SourceNCT6779D.SYSTIN,
3.202 + (byte)SourceNCT6779D.AUXTIN0,
3.203 + (byte)SourceNCT6779D.AUXTIN1,
3.204 + (byte)SourceNCT6779D.AUXTIN2,
3.205 + (byte)SourceNCT6779D.AUXTIN3
3.206 + };
3.207 +
3.208 + temperatureRegister = new ushort[]
3.209 + { 0x027, 0x073, 0x075, 0x077, 0x079, 0x07B, 0x150 };
3.210 + temperatureHalfRegister = new ushort[]
3.211 + { 0, 0x074, 0x076, 0x078, 0x07A, 0x07C, 0x151 };
3.212 + temperatureHalfBit = new int[]
3.213 + { -1, 7, 7, 7, 7, 7, 7 };
3.214 + temperatureSourceRegister = new ushort[]
3.215 + { 0x621, 0x100, 0x200, 0x300, 0x800, 0x900, 0x622 };
3.216 +
3.217 + alternateTemperatureRegister = new ushort?[]
3.218 + {null, 0x491, 0x490, 0x492, 0x493, 0x494, 0x495 };
3.219 +
3.220 break;
3.221 }
3.222 }
3.223 @@ -179,6 +286,9 @@
3.224 }
3.225
3.226 public void SetControl(int index, byte? value) {
3.227 + if (index < 0 || index >= controls.Length)
3.228 + throw new ArgumentOutOfRangeException("index");
3.229 +
3.230 if (!Ring0.WaitIsaBusMutex(10))
3.231 return;
3.232
3.233 @@ -208,51 +318,48 @@
3.234 return;
3.235
3.236 for (int i = 0; i < voltages.Length; i++) {
3.237 - float value = 0.008f * ReadByte(VOLTAGE_REG[i]);
3.238 + float value = 0.008f * ReadByte(voltageRegisters[i]);
3.239 bool valid = value > 0;
3.240
3.241 // check if battery voltage monitor is enabled
3.242 - if (valid && VOLTAGE_REG[i] == VOLTAGE_VBAT_REG)
3.243 + if (valid && voltageRegisters[i] == voltageVBatRegister)
3.244 valid = (ReadByte(0x005D) & 0x01) > 0;
3.245
3.246 voltages[i] = valid ? value : (float?)null;
3.247 }
3.248
3.249 - for (int i = TEMPERATURE_REG.Length - 1; i >= 0 ; i--) {
3.250 - int value = ((sbyte)ReadByte(TEMPERATURE_REG[i])) << 1;
3.251 - if (TEMPERATURE_HALF_BIT[i] > 0) {
3.252 - value |= ((ReadByte(TEMPERATURE_HALF_REG[i]) >>
3.253 - TEMPERATURE_HALF_BIT[i]) & 0x1);
3.254 + int temperatureSourceMask = 0;
3.255 + for (int i = temperatureRegister.Length - 1; i >= 0 ; i--) {
3.256 + int value = ((sbyte)ReadByte(temperatureRegister[i])) << 1;
3.257 + if (temperatureHalfBit[i] > 0) {
3.258 + value |= ((ReadByte(temperatureHalfRegister[i]) >>
3.259 + temperatureHalfBit[i]) & 0x1);
3.260 }
3.261
3.262 - byte source = ReadByte(TEMPERATURE_SRC_REG[i]);
3.263 + byte source = ReadByte(temperatureSourceRegister[i]);
3.264 + temperatureSourceMask |= 1 << source;
3.265
3.266 float? temperature = 0.5f * value;
3.267 if (temperature > 125 || temperature < -55)
3.268 temperature = null;
3.269
3.270 - switch (chip) {
3.271 - case Chip.NCT6771F:
3.272 - switch ((SourceNCT6771F)source) {
3.273 - case SourceNCT6771F.PECI_0: temperatures[0] = temperature; break;
3.274 - case SourceNCT6771F.CPUTIN: temperatures[1] = temperature; break;
3.275 - case SourceNCT6771F.AUXTIN: temperatures[2] = temperature; break;
3.276 - case SourceNCT6771F.SYSTIN: temperatures[3] = temperature; break;
3.277 -
3.278 - } break;
3.279 - case Chip.NCT6776F:
3.280 - switch ((SourceNCT6776F)source) {
3.281 - case SourceNCT6776F.PECI_0: temperatures[0] = temperature; break;
3.282 - case SourceNCT6776F.CPUTIN: temperatures[1] = temperature; break;
3.283 - case SourceNCT6776F.AUXTIN: temperatures[2] = temperature; break;
3.284 - case SourceNCT6776F.SYSTIN: temperatures[3] = temperature; break;
3.285 - } break;
3.286 - }
3.287 + for (int j = 0; j < temperatures.Length; j++)
3.288 + if (temperaturesSource[j] == source)
3.289 + temperatures[j] = temperature;
3.290 + }
3.291 + for (int i = 0; i < alternateTemperatureRegister.Length; i++) {
3.292 + if (!alternateTemperatureRegister[i].HasValue)
3.293 + continue;
3.294 +
3.295 + if ((temperatureSourceMask & (1 << temperaturesSource[i])) > 0)
3.296 + continue;
3.297 +
3.298 + temperatures[i] = ReadByte(alternateTemperatureRegister[i].Value);
3.299 }
3.300
3.301 for (int i = 0; i < fans.Length; i++) {
3.302 - byte high = ReadByte(FAN_RPM_REG[i]);
3.303 - byte low = ReadByte((ushort)(FAN_RPM_REG[i] + 1));
3.304 + byte high = ReadByte((ushort)(fanRpmBaseRegister + (i << 1)));
3.305 + byte low = ReadByte((ushort)(fanRpmBaseRegister + (i << 1) + 1));
3.306 int value = (high << 8) | low;
3.307
3.308 fans[i] = value > minFanRPM ? value : 0;
3.309 @@ -286,9 +393,11 @@
3.310 0x100, 0x110, 0x120, 0x130, 0x140, 0x150,
3.311 0x200, 0x220, 0x230, 0x240, 0x250,
3.312 0x300, 0x320, 0x330, 0x340,
3.313 - 0x400, 0x410, 0x420, 0x440, 0x450, 0x460,
3.314 + 0x400, 0x410, 0x420, 0x440, 0x450, 0x460, 0x480, 0x490, 0x4C0,
3.315 0x500, 0x550,
3.316 0x600, 0x610 ,0x620, 0x630, 0x640, 0x650, 0x660, 0x670,
3.317 + 0x800,
3.318 + 0x900,
3.319 0xA00, 0xA10, 0xA20, 0xA30, 0xA50, 0xA60, 0xA70,
3.320 0xB00, 0xB10, 0xB20, 0xB30, 0xB50, 0xB60, 0xB70,
3.321 0xC00, 0xC10, 0xC20, 0xC30, 0xC50, 0xC60, 0xC70,
4.1 --- a/Properties/AssemblyVersion.cs Sun Jun 24 16:16:46 2012 +0000
4.2 +++ b/Properties/AssemblyVersion.cs Sun Jul 01 21:44:07 2012 +0000
4.3 @@ -10,5 +10,5 @@
4.4
4.5 using System.Reflection;
4.6
4.7 -[assembly: AssemblyVersion("0.4.0.11")]
4.8 -[assembly: AssemblyInformationalVersion("0.4.0.11 Alpha")]
4.9 \ No newline at end of file
4.10 +[assembly: AssemblyVersion("0.4.0.12")]
4.11 +[assembly: AssemblyInformationalVersion("0.4.0.12 Alpha")]
4.12 \ No newline at end of file