Added experimental support for Nuvoton NCT6779D super I/O chips.
authormoel.mich
Sun, 01 Jul 2012 21:44:07 +0000
changeset 35517dbf781401e
parent 354 e71b968c04f9
child 356 e471b1c2b1a6
Added experimental support for Nuvoton NCT6779D super I/O chips.
Hardware/LPC/Chip.cs
Hardware/LPC/LPCIO.cs
Hardware/LPC/NCT677X.cs
Properties/AssemblyVersion.cs
     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