From 9e32a33cbf2497eeb5e9d5487b15e4a3dacee31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=B6ller?= Date: Sun, 15 Nov 2015 16:35:26 +0100 Subject: [PATCH] Merged the Nuvoton NCT6102D/NCT6106D implementation back into the NCT677X class. --- Hardware/LPC/LPCIO.cs | 4 +- Hardware/LPC/NCT610X.cs | 310 ---------------------------------- Hardware/LPC/NCT677X.cs | 111 ++++++++++-- OpenHardwareMonitorLib.csproj | 1 - 4 files changed, 98 insertions(+), 328 deletions(-) delete mode 100644 Hardware/LPC/NCT610X.cs diff --git a/Hardware/LPC/LPCIO.cs b/Hardware/LPC/LPCIO.cs index de34bb6..cc79031 100644 --- a/Hardware/LPC/LPCIO.cs +++ b/Hardware/LPC/LPCIO.cs @@ -4,7 +4,7 @@ License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - Copyright (C) 2009-2013 Michael Möller + Copyright (C) 2009-2015 Michael Möller */ @@ -316,8 +316,6 @@ namespace OpenHardwareMonitor.Hardware.LPC { superIOs.Add(new W836XX(chip, revision, address)); break; case Chip.NCT610X: - superIOs.Add(new NCT610X(chip, revision, address)); - break; case Chip.NCT6771F: case Chip.NCT6776F: case Chip.NCT6779D: diff --git a/Hardware/LPC/NCT610X.cs b/Hardware/LPC/NCT610X.cs deleted file mode 100644 index 7abb5cd..0000000 --- a/Hardware/LPC/NCT610X.cs +++ /dev/null @@ -1,310 +0,0 @@ -/* - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - - Copyright (C) 2010-2013 Michael Möller - Copyright (C) 2015 Dawid Gan - -*/ - -using System; -using System.Globalization; -using System.Text; - -namespace OpenHardwareMonitor.Hardware.LPC { - internal class NCT610X : ISuperIO { - - private readonly ushort port; - private readonly byte revision; - - private readonly Chip chip; - - private readonly bool isNuvotonVendor; - - private readonly float?[] voltages = new float?[0]; - private readonly float?[] temperatures = new float?[0]; - private readonly float?[] fans = new float?[0]; - private readonly float?[] controls = new float?[0]; - - // Hardware Monitor - private const uint ADDRESS_REGISTER_OFFSET = 0x05; - private const uint DATA_REGISTER_OFFSET = 0x06; - private const byte BANK_SELECT_REGISTER = 0x4E; - - private byte ReadByte(ushort address) { - byte bank = (byte)(address >> 8); - byte register = (byte)(address & 0xFF); - Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, BANK_SELECT_REGISTER); - Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, bank); - Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, register); - return Ring0.ReadIoPort(port + DATA_REGISTER_OFFSET); - } - - private void WriteByte(ushort address, byte value) { - byte bank = (byte)(address >> 8); - byte register = (byte)(address & 0xFF); - Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, BANK_SELECT_REGISTER); - Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, bank); - Ring0.WriteIoPort(port + ADDRESS_REGISTER_OFFSET, register); - Ring0.WriteIoPort(port + DATA_REGISTER_OFFSET, value); - } - - // Consts - private const ushort NUVOTON_VENDOR_ID = 0x5CA3; - - // Hardware Monitor Registers - private const ushort VENDOR_ID_HIGH_REGISTER = 0x80FE; - private const ushort VENDOR_ID_LOW_REGISTER = 0x00FE; - - private readonly ushort[] FAN_PWM_OUT_REG = - { 0x04A, 0x04B, 0x04C }; - private readonly ushort[] FAN_PWM_COMMAND_REG = - { 0x119, 0x129, 0x139 }; - private readonly ushort[] FAN_CONTROL_MODE_REG = - { 0x113, 0x123, 0x133 }; - - private readonly ushort fanRpmBaseRegister; - private readonly int minFanRPM; - - private bool[] restoreDefaultFanControlRequired = new bool[6]; - private byte[] initialFanControlMode = new byte[6]; - private byte[] initialFanPwmCommand = new byte[6]; - - private readonly ushort?[] voltageRegisters; - private readonly ushort voltageVBatRegister; - - private readonly byte[] temperaturesSource; - - private readonly ushort[] temperatureRegister; - private readonly ushort[] temperatureHalfRegister; - private readonly int[] temperatureHalfBit; - private readonly ushort[] temperatureSourceRegister; - - private readonly ushort?[] alternateTemperatureRegister; - - - private enum SourceNCT610X : byte - { - SYSTIN = 1, - CPUTIN = 2, - AUXTIN = 3, - SMBUSMASTER_0 = 4, - SMBUSMASTER_1 = 5, - SMBUSMASTER_2 = 6, - SMBUSMASTER_3 = 7, - SMBUSMASTER_4 = 8, - SMBUSMASTER_5 = 9, - SMBUSMASTER_6 = 10, - SMBUSMASTER_7 = 11, - PECI_0 = 12, - PECI_1 = 13, - PCH_CHIP_CPU_MAX_TEMP = 14, - PCH_CHIP_TEMP = 15, - PCH_CPU_TEMP = 16, - PCH_MCH_TEMP = 17, - PCH_DIM0_TEMP = 18, - PCH_DIM1_TEMP = 19, - PCH_DIM2_TEMP = 20, - PCH_DIM3_TEMP = 21, - BYTE_TEMP = 22 - } - - public NCT610X(Chip chip, byte revision, ushort port) - { - this.chip = chip; - this.revision = revision; - this.port = port; - - this.isNuvotonVendor = IsNuvotonVendor(); - - if (!isNuvotonVendor) - return; - - fans = new float?[3]; - controls = new float?[3]; - - fanRpmBaseRegister = 0x030; - - // min value RPM value with 13-bit fan counter - minFanRPM = (int)(1.35e6 / 0x1FFF); - - voltages = new float?[15]; - voltageRegisters = new ushort?[] - { 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, null, 0x307, 0x308, - 0x309, null, null, null, null, null }; - voltageVBatRegister = 0x308; - - temperatures = new float?[4]; - temperaturesSource = new byte[] { - (byte)SourceNCT610X.PECI_0, - (byte)SourceNCT610X.SYSTIN, - (byte)SourceNCT610X.CPUTIN, - (byte)SourceNCT610X.AUXTIN - }; - - temperatureRegister = new ushort[] - { 0x027, 0x018, 0x019, 0x01A }; - temperatureHalfRegister = new ushort[] - { 0, 0x01B, 0x11B, 0x21B }; - temperatureHalfBit = new int[] - { -1, 7, 7, 7 }; - temperatureSourceRegister = new ushort[] - { 0x621, 0x100, 0x200, 0x300 }; - - alternateTemperatureRegister = new ushort?[] - {null, 0x018, 0x019, 0x01A }; - } - - private bool IsNuvotonVendor() { - return ((ReadByte(VENDOR_ID_HIGH_REGISTER) << 8) | - ReadByte(VENDOR_ID_LOW_REGISTER)) == NUVOTON_VENDOR_ID; - } - - public byte? ReadGPIO(int index) { - return null; - } - - public void WriteGPIO(int index, byte value) { } - - private void SaveDefaultFanControl(int index) { - if (!restoreDefaultFanControlRequired[index]) { - initialFanControlMode[index] = ReadByte(FAN_CONTROL_MODE_REG[index]); - initialFanPwmCommand[index] = ReadByte(FAN_PWM_COMMAND_REG[index]); - restoreDefaultFanControlRequired[index] = true; - } - } - - private void RestoreDefaultFanControl(int index) { - if (restoreDefaultFanControlRequired[index]) { - WriteByte(FAN_CONTROL_MODE_REG[index], initialFanControlMode[index]); - WriteByte(FAN_PWM_COMMAND_REG[index], initialFanPwmCommand[index]); - restoreDefaultFanControlRequired[index] = false; - } - } - - public void SetControl(int index, byte? value) { - if (!isNuvotonVendor) - return; - - if (index < 0 || index >= controls.Length) - throw new ArgumentOutOfRangeException("index"); - - if (!Ring0.WaitIsaBusMutex(10)) - return; - - if (value.HasValue) { - SaveDefaultFanControl(index); - - // set manual mode - WriteByte(FAN_CONTROL_MODE_REG[index], 0); - - // set output value - WriteByte(FAN_PWM_COMMAND_REG[index], value.Value); - } else { - RestoreDefaultFanControl(index); - } - - Ring0.ReleaseIsaBusMutex(); - } - - public Chip Chip { get { return chip; } } - public float?[] Voltages { get { return voltages; } } - public float?[] Temperatures { get { return temperatures; } } - public float?[] Fans { get { return fans; } } - public float?[] Controls { get { return controls; } } - - public void Update() { - if (!isNuvotonVendor) - return; - - if (!Ring0.WaitIsaBusMutex(10)) - return; - - for (int i = 0; i < voltages.Length; i++) { - if (!voltageRegisters[i].HasValue) - continue; - - float value = 0.008f * ReadByte(voltageRegisters[i].Value); - bool valid = value > 0; - - // check if battery voltage monitor is enabled - if (valid && voltageRegisters[i] == voltageVBatRegister) - valid = (ReadByte(0x0318) & 0x01) > 0; - - voltages[i] = valid ? value : (float?)null; - } - - int temperatureSourceMask = 0; - for (int i = temperatureRegister.Length - 1; i >= 0 ; i--) { - int value = ((sbyte)ReadByte(temperatureRegister[i])) << 1; - if (temperatureHalfBit[i] > 0) { - value |= ((ReadByte(temperatureHalfRegister[i]) >> - temperatureHalfBit[i]) & 0x1); - } - - byte source = ReadByte(temperatureSourceRegister[i]); - temperatureSourceMask |= 1 << source; - - float? temperature = 0.5f * value; - if (temperature > 125 || temperature < -55) - temperature = null; - - for (int j = 0; j < temperatures.Length; j++) - if (temperaturesSource[j] == source) - temperatures[j] = temperature; - } - for (int i = 0; i < alternateTemperatureRegister.Length; i++) { - if (!alternateTemperatureRegister[i].HasValue) - continue; - - if ((temperatureSourceMask & (1 << temperaturesSource[i])) > 0) - continue; - - float? temperature = (sbyte) - ReadByte(alternateTemperatureRegister[i].Value); - - if (temperature > 125 || temperature < -55) - temperature = null; - - temperatures[i] = temperature; - } - - for (int i = 0; i < fans.Length; i++) { - byte high = ReadByte((ushort)(fanRpmBaseRegister + (i << 1))); - byte low = ReadByte((ushort)(fanRpmBaseRegister + (i << 1) + 1)); - int value = (high << 8) | low; - - fans[i] = value > minFanRPM ? value : 0; - } - - for (int i = 0; i < controls.Length; i++) { - int value = ReadByte(FAN_PWM_OUT_REG[i]); - controls[i] = value / 2.55f; - } - - Ring0.ReleaseIsaBusMutex(); - } - - public string GetReport() { - StringBuilder r = new StringBuilder(); - - r.AppendLine("LPC " + this.GetType().Name); - r.AppendLine(); - r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X")); - r.Append("Chip revision: 0x"); - r.AppendLine(revision.ToString("X", CultureInfo.InvariantCulture)); - r.Append("Base Adress: 0x"); - r.AppendLine(port.ToString("X4", CultureInfo.InvariantCulture)); - r.AppendLine(); - - if (!Ring0.WaitIsaBusMutex(100)) - return r.ToString(); - - Ring0.ReleaseIsaBusMutex(); - - return r.ToString(); - } - } -} diff --git a/Hardware/LPC/NCT677X.cs b/Hardware/LPC/NCT677X.cs index 4c63ed8..6bd1553 100644 --- a/Hardware/LPC/NCT677X.cs +++ b/Hardware/LPC/NCT677X.cs @@ -4,8 +4,9 @@ License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - Copyright (C) 2010-2013 Michael Möller - + Copyright (C) 2010-2015 Michael Möller + Copyright (C) 2015 Dawid Gan + * */ using System; @@ -54,15 +55,12 @@ namespace OpenHardwareMonitor.Hardware.LPC { private const ushort NUVOTON_VENDOR_ID = 0x5CA3; // Hardware Monitor Registers - private const ushort VENDOR_ID_HIGH_REGISTER = 0x804F; - private const ushort VENDOR_ID_LOW_REGISTER = 0x004F; + private readonly ushort VENDOR_ID_HIGH_REGISTER = 0x804F; + private readonly ushort VENDOR_ID_LOW_REGISTER = 0x004F; - private readonly ushort[] FAN_PWM_OUT_REG = - { 0x001, 0x003, 0x011, 0x013, 0x015, 0x017 }; - private readonly ushort[] FAN_PWM_COMMAND_REG = - { 0x109, 0x209, 0x309, 0x809, 0x909, 0xA09 }; - private readonly ushort[] FAN_CONTROL_MODE_REG = - { 0x102, 0x202, 0x302, 0x802, 0x902, 0xA02 }; + private readonly ushort[] FAN_PWM_OUT_REG; + private readonly ushort[] FAN_PWM_COMMAND_REG; + private readonly ushort[] FAN_CONTROL_MODE_REG; private readonly ushort fanRpmBaseRegister; private readonly int minFanRPM; @@ -73,6 +71,7 @@ namespace OpenHardwareMonitor.Hardware.LPC { private readonly ushort[] voltageRegisters; private readonly ushort voltageVBatRegister; + private readonly ushort vBatMonitorControlRegister; private readonly byte[] temperaturesSource; @@ -159,6 +158,31 @@ namespace OpenHardwareMonitor.Hardware.LPC { BYTE_TEMP = 26 } + private enum SourceNCT610X : byte { + SYSTIN = 1, + CPUTIN = 2, + AUXTIN = 3, + SMBUSMASTER_0 = 4, + SMBUSMASTER_1 = 5, + SMBUSMASTER_2 = 6, + SMBUSMASTER_3 = 7, + SMBUSMASTER_4 = 8, + SMBUSMASTER_5 = 9, + SMBUSMASTER_6 = 10, + SMBUSMASTER_7 = 11, + PECI_0 = 12, + PECI_1 = 13, + PCH_CHIP_CPU_MAX_TEMP = 14, + PCH_CHIP_TEMP = 15, + PCH_CPU_TEMP = 16, + PCH_MCH_TEMP = 17, + PCH_DIM0_TEMP = 18, + PCH_DIM1_TEMP = 19, + PCH_DIM2_TEMP = 20, + PCH_DIM3_TEMP = 21, + BYTE_TEMP = 22 + } + public NCT677X(Chip chip, byte revision, ushort port) { this.chip = chip; this.revision = revision; @@ -170,6 +194,29 @@ namespace OpenHardwareMonitor.Hardware.LPC { if (!isNuvotonVendor) return; + if (chip == LPC.Chip.NCT610X) { + VENDOR_ID_HIGH_REGISTER = 0x80FE; + VENDOR_ID_LOW_REGISTER = 0x00FE; + + FAN_PWM_OUT_REG = new ushort[] { 0x04A, 0x04B, 0x04C }; + FAN_PWM_COMMAND_REG = new ushort[] { 0x119, 0x129, 0x139 }; + FAN_CONTROL_MODE_REG = new ushort[] { 0x113, 0x123, 0x133 }; + + vBatMonitorControlRegister = 0x0318; + } else { + VENDOR_ID_HIGH_REGISTER = 0x804F; + VENDOR_ID_LOW_REGISTER = 0x004F; + + FAN_PWM_OUT_REG = new ushort[] { + 0x001, 0x003, 0x011, 0x013, 0x015, 0x017 }; + FAN_PWM_COMMAND_REG = new ushort[] { + 0x109, 0x209, 0x309, 0x809, 0x909, 0xA09 }; + FAN_CONTROL_MODE_REG = new ushort[] { + 0x102, 0x202, 0x302, 0x802, 0x902, 0xA02 }; + + vBatMonitorControlRegister = 0x005D; + } + switch (chip) { case Chip.NCT6771F: case Chip.NCT6776F: @@ -266,6 +313,42 @@ namespace OpenHardwareMonitor.Hardware.LPC { {null, 0x491, 0x490, 0x492, 0x493, 0x494, 0x495 }; break; + case Chip.NCT610X: + + fans = new float?[3]; + controls = new float?[3]; + + fanRpmBaseRegister = 0x030; + + // min value RPM value with 13-bit fan counter + minFanRPM = (int)(1.35e6 / 0x1FFF); + + voltages = new float?[9]; + voltageRegisters = new ushort[] + { 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x307, 0x308, 0x309 }; + voltageVBatRegister = 0x308; + + temperatures = new float?[4]; + temperaturesSource = new byte[] { + (byte)SourceNCT610X.PECI_0, + (byte)SourceNCT610X.SYSTIN, + (byte)SourceNCT610X.CPUTIN, + (byte)SourceNCT610X.AUXTIN + }; + + temperatureRegister = new ushort[] + { 0x027, 0x018, 0x019, 0x01A }; + temperatureHalfRegister = new ushort[] + { 0, 0x01B, 0x11B, 0x21B }; + temperatureHalfBit = new int[] + { -1, 7, 7, 7 }; + temperatureSourceRegister = new ushort[] + { 0x621, 0x100, 0x200, 0x300 }; + + alternateTemperatureRegister = new ushort?[] + {null, 0x018, 0x019, 0x01A }; + + break; } } @@ -341,7 +424,7 @@ namespace OpenHardwareMonitor.Hardware.LPC { // check if battery voltage monitor is enabled if (valid && voltageRegisters[i] == voltageVBatRegister) - valid = (ReadByte(0x005D) & 0x01) > 0; + valid = (ReadByte(vBatMonitorControlRegister) & 0x01) > 0; voltages[i] = valid ? value : (float?)null; } @@ -413,9 +496,9 @@ namespace OpenHardwareMonitor.Hardware.LPC { return r.ToString(); ushort[] addresses = new ushort[] { - 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, + 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x0F0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, - 0x200, 0x220, 0x230, 0x240, 0x250, 0x260, + 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x300, 0x320, 0x330, 0x340, 0x360, 0x400, 0x410, 0x420, 0x440, 0x450, 0x460, 0x480, 0x490, 0x4B0, 0x4C0, 0x4F0, @@ -430,7 +513,7 @@ namespace OpenHardwareMonitor.Hardware.LPC { 0xD00, 0xD10, 0xD20, 0xD30, 0xD50, 0xD60, 0xE00, 0xE10, 0xE20, 0xE30, 0xF00, 0xF10, 0xF20, 0xF30, - 0x8040}; + 0x8040, 0x80F0}; r.AppendLine("Hardware Monitor Registers"); r.AppendLine(); diff --git a/OpenHardwareMonitorLib.csproj b/OpenHardwareMonitorLib.csproj index 0db4c68..8673f7a 100644 --- a/OpenHardwareMonitorLib.csproj +++ b/OpenHardwareMonitorLib.csproj @@ -140,7 +140,6 @@ -