Added first experimental support for the Nuvoton NCT6771F super I/O chip.
1.1 --- a/Hardware/LPC/Chip.cs Sun Nov 21 12:28:31 2010 +0000
1.2 +++ b/Hardware/LPC/Chip.cs Sun Nov 21 17:31:25 2010 +0000
1.3 @@ -53,12 +53,13 @@
1.4 W83667HG = 0xA510,
1.5 W83667HGB = 0xB350,
1.6 W83687THF = 0x8541,
1.7 + NCT6771F = 0xB470,
1.8 F71858 = 0x0507,
1.9 F71862 = 0x0601,
1.10 F71869 = 0x0814,
1.11 F71882 = 0x0541,
1.12 F71889ED = 0x0909,
1.13 - F71889F = 0x0723
1.14 + F71889F = 0x0723
1.15 }
1.16
1.17 internal class ChipName {
1.18 @@ -87,6 +88,7 @@
1.19 case Chip.W83667HG: return "Winbond W83667HG";
1.20 case Chip.W83667HGB: return "Winbond W83667HG-B";
1.21 case Chip.W83687THF: return "Winbond W83687THF";
1.22 + case Chip.NCT6771F: return "Nuvoton NCT6771F";
1.23 case Chip.Unknown: return "Unkown";
1.24 default: return "Unknown";
1.25 }
2.1 --- a/Hardware/LPC/LPCIO.cs Sun Nov 21 12:28:31 2010 +0000
2.2 +++ b/Hardware/LPC/LPCIO.cs Sun Nov 21 17:31:25 2010 +0000
2.3 @@ -88,27 +88,27 @@
2.4 report.AppendLine();
2.5 }
2.6
2.7 - #region Winbond, Fintek
2.8 + #region Winbond, Nuvoton, Fintek
2.9
2.10 private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
2.11 private const ushort FINTEK_VENDOR_ID = 0x1934;
2.12
2.13 - private const byte WINBOND_HARDWARE_MONITOR_LDN = 0x0B;
2.14 + private const byte WINBOND_NUVOTON_HARDWARE_MONITOR_LDN = 0x0B;
2.15
2.16 private const byte F71858_HARDWARE_MONITOR_LDN = 0x02;
2.17 private const byte FINTEK_HARDWARE_MONITOR_LDN = 0x04;
2.18
2.19 - private void WinbondFintekEnter() {
2.20 + private void WinbondNuvotonFintekEnter() {
2.21 Ring0.WriteIoPort(registerPort, 0x87);
2.22 Ring0.WriteIoPort(registerPort, 0x87);
2.23 }
2.24
2.25 - private void WinbondFintekExit() {
2.26 + private void WinbondNuvotonFintekExit() {
2.27 Ring0.WriteIoPort(registerPort, 0xAA);
2.28 }
2.29
2.30 private bool DetectWinbondFintek() {
2.31 - WinbondFintekEnter();
2.32 + WinbondNuvotonFintekEnter();
2.33
2.34 byte logicalDeviceNumber = 0;
2.35 byte id = ReadByte(CHIP_ID_REGISTER);
2.36 @@ -160,21 +160,21 @@
2.37 case 0x3A:
2.38 case 0x41:
2.39 chip = Chip.W83627HF;
2.40 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.41 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.42 break;
2.43 } break;
2.44 case 0x82:
2.45 switch (revision & 0xF0) {
2.46 case 0x80:
2.47 chip = Chip.W83627THF;
2.48 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.49 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.50 break;
2.51 } break;
2.52 case 0x85:
2.53 switch (revision) {
2.54 case 0x41:
2.55 chip = Chip.W83687THF;
2.56 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.57 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.58 break;
2.59 } break;
2.60 case 0x88:
2.61 @@ -182,43 +182,51 @@
2.62 case 0x50:
2.63 case 0x60:
2.64 chip = Chip.W83627EHF;
2.65 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.66 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.67 break;
2.68 } break;
2.69 case 0xA0:
2.70 switch (revision & 0xF0) {
2.71 case 0x20:
2.72 chip = Chip.W83627DHG;
2.73 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.74 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.75 break;
2.76 } break;
2.77 case 0xA5:
2.78 switch (revision & 0xF0) {
2.79 case 0x10:
2.80 chip = Chip.W83667HG;
2.81 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.82 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.83 break;
2.84 } break;
2.85 case 0xB0:
2.86 switch (revision & 0xF0) {
2.87 case 0x70:
2.88 chip = Chip.W83627DHGP;
2.89 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.90 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.91 break;
2.92 } break;
2.93 case 0xB3:
2.94 switch (revision & 0xF0) {
2.95 case 0x50:
2.96 chip = Chip.W83667HGB;
2.97 - logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
2.98 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.99 + break;
2.100 + } break;
2.101 + case 0xB4:
2.102 + switch (revision & 0xF0) {
2.103 + case 0x70:
2.104 + chip = Chip.NCT6771F;
2.105 + logicalDeviceNumber = WINBOND_NUVOTON_HARDWARE_MONITOR_LDN;
2.106 break;
2.107 } break;
2.108 }
2.109 if (chip == Chip.Unknown) {
2.110 if (id != 0 && id != 0xff) {
2.111 - WinbondFintekExit();
2.112 + WinbondNuvotonFintekExit();
2.113
2.114 - ReportUnknownChip("Winbond / Fintek", ((id << 8) | revision));
2.115 + ReportUnknownChip("Winbond / Nuvoton / Fintek",
2.116 + ((id << 8) | revision));
2.117 }
2.118 } else {
2.119
2.120 @@ -229,7 +237,7 @@
2.121
2.122 ushort vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
2.123
2.124 - WinbondFintekExit();
2.125 + WinbondNuvotonFintekExit();
2.126
2.127 if (address != verify) {
2.128 report.Append("Chip ID: 0x");
2.129 @@ -270,6 +278,9 @@
2.130 case Chip.W83687THF:
2.131 superIOs.Add(new W836XX(chip, revision, address));
2.132 break;
2.133 + case Chip.NCT6771F:
2.134 + superIOs.Add(new NCT677X(chip, revision, address));
2.135 + break;
2.136 case Chip.F71858:
2.137 case Chip.F71862:
2.138 case Chip.F71869:
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/Hardware/LPC/NCT677X.cs Sun Nov 21 17:31:25 2010 +0000
3.3 @@ -0,0 +1,225 @@
3.4 +/*
3.5 +
3.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
3.7 +
3.8 + The contents of this file are subject to the Mozilla Public License Version
3.9 + 1.1 (the "License"); you may not use this file except in compliance with
3.10 + the License. You may obtain a copy of the License at
3.11 +
3.12 + http://www.mozilla.org/MPL/
3.13 +
3.14 + Software distributed under the License is distributed on an "AS IS" basis,
3.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
3.16 + for the specific language governing rights and limitations under the License.
3.17 +
3.18 + The Original Code is the Open Hardware Monitor code.
3.19 +
3.20 + The Initial Developer of the Original Code is
3.21 + Michael Möller <m.moeller@gmx.ch>.
3.22 + Portions created by the Initial Developer are Copyright (C) 2010
3.23 + the Initial Developer. All Rights Reserved.
3.24 +
3.25 + Contributor(s):
3.26 +
3.27 + Alternatively, the contents of this file may be used under the terms of
3.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
3.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
3.30 + in which case the provisions of the GPL or the LGPL are applicable instead
3.31 + of those above. If you wish to allow use of your version of this file only
3.32 + under the terms of either the GPL or the LGPL, and not to allow others to
3.33 + use your version of this file under the terms of the MPL, indicate your
3.34 + decision by deleting the provisions above and replace them with the notice
3.35 + and other provisions required by the GPL or the LGPL. If you do not delete
3.36 + the provisions above, a recipient may use your version of this file under
3.37 + the terms of any one of the MPL, the GPL or the LGPL.
3.38 +
3.39 +*/
3.40 +
3.41 +using System.Globalization;
3.42 +using System.Text;
3.43 +
3.44 +namespace OpenHardwareMonitor.Hardware.LPC {
3.45 + internal class NCT677X : ISuperIO {
3.46 +
3.47 + private readonly ushort port;
3.48 + private readonly byte revision;
3.49 +
3.50 + private readonly Chip chip;
3.51 +
3.52 + private readonly float?[] voltages = new float?[9];
3.53 + private readonly float?[] temperatures = new float?[3];
3.54 + private readonly float?[] fans = new float?[4];
3.55 +
3.56 + // Hardware Monitor
3.57 + private const uint ADDRESS_REGISTER_OFFSET = 0x05;
3.58 + private const uint DATA_REGISTER_OFFSET = 0x06;
3.59 + private const byte BANK_SELECT_REGISTER = 0x4E;
3.60 +
3.61 + private byte ReadByte(ushort address) {
3.62 + byte bank = (byte)(address >> 8);
3.63 + byte register = (byte)(address & 0xFF);
3.64 + Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, BANK_SELECT_REGISTER);
3.65 + Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, bank);
3.66 + Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, register);
3.67 + return Ring0.ReadIoPort(port + DATA_REGISTER_OFFSET);
3.68 + }
3.69 +
3.70 + // Consts
3.71 + private const ushort NUVOTON_VENDOR_ID = 0x5CA3;
3.72 +
3.73 + // Hardware Monitor Registers
3.74 + private const ushort VENDOR_ID_HIGH_REGISTER = 0x804F;
3.75 + private const ushort VENDOR_ID_LOW_REGISTER = 0x004F;
3.76 + private const ushort VOLTAGE_VBAT_REG = 0x0551;
3.77 +
3.78 + private readonly ushort[] TEMPERATURE_REG =
3.79 + { 0x150, 0x250, 0x27, 0x62B, 0x62C, 0x62D };
3.80 + private readonly ushort[] TEMPERATURE_HALF_REG =
3.81 + { 0x151, 0x251, 0, 0x62E, 0x62E, 0x62E };
3.82 + private readonly ushort[] TEMPERATURE_SRC_REG =
3.83 + { 0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
3.84 + private readonly int[] TEMPERATURE_HALF_BIT = { 7, 7, -1, 0, 1, 2 };
3.85 + private readonly ushort[] VOLTAGE_REG =
3.86 + { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551 };
3.87 + private readonly ushort[] FAN_RPM_REG = { 0x656, 0x658, 0x65A, 0x65C};
3.88 +
3.89 + private enum TemperatureSource : byte {
3.90 + SYSTIN = 1,
3.91 + CPUTIN = 2,
3.92 + AUXTIN = 3,
3.93 + SMBUSMASTER = 4,
3.94 + PECI0 = 5,
3.95 + PECI1 = 6,
3.96 + PECI2 = 7,
3.97 + PECI3 = 8,
3.98 + PECI4 = 9,
3.99 + PECI5 = 10,
3.100 + PECI6 = 11,
3.101 + PECI7 = 12,
3.102 + PCH_CHIP_CPU_MAX_TEMP = 13,
3.103 + PCH_CHIP_TEMP = 14,
3.104 + PCH_CPU_TEMP = 15,
3.105 + PCH_MCH_TEMP = 16,
3.106 + PCH_DIM0_TEMP = 17,
3.107 + PCH_DIM1_TEMP = 18,
3.108 + PCH_DIM2_TEMP = 19,
3.109 + PCH_DIM3_TEMP = 20
3.110 + }
3.111 +
3.112 + public NCT677X(Chip chip, byte revision, ushort port) {
3.113 + this.chip = chip;
3.114 + this.revision = revision;
3.115 + this.port = port;
3.116 +
3.117 + if (!IsNuvotonVendor())
3.118 + return;
3.119 + }
3.120 +
3.121 + private bool IsNuvotonVendor() {
3.122 + return ((ReadByte(VENDOR_ID_HIGH_REGISTER) << 8) |
3.123 + ReadByte(VENDOR_ID_LOW_REGISTER)) == NUVOTON_VENDOR_ID;
3.124 + }
3.125 +
3.126 + public byte? ReadGPIO(int index) {
3.127 + return null;
3.128 + }
3.129 +
3.130 + public void WriteGPIO(int index, byte value) { }
3.131 +
3.132 + public Chip Chip { get { return chip; } }
3.133 + public float?[] Voltages { get { return voltages; } }
3.134 + public float?[] Temperatures { get { return temperatures; } }
3.135 + public float?[] Fans { get { return fans; } }
3.136 +
3.137 + public void Update() {
3.138 + if (!Ring0.WaitIsaBusMutex(10))
3.139 + return;
3.140 +
3.141 + for (int i = 0; i < voltages.Length; i++) {
3.142 + float value = 0.008f * ReadByte(VOLTAGE_REG[i]);
3.143 + bool valid = value > 0;
3.144 +
3.145 + // check if battery voltage monitor is enabled
3.146 + if (valid && VOLTAGE_REG[i] == VOLTAGE_VBAT_REG)
3.147 + valid = (ReadByte(0x005D) & 0x01) > 0;
3.148 +
3.149 + voltages[i] = valid ? value : (float?)null;
3.150 + }
3.151 +
3.152 + for (int i = 0; i < TEMPERATURE_REG.Length; i++) {
3.153 + float value = ReadByte(TEMPERATURE_REG[i]);
3.154 + if (TEMPERATURE_HALF_BIT[i] > 0) {
3.155 + value += 0.5f * ((ReadByte(TEMPERATURE_HALF_REG[i]) >>
3.156 + TEMPERATURE_HALF_BIT[i]) & 0x1);
3.157 + }
3.158 +
3.159 + TemperatureSource source = (TemperatureSource)
3.160 + ReadByte(TEMPERATURE_SRC_REG[i]);
3.161 +
3.162 + switch (source) {
3.163 + case TemperatureSource.CPUTIN: temperatures[0] = value; break;
3.164 + case TemperatureSource.AUXTIN: temperatures[1] = value; break;
3.165 + case TemperatureSource.SYSTIN: temperatures[2] = value; break;
3.166 + }
3.167 + }
3.168 +
3.169 + for (int i = 0; i < fans.Length; i++) {
3.170 + byte high = ReadByte(FAN_RPM_REG[i]);
3.171 + byte low = ReadByte((ushort)(FAN_RPM_REG[i] + 1));
3.172 + fans[i] = (high << 8) | low;
3.173 + }
3.174 +
3.175 + Ring0.ReleaseIsaBusMutex();
3.176 + }
3.177 +
3.178 + public string GetReport() {
3.179 + StringBuilder r = new StringBuilder();
3.180 +
3.181 + r.AppendLine("LPC " + this.GetType().Name);
3.182 + r.AppendLine();
3.183 + r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X"));
3.184 + r.Append("Chip revision: 0x");
3.185 + r.AppendLine(revision.ToString("X", CultureInfo.InvariantCulture));
3.186 + r.Append("Base Adress: 0x");
3.187 + r.AppendLine(port.ToString("X4", CultureInfo.InvariantCulture));
3.188 + r.AppendLine();
3.189 +
3.190 + if (!Ring0.WaitIsaBusMutex(100))
3.191 + return r.ToString();
3.192 +
3.193 + r.AppendLine("Hardware Monitor Registers");
3.194 + r.AppendLine();
3.195 + r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
3.196 + r.AppendLine();
3.197 + for (int i = 0; i <= 0x7; i++) {
3.198 + r.Append(" ");
3.199 + r.Append((i << 4).ToString("X3", CultureInfo.InvariantCulture));
3.200 + r.Append(" ");
3.201 + for (int j = 0; j <= 0xF; j++) {
3.202 + r.Append(" ");
3.203 + r.Append(ReadByte((ushort)((i << 4) | j)).ToString(
3.204 + "X2", CultureInfo.InvariantCulture));
3.205 + }
3.206 + r.AppendLine();
3.207 + }
3.208 + for (int bank = 1; bank <= 15; bank++) {
3.209 + for (int i = 0x5; i < 0x6; i++) {
3.210 + r.Append(" ");
3.211 + r.Append((i << 4).ToString("X3", CultureInfo.InvariantCulture));
3.212 + r.Append(" ");
3.213 + for (int j = 0; j <= 0xF; j++) {
3.214 + r.Append(" ");
3.215 + r.Append(ReadByte((ushort)((bank << 8) | (i << 4) | j)).ToString(
3.216 + "X2", CultureInfo.InvariantCulture));
3.217 + }
3.218 + r.AppendLine();
3.219 + }
3.220 + }
3.221 + r.AppendLine();
3.222 +
3.223 + Ring0.ReleaseIsaBusMutex();
3.224 +
3.225 + return r.ToString();
3.226 + }
3.227 + }
3.228 +}
4.1 --- a/Hardware/Mainboard/SuperIOHardware.cs Sun Nov 21 12:28:31 2010 +0000
4.2 +++ b/Hardware/Mainboard/SuperIOHardware.cs Sun Nov 21 17:31:25 2010 +0000
4.3 @@ -741,6 +741,24 @@
4.4 f.Add(new Fan("CPU Fan", 1));
4.5 f.Add(new Fan("Auxiliary Fan", 2));
4.6 break;
4.7 + case Chip.NCT6771F:
4.8 + v.Add(new Voltage("CPU VCore", 0));
4.9 + v.Add(new Voltage("Voltage #2", 1, true));
4.10 + v.Add(new Voltage("AVCC", 2, 34, 34));
4.11 + v.Add(new Voltage("3VCC", 3, 34, 34));
4.12 + v.Add(new Voltage("Voltage #5", 4, true));
4.13 + v.Add(new Voltage("Voltage #6", 5, true));
4.14 + v.Add(new Voltage("Voltage #7", 6, true));
4.15 + v.Add(new Voltage("3VSB", 7, 34, 34));
4.16 + v.Add(new Voltage("VBAT", 8, 34, 34));
4.17 + t.Add(new Temperature("CPU", 0));
4.18 + t.Add(new Temperature("Auxiliary", 1));
4.19 + t.Add(new Temperature("System", 2));
4.20 + f.Add(new Fan("System Fan", 0));
4.21 + f.Add(new Fan("CPU Fan", 1));
4.22 + f.Add(new Fan("Auxiliary Fan", 2));
4.23 + f.Add(new Fan("Auxiliary Fan #2", 4));
4.24 + break;
4.25 default:
4.26 for (int i = 0; i < superIO.Voltages.Length; i++)
4.27 v.Add(new Voltage("Voltage #" + (i + 1), i, true));
5.1 --- a/OpenHardwareMonitorLib.csproj Sun Nov 21 12:28:31 2010 +0000
5.2 +++ b/OpenHardwareMonitorLib.csproj Sun Nov 21 17:31:25 2010 +0000
5.3 @@ -69,6 +69,7 @@
5.4 <Compile Include="Hardware\CPU\CPUID.cs" />
5.5 <Compile Include="Hardware\CPU\CPULoad.cs" />
5.6 <Compile Include="Hardware\CPU\IntelCPU.cs" />
5.7 + <Compile Include="Hardware\LPC\NCT677X.cs" />
5.8 <Compile Include="Hardware\Opcode.cs" />
5.9 <Compile Include="Hardware\Ring0.cs" />
5.10 <Compile Include="Hardware\KernelDriver.cs" />