Hardware/Mainboard/SuperIOHardware.cs
author moel.mich
Thu, 16 Feb 2012 22:10:30 +0000
changeset 341 5172a92c5c20
parent 337 10283dd68bbb
child 344 3145aadca3d2
permissions -rw-r--r--
Added experimental support for ITE IT8771E super I/O chips.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2012
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.Globalization;
    41 using System.Threading;
    42 using OpenHardwareMonitor.Hardware.LPC;
    43 
    44 namespace OpenHardwareMonitor.Hardware.Mainboard {
    45   internal class SuperIOHardware : Hardware {
    46 
    47     private readonly Mainboard mainboard;
    48     private readonly ISuperIO superIO;
    49 
    50     private readonly List<Sensor> voltages = new List<Sensor>();
    51     private readonly List<Sensor> temperatures = new List<Sensor>();
    52     private readonly List<Sensor> fans = new List<Sensor>();
    53     private readonly List<Sensor> controls = new List<Sensor>();
    54 
    55     private delegate float? ReadValueDelegate(int index);
    56     private delegate void UpdateDelegate();
    57 
    58     // delegates for mainboard specific sensor reading code
    59     private readonly ReadValueDelegate readVoltage;
    60     private readonly ReadValueDelegate readTemperature;
    61     private readonly ReadValueDelegate readFan;
    62     private readonly ReadValueDelegate readControl;
    63 
    64     // delegate for post update mainboard specific code
    65     private readonly UpdateDelegate postUpdate;
    66 
    67     // mainboard specific mutex
    68     private readonly Mutex mutex;
    69 
    70     public SuperIOHardware(Mainboard mainboard, ISuperIO superIO, 
    71       Manufacturer manufacturer, Model model, ISettings settings) 
    72       : base(ChipName.GetName(superIO.Chip), new Identifier("lpc", 
    73         superIO.Chip.ToString().ToLower(CultureInfo.InvariantCulture)), 
    74         settings)
    75     {
    76       this.mainboard = mainboard;
    77       this.superIO = superIO;
    78 
    79       this.readVoltage = (index) => superIO.Voltages[index];
    80       this.readTemperature = (index) => superIO.Temperatures[index];
    81       this.readFan = (index) => superIO.Fans[index];
    82       this.readControl = (index) => superIO.Controls[index];
    83 
    84       this.postUpdate = () => { };
    85 
    86       List<Voltage> v = new List<Voltage>();
    87       List<Temperature> t = new List<Temperature>();
    88       List<Fan> f = new List<Fan>();
    89       List<Ctrl> c = new List<Ctrl>();
    90 
    91       switch (superIO.Chip) {
    92         case Chip.IT8712F:
    93         case Chip.IT8716F:
    94         case Chip.IT8718F:
    95         case Chip.IT8720F: 
    96         case Chip.IT8726F:        
    97           switch (manufacturer) {
    98             case Manufacturer.ASUS:
    99               switch (model) {
   100                 case Model.Crosshair_III_Formula: // IT8720F
   101                   v.Add(new Voltage("VBat", 8));
   102                   t.Add(new Temperature("CPU", 0));
   103                   for (int i = 0; i < superIO.Fans.Length; i++)
   104                     f.Add(new Fan("Fan #" + (i + 1), i));
   105                   break;
   106                 case Model.M2N_SLI_DELUXE:                
   107                   v.Add(new Voltage("CPU VCore", 0));
   108                   v.Add(new Voltage("+3.3V", 1));
   109                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   110                   v.Add(new Voltage("+12V", 4, 30, 10));
   111                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   112                   v.Add(new Voltage("VBat", 8));
   113                   t.Add(new Temperature("CPU", 0));
   114                   t.Add(new Temperature("Motherboard", 1));
   115                   f.Add(new Fan("CPU Fan", 0));
   116                   f.Add(new Fan("Chassis Fan #1", 1));
   117                   f.Add(new Fan("Power Fan", 2));
   118                   break;
   119                 case Model.M4A79XTD_EVO: // IT8720F           
   120                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   121                   v.Add(new Voltage("VBat", 8));
   122                   t.Add(new Temperature("CPU", 0));
   123                   t.Add(new Temperature("Motherboard", 1));
   124                   f.Add(new Fan("CPU Fan", 0));
   125                   f.Add(new Fan("Chassis Fan #1", 1));
   126                   f.Add(new Fan("Chassis Fan #2", 2));
   127                   break;
   128                 default:
   129                   v.Add(new Voltage("CPU VCore", 0));
   130                   v.Add(new Voltage("Voltage #2", 1, true));
   131                   v.Add(new Voltage("Voltage #3", 2, true));
   132                   v.Add(new Voltage("Voltage #4", 3, true));
   133                   v.Add(new Voltage("Voltage #5", 4, true));
   134                   v.Add(new Voltage("Voltage #6", 5, true));
   135                   v.Add(new Voltage("Voltage #7", 6, true));
   136                   v.Add(new Voltage("Voltage #8", 7, true));
   137                   v.Add(new Voltage("VBat", 8));
   138                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   139                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   140                   for (int i = 0; i < superIO.Fans.Length; i++)
   141                     f.Add(new Fan("Fan #" + (i + 1), i));
   142                   break;
   143               }
   144               break;
   145 
   146             case Manufacturer.ASRock:
   147               switch (model) {
   148                 case Model.P55_Deluxe: // IT8720F
   149                   
   150                   v.Add(new Voltage("CPU VCore", 0));
   151                   v.Add(new Voltage("+3.3V", 2));
   152                   v.Add(new Voltage("+12V", 4, 30, 10));
   153                   v.Add(new Voltage("+5V", 5, 6.8f, 10));
   154                   v.Add(new Voltage("VBat", 8));                  
   155                   t.Add(new Temperature("CPU", 0));
   156                   t.Add(new Temperature("Motherboard", 1));
   157                   f.Add(new Fan("CPU Fan", 0));
   158                   f.Add(new Fan("Chassis Fan #1", 1));
   159 
   160                   // this mutex is also used by the official ASRock tool
   161                   mutex = new Mutex(false, "ASRockOCMark");
   162                   
   163                   bool exclusiveAccess = false;
   164                   try {
   165                     exclusiveAccess = mutex.WaitOne(10, false);
   166                   } catch (AbandonedMutexException) { } 
   167                     catch (InvalidOperationException) { }  
   168 
   169                   // only read additional fans if we get exclusive access
   170                   if (exclusiveAccess) {
   171 
   172                     f.Add(new Fan("Chassis Fan #2", 2));
   173                     f.Add(new Fan("Chassis Fan #3", 3));
   174                     f.Add(new Fan("Power Fan", 4));
   175 
   176                     readFan = (index) => {
   177                       if (index < 2) {
   178                         return superIO.Fans[index];
   179                       } else {
   180                         // get GPIO 80-87
   181                         byte? gpio = superIO.ReadGPIO(7);
   182                         if (!gpio.HasValue)
   183                           return null;
   184 
   185                         // read the last 3 fans based on GPIO 83-85
   186                         int[] masks = { 0x05, 0x03, 0x06 };
   187                         return (((gpio.Value >> 3) & 0x07) ==
   188                           masks[index - 2]) ? superIO.Fans[2] : null;
   189                       }
   190                     };
   191 
   192                     int fanIndex = 0;
   193                     postUpdate = () => {
   194                       // get GPIO 80-87
   195                       byte? gpio = superIO.ReadGPIO(7);
   196                       if (!gpio.HasValue)
   197                         return;
   198 
   199                       // prepare the GPIO 83-85 for the next update
   200                       int[] masks = { 0x05, 0x03, 0x06 };
   201                       superIO.WriteGPIO(7,
   202                         (byte)((gpio.Value & 0xC7) | (masks[fanIndex] << 3)));
   203                       fanIndex = (fanIndex + 1) % 3;
   204                     };
   205                   }
   206 
   207                   break;
   208                 default:
   209                   v.Add(new Voltage("CPU VCore", 0));
   210                   v.Add(new Voltage("Voltage #2", 1, true));
   211                   v.Add(new Voltage("Voltage #3", 2, true));
   212                   v.Add(new Voltage("Voltage #4", 3, true));
   213                   v.Add(new Voltage("Voltage #5", 4, true));
   214                   v.Add(new Voltage("Voltage #6", 5, true));
   215                   v.Add(new Voltage("Voltage #7", 6, true));
   216                   v.Add(new Voltage("Voltage #8", 7, true));
   217                   v.Add(new Voltage("VBat", 8));
   218                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   219                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   220                   for (int i = 0; i < superIO.Fans.Length; i++)
   221                     f.Add(new Fan("Fan #" + (i + 1), i));
   222                   break;
   223               };
   224               break;
   225 
   226             case Manufacturer.DFI:
   227               switch (model) {
   228                 case Model.LP_BI_P45_T2RS_Elite: // IT8718F
   229                   v.Add(new Voltage("CPU VCore", 0));
   230                   v.Add(new Voltage("FSB VTT", 1));
   231                   v.Add(new Voltage("+3.3V", 2));
   232                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   233                   v.Add(new Voltage("+12V", 4, 30, 10));
   234                   v.Add(new Voltage("NB Core", 5));
   235                   v.Add(new Voltage("VDIMM", 6));
   236                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   237                   v.Add(new Voltage("VBat", 8));
   238                   t.Add(new Temperature("CPU", 0));
   239                   t.Add(new Temperature("System", 1));
   240                   t.Add(new Temperature("Chipset", 2));
   241                   f.Add(new Fan("Fan #1", 0));
   242                   f.Add(new Fan("Fan #2", 1));
   243                   f.Add(new Fan("Fan #3", 2));
   244                   break;
   245                 case Model.LP_DK_P55_T3eH9: // IT8720F
   246                   v.Add(new Voltage("CPU VCore", 0));
   247                   v.Add(new Voltage("VTT", 1));
   248                   v.Add(new Voltage("+3.3V", 2));
   249                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   250                   v.Add(new Voltage("+12V", 4, 30, 10));
   251                   v.Add(new Voltage("CPU PLL", 5));
   252                   v.Add(new Voltage("DRAM", 6));
   253                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10));
   254                   v.Add(new Voltage("VBat", 8));
   255                   t.Add(new Temperature("Chipset", 0));
   256                   t.Add(new Temperature("CPU PWM", 1));
   257                   t.Add(new Temperature("CPU", 2));
   258                   f.Add(new Fan("Fan #1", 0));
   259                   f.Add(new Fan("Fan #2", 1));
   260                   f.Add(new Fan("Fan #3", 2));
   261                   break;
   262                 default:
   263                   v.Add(new Voltage("CPU VCore", 0));
   264                   v.Add(new Voltage("VTT", 1, true));
   265                   v.Add(new Voltage("+3.3V", 2, true));
   266                   v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   267                   v.Add(new Voltage("+12V", 4, 30, 10, 0, true));
   268                   v.Add(new Voltage("Voltage #6", 5, true));
   269                   v.Add(new Voltage("DRAM", 6, true));
   270                   v.Add(new Voltage("+5VSB", 7, 6.8f, 10, 0, true));
   271                   v.Add(new Voltage("VBat", 8));
   272                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   273                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   274                   for (int i = 0; i < superIO.Fans.Length; i++)
   275                     f.Add(new Fan("Fan #" + (i + 1), i));
   276                   break;
   277               }
   278               break;
   279 
   280             case Manufacturer.Gigabyte:
   281               switch (model) {
   282                 case Model._965P_S3: // IT8718F
   283                   v.Add(new Voltage("CPU VCore", 0));
   284                   v.Add(new Voltage("DRAM", 1));
   285                   v.Add(new Voltage("+3.3V", 2));
   286                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   287                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   288                   v.Add(new Voltage("VBat", 8));
   289                   t.Add(new Temperature("System", 0));
   290                   t.Add(new Temperature("CPU", 1));
   291                   f.Add(new Fan("CPU Fan", 0));
   292                   f.Add(new Fan("System Fan", 1));
   293                   break;
   294                 case Model.EP45_DS3R: // IT8718F
   295                 case Model.EP45_UD3R: 
   296                 case Model.X38_DS5:    
   297                   v.Add(new Voltage("CPU VCore", 0));
   298                   v.Add(new Voltage("DRAM", 1));
   299                   v.Add(new Voltage("+3.3V", 2));
   300                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   301                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   302                   v.Add(new Voltage("VBat", 8));
   303                   t.Add(new Temperature("System", 0));
   304                   t.Add(new Temperature("CPU", 1));
   305                   f.Add(new Fan("CPU Fan", 0));
   306                   f.Add(new Fan("System Fan #2", 1));
   307                   f.Add(new Fan("Power Fan", 2));
   308                   f.Add(new Fan("System Fan #1", 3));
   309                   break;
   310                 case Model.EX58_EXTREME: // IT8720F 
   311                   v.Add(new Voltage("CPU VCore", 0));
   312                   v.Add(new Voltage("DRAM", 1));
   313                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   314                   v.Add(new Voltage("VBat", 8));
   315                   t.Add(new Temperature("System", 0));
   316                   t.Add(new Temperature("CPU", 1));
   317                   t.Add(new Temperature("Northbridge", 2));
   318                   f.Add(new Fan("CPU Fan", 0));
   319                   f.Add(new Fan("System Fan #2", 1));
   320                   f.Add(new Fan("Power Fan", 2));
   321                   f.Add(new Fan("System Fan #1", 3));
   322                   break;
   323                 case Model.P35_DS3: // IT8718F 
   324                 case Model.P35_DS3L: // IT8718F
   325                   v.Add(new Voltage("CPU VCore", 0));
   326                   v.Add(new Voltage("DRAM", 1));
   327                   v.Add(new Voltage("+3.3V", 2));
   328                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   329                   v.Add(new Voltage("+12V", 7, 27, 9.1f));
   330                   v.Add(new Voltage("VBat", 8));
   331                   t.Add(new Temperature("System", 0));
   332                   t.Add(new Temperature("CPU", 1));
   333                   f.Add(new Fan("CPU Fan", 0));
   334                   f.Add(new Fan("System Fan #1", 1));
   335                   f.Add(new Fan("System Fan #2", 2));
   336                   f.Add(new Fan("Power Fan", 3));
   337                   break;
   338                 case Model.P55_UD4: // IT8720F
   339                 case Model.P55M_UD4: // IT8720F
   340                   v.Add(new Voltage("CPU VCore", 0));
   341                   v.Add(new Voltage("DRAM", 1));
   342                   v.Add(new Voltage("+3.3V", 2));
   343                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   344                   v.Add(new Voltage("+12V", 5, 27, 9.1f));
   345                   v.Add(new Voltage("VBat", 8));
   346                   t.Add(new Temperature("System", 0));
   347                   t.Add(new Temperature("CPU", 2));
   348                   f.Add(new Fan("CPU Fan", 0));
   349                   f.Add(new Fan("System Fan #2", 1));
   350                   f.Add(new Fan("Power Fan", 2));
   351                   f.Add(new Fan("System Fan #1", 3));
   352                   break;
   353                 case Model.GA_MA770T_UD3: // IT8720F
   354                   v.Add(new Voltage("CPU VCore", 0));
   355                   v.Add(new Voltage("DRAM", 1));
   356                   v.Add(new Voltage("+3.3V", 2));
   357                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   358                   v.Add(new Voltage("+12V", 4, 27, 9.1f));
   359                   v.Add(new Voltage("VBat", 8));
   360                   t.Add(new Temperature("System", 0));
   361                   t.Add(new Temperature("CPU", 1));
   362                   f.Add(new Fan("CPU Fan", 0));
   363                   f.Add(new Fan("System Fan #1", 1));
   364                   f.Add(new Fan("System Fan #2", 2));
   365                   f.Add(new Fan("Power Fan", 3));
   366                   break;
   367                 case Model.GA_MA785GMT_UD2H: // IT8718F
   368                   v.Add(new Voltage("CPU VCore", 0));
   369                   v.Add(new Voltage("DRAM", 1));
   370                   v.Add(new Voltage("+3.3V", 2));
   371                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   372                   v.Add(new Voltage("+12V", 4, 27, 9.1f));
   373                   v.Add(new Voltage("VBat", 8));
   374                   t.Add(new Temperature("System", 0));
   375                   t.Add(new Temperature("CPU", 1));
   376                   f.Add(new Fan("CPU Fan", 0));
   377                   f.Add(new Fan("System Fan", 1));
   378                   f.Add(new Fan("NB Fan", 2));
   379                   break;
   380                 case Model.X58A_UD3R: // IT8720F 
   381                   v.Add(new Voltage("CPU VCore", 0));
   382                   v.Add(new Voltage("DRAM", 1));
   383                   v.Add(new Voltage("+3.3V", 2));
   384                   v.Add(new Voltage("+5V", 3, 6.8f, 10));
   385                   v.Add(new Voltage("+12V", 5, 27, 9.1f));
   386                   v.Add(new Voltage("VBat", 8));
   387                   t.Add(new Temperature("System", 0));
   388                   t.Add(new Temperature("CPU", 1));
   389                   t.Add(new Temperature("Northbridge", 2));
   390                   f.Add(new Fan("CPU Fan", 0));
   391                   f.Add(new Fan("System Fan #2", 1));
   392                   f.Add(new Fan("Power Fan", 2));
   393                   f.Add(new Fan("System Fan #1", 3));
   394                   break;
   395                 default:
   396                   v.Add(new Voltage("CPU VCore", 0));
   397                   v.Add(new Voltage("DRAM", 1, true));
   398                   v.Add(new Voltage("+3.3V", 2, true));
   399                   v.Add(new Voltage("+5V", 3, 6.8f, 10, 0, true));
   400                   v.Add(new Voltage("Voltage #5", 4, true));
   401                   v.Add(new Voltage("Voltage #6", 5, true));
   402                   v.Add(new Voltage("Voltage #7", 6, true));
   403                   v.Add(new Voltage("Voltage #8", 7, true));
   404                   v.Add(new Voltage("VBat", 8));
   405                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   406                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   407                   for (int i = 0; i < superIO.Fans.Length; i++)
   408                     f.Add(new Fan("Fan #" + (i + 1), i));
   409                   break;
   410               }
   411               break;
   412 
   413             default:
   414               v.Add(new Voltage("CPU VCore", 0));
   415               v.Add(new Voltage("Voltage #2", 1, true));
   416               v.Add(new Voltage("Voltage #3", 2, true));
   417               v.Add(new Voltage("Voltage #4", 3, true));
   418               v.Add(new Voltage("Voltage #5", 4, true));
   419               v.Add(new Voltage("Voltage #6", 5, true));
   420               v.Add(new Voltage("Voltage #7", 6, true));
   421               v.Add(new Voltage("Voltage #8", 7, true));
   422               v.Add(new Voltage("VBat", 8));
   423               for (int i = 0; i < superIO.Temperatures.Length; i++)
   424                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   425               for (int i = 0; i < superIO.Fans.Length; i++)
   426                 f.Add(new Fan("Fan #" + (i + 1), i));
   427               break;
   428           }
   429           break;
   430 
   431         case Chip.IT8721F:
   432         case Chip.IT8728F:
   433         case Chip.IT8771E:
   434         case Chip.IT8772E:
   435           switch (manufacturer) {
   436             case Manufacturer.ECS:
   437               switch (model) {
   438                 case Model.A890GXM_A: // IT8721F
   439                   v.Add(new Voltage("CPU VCore", 0));
   440                   v.Add(new Voltage("VDIMM", 1));
   441                   v.Add(new Voltage("NB Voltage", 2));
   442                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10));
   443                   // v.Add(new Voltage("VDIMM", 6, true));
   444                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   445                   v.Add(new Voltage("VBat", 8, 10, 10));
   446                   t.Add(new Temperature("CPU", 0));
   447                   t.Add(new Temperature("System", 1));
   448                   t.Add(new Temperature("Northbridge", 2));
   449                   f.Add(new Fan("CPU Fan", 0));
   450                   f.Add(new Fan("System Fan", 1));
   451                   f.Add(new Fan("Power Fan", 2));
   452                   break;
   453                 default:
   454                   v.Add(new Voltage("Voltage #1", 0, true));
   455                   v.Add(new Voltage("Voltage #2", 1, true));
   456                   v.Add(new Voltage("Voltage #3", 2, true));
   457                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   458                   v.Add(new Voltage("Voltage #5", 4, true));
   459                   v.Add(new Voltage("Voltage #6", 5, true));
   460                   v.Add(new Voltage("Voltage #7", 6, true));
   461                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   462                   v.Add(new Voltage("VBat", 8, 10, 10));
   463                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   464                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   465                   for (int i = 0; i < superIO.Fans.Length; i++)
   466                     f.Add(new Fan("Fan #" + (i + 1), i));
   467                   break;
   468               }
   469               break;
   470             case Manufacturer.Gigabyte:
   471               switch (model) {
   472                 case Model.P67A_UD4_B3: // IT8728F
   473                   v.Add(new Voltage("+12V", 0, 100, 10));
   474                   v.Add(new Voltage("+5V", 1, 15, 10));
   475                   v.Add(new Voltage("Voltage #3", 2, true));
   476                   v.Add(new Voltage("Voltage #4", 3, true));
   477                   v.Add(new Voltage("Voltage #5", 4, true));
   478                   v.Add(new Voltage("CPU VCore", 5));
   479                   v.Add(new Voltage("DRAM", 6));
   480                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   481                   v.Add(new Voltage("VBat", 8, 10, 10));
   482                   t.Add(new Temperature("System", 0));
   483                   t.Add(new Temperature("CPU", 2));
   484                   f.Add(new Fan("CPU Fan", 0));
   485                   f.Add(new Fan("System Fan #2", 1));
   486                   f.Add(new Fan("Power Fan", 2));
   487                   f.Add(new Fan("System Fan #1", 3));
   488                   break;
   489                 case Model.H67A_UD3H_B3: // IT8728F
   490                   v.Add(new Voltage("VTT", 0));
   491                   v.Add(new Voltage("+5V", 1, 15, 10));
   492                   v.Add(new Voltage("+12V", 2, 68, 22));
   493                   v.Add(new Voltage("Voltage #4", 3, true));
   494                   v.Add(new Voltage("Voltage #5", 4, true));
   495                   v.Add(new Voltage("CPU VCore", 5));
   496                   v.Add(new Voltage("DRAM", 6));
   497                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   498                   v.Add(new Voltage("VBat", 8, 10, 10));
   499                   t.Add(new Temperature("System", 0));
   500                   t.Add(new Temperature("CPU", 2));
   501                   f.Add(new Fan("CPU Fan", 0));
   502                   f.Add(new Fan("System Fan #1", 1));
   503                   f.Add(new Fan("Power Fan", 2));
   504                   f.Add(new Fan("System Fan #2", 3));
   505                   break;
   506                 case Model.Z68X_UD7_B3: // IT8728F
   507                   v.Add(new Voltage("VTT", 0));
   508                   v.Add(new Voltage("+3.3V", 1, 13.3f, 20.5f));
   509                   v.Add(new Voltage("+12V", 2, 68, 22));
   510                   v.Add(new Voltage("+5V", 3, 14.3f, 20));
   511                   v.Add(new Voltage("CPU VCore", 5));
   512                   v.Add(new Voltage("DRAM", 6));
   513                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   514                   v.Add(new Voltage("VBat", 8, 10, 10));
   515                   t.Add(new Temperature("System", 0));
   516                   t.Add(new Temperature("CPU", 1));
   517                   t.Add(new Temperature("System 3", 2));
   518                   f.Add(new Fan("CPU Fan", 0));
   519                   f.Add(new Fan("Power Fan", 1));
   520                   f.Add(new Fan("System Fan #1", 2));
   521                   f.Add(new Fan("System Fan #2", 3));
   522                   f.Add(new Fan("System Fan #3", 4));
   523                   break;
   524                 default:
   525                   v.Add(new Voltage("Voltage #1", 0, true));
   526                   v.Add(new Voltage("Voltage #2", 1, true));
   527                   v.Add(new Voltage("Voltage #3", 2, true));
   528                   v.Add(new Voltage("Voltage #4", 3, true));
   529                   v.Add(new Voltage("Voltage #5", 4, true));
   530                   v.Add(new Voltage("Voltage #6", 5, true));
   531                   v.Add(new Voltage("Voltage #7", 6, true));
   532                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   533                   v.Add(new Voltage("VBat", 8, 10, 10));
   534                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   535                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   536                   for (int i = 0; i < superIO.Fans.Length; i++)
   537                     f.Add(new Fan("Fan #" + (i + 1), i));
   538                   break;
   539               }
   540               break;
   541             case Manufacturer.Shuttle:
   542               switch (model) {
   543                 case Model.FH67: // IT8772E 
   544                   v.Add(new Voltage("CPU VCore", 0));
   545                   v.Add(new Voltage("DRAM", 1));
   546                   v.Add(new Voltage("PCH VCCIO", 2));
   547                   v.Add(new Voltage("CPU VCCIO", 3));
   548                   v.Add(new Voltage("Graphic Voltage", 4));
   549                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   550                   v.Add(new Voltage("VBat", 8, 10, 10));
   551                   t.Add(new Temperature("System", 0));
   552                   t.Add(new Temperature("CPU", 1));                  
   553                   f.Add(new Fan("Fan #1", 0));
   554                   f.Add(new Fan("CPU Fan", 1));
   555                   break;
   556                 default:
   557                   v.Add(new Voltage("Voltage #1", 0, true));
   558                   v.Add(new Voltage("Voltage #2", 1, true));
   559                   v.Add(new Voltage("Voltage #3", 2, true));
   560                   v.Add(new Voltage("Voltage #4", 3, true));
   561                   v.Add(new Voltage("Voltage #5", 4, true));
   562                   v.Add(new Voltage("Voltage #6", 5, true));
   563                   v.Add(new Voltage("Voltage #7", 6, true));
   564                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   565                   v.Add(new Voltage("VBat", 8, 10, 10));
   566                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   567                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   568                   for (int i = 0; i < superIO.Fans.Length; i++)
   569                     f.Add(new Fan("Fan #" + (i + 1), i));
   570                   break;
   571               }
   572               break;
   573             default:
   574               v.Add(new Voltage("Voltage #1", 0, true));
   575               v.Add(new Voltage("Voltage #2", 1, true));
   576               v.Add(new Voltage("Voltage #3", 2, true));
   577               v.Add(new Voltage("Voltage #4", 3, true));
   578               v.Add(new Voltage("Voltage #5", 4, true));
   579               v.Add(new Voltage("Voltage #6", 5, true));
   580               v.Add(new Voltage("Voltage #7", 6, true));
   581               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   582               v.Add(new Voltage("VBat", 8, 10, 10));
   583               for (int i = 0; i < superIO.Temperatures.Length; i++)
   584                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   585               for (int i = 0; i < superIO.Fans.Length; i++)
   586                 f.Add(new Fan("Fan #" + (i + 1), i));
   587               break;
   588           }
   589           break;
   590           
   591         case Chip.F71858:
   592           v.Add(new Voltage("VCC3V", 0, 150, 150));
   593           v.Add(new Voltage("VSB3V", 1, 150, 150));
   594           v.Add(new Voltage("Battery", 2, 150, 150));
   595           for (int i = 0; i < superIO.Temperatures.Length; i++)
   596             t.Add(new Temperature("Temperature #" + (i + 1), i));
   597           for (int i = 0; i < superIO.Fans.Length; i++)
   598             f.Add(new Fan("Fan #" + (i + 1), i));
   599           break;
   600         case Chip.F71862: 
   601         case Chip.F71869: 
   602         case Chip.F71882:
   603         case Chip.F71889AD: 
   604         case Chip.F71889ED: 
   605         case Chip.F71889F:
   606           switch (manufacturer) {
   607             case Manufacturer.EVGA:
   608               switch (model) {
   609                 case Model.X58_SLI_Classified: // F71882 
   610                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   611                   v.Add(new Voltage("CPU VCore", 1, 47, 100));
   612                   v.Add(new Voltage("DIMM", 2, 47, 100));
   613                   v.Add(new Voltage("CPU VTT", 3, 24, 100));
   614                   v.Add(new Voltage("IOH Vcore", 4, 24, 100));
   615                   v.Add(new Voltage("+5V", 5, 51, 12));
   616                   v.Add(new Voltage("+12V", 6, 56, 6.8f));
   617                   v.Add(new Voltage("3VSB", 7, 150, 150));
   618                   v.Add(new Voltage("VBat", 8, 150, 150));
   619                   t.Add(new Temperature("CPU", 0));
   620                   t.Add(new Temperature("VREG", 1));
   621                   t.Add(new Temperature("System", 2));
   622                   f.Add(new Fan("CPU Fan", 0));
   623                   f.Add(new Fan("Power Fan", 1));
   624                   f.Add(new Fan("Chassis Fan", 2));
   625                   break;
   626                 default:
   627                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   628                   v.Add(new Voltage("CPU VCore", 1));
   629                   v.Add(new Voltage("Voltage #3", 2, true));
   630                   v.Add(new Voltage("Voltage #4", 3, true));
   631                   v.Add(new Voltage("Voltage #5", 4, true));
   632                   v.Add(new Voltage("Voltage #6", 5, true));
   633                   v.Add(new Voltage("Voltage #7", 6, true));
   634                   v.Add(new Voltage("VSB3V", 7, 150, 150));
   635                   v.Add(new Voltage("VBat", 8, 150, 150));
   636                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   637                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   638                   for (int i = 0; i < superIO.Fans.Length; i++)
   639                     f.Add(new Fan("Fan #" + (i + 1), i));
   640                   break;
   641               }
   642               break;
   643             default:
   644               v.Add(new Voltage("VCC3V", 0, 150, 150));
   645               v.Add(new Voltage("CPU VCore", 1));
   646               v.Add(new Voltage("Voltage #3", 2, true));
   647               v.Add(new Voltage("Voltage #4", 3, true));
   648               v.Add(new Voltage("Voltage #5", 4, true));
   649               v.Add(new Voltage("Voltage #6", 5, true));
   650               v.Add(new Voltage("Voltage #7", 6, true));
   651               v.Add(new Voltage("VSB3V", 7, 150, 150));
   652               v.Add(new Voltage("VBat", 8, 150, 150));
   653               for (int i = 0; i < superIO.Temperatures.Length; i++)
   654                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   655               for (int i = 0; i < superIO.Fans.Length; i++)
   656                 f.Add(new Fan("Fan #" + (i + 1), i));
   657               break;
   658           }
   659           break;
   660 
   661         case Chip.W83627EHF:
   662           switch (manufacturer) {
   663             case Manufacturer.ASRock:
   664               switch (model) {
   665                 case Model.AOD790GX_128M: // W83627EHF
   666                   v.Add(new Voltage("CPU VCore", 0));
   667                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   668                   v.Add(new Voltage("+3.3V", 4, 10, 10));
   669                   v.Add(new Voltage("+5V", 5, 20, 10));
   670                   v.Add(new Voltage("+12V", 6, 28, 5));
   671                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   672                   v.Add(new Voltage("VBAT", 8, 34, 34));
   673                   t.Add(new Temperature("CPU", 0));
   674                   t.Add(new Temperature("Motherboard", 2));
   675                   f.Add(new Fan("CPU Fan", 0));
   676                   f.Add(new Fan("Chassis Fan", 1));                 
   677                   break;
   678                 default:
   679                   v.Add(new Voltage("CPU VCore", 0));
   680                   v.Add(new Voltage("Voltage #2", 1, true));
   681                   v.Add(new Voltage("AVCC", 2, 34, 34));
   682                   v.Add(new Voltage("3VCC", 3, 34, 34));
   683                   v.Add(new Voltage("Voltage #5", 4, true));
   684                   v.Add(new Voltage("Voltage #6", 5, true));
   685                   v.Add(new Voltage("Voltage #7", 6, true));
   686                   v.Add(new Voltage("3VSB", 7, 34, 34));
   687                   v.Add(new Voltage("VBAT", 8, 34, 34));
   688                   v.Add(new Voltage("Voltage #10", 9, true));
   689                   t.Add(new Temperature("CPU", 0));
   690                   t.Add(new Temperature("Auxiliary", 1));
   691                   t.Add(new Temperature("System", 2));
   692                   f.Add(new Fan("System Fan", 0));
   693                   f.Add(new Fan("CPU Fan", 1));
   694                   f.Add(new Fan("Auxiliary Fan", 2));
   695                   f.Add(new Fan("CPU Fan #2", 3));
   696                   f.Add(new Fan("Auxiliary Fan #2", 4));
   697                   break;
   698               } break;
   699             default:
   700               v.Add(new Voltage("CPU VCore", 0));
   701               v.Add(new Voltage("Voltage #2", 1, true));
   702               v.Add(new Voltage("AVCC", 2, 34, 34));
   703               v.Add(new Voltage("3VCC", 3, 34, 34));
   704               v.Add(new Voltage("Voltage #5", 4, true));
   705               v.Add(new Voltage("Voltage #6", 5, true));
   706               v.Add(new Voltage("Voltage #7", 6, true));
   707               v.Add(new Voltage("3VSB", 7, 34, 34));
   708               v.Add(new Voltage("VBAT", 8, 34, 34));
   709               v.Add(new Voltage("Voltage #10", 9, true));
   710               t.Add(new Temperature("CPU", 0));
   711               t.Add(new Temperature("Auxiliary", 1));
   712               t.Add(new Temperature("System", 2));
   713               f.Add(new Fan("System Fan", 0));
   714               f.Add(new Fan("CPU Fan", 1));
   715               f.Add(new Fan("Auxiliary Fan", 2));
   716               f.Add(new Fan("CPU Fan #2", 3));
   717               f.Add(new Fan("Auxiliary Fan #2", 4));
   718               break;
   719           }
   720           break;
   721         case Chip.W83627DHG: 
   722         case Chip.W83627DHGP:                      
   723         case Chip.W83667HG:
   724         case Chip.W83667HGB:
   725           switch (manufacturer) {
   726             case Manufacturer.ASRock:
   727               switch (model) {
   728                 case Model._880GMH_USB3: // W83627DHG-P
   729                   v.Add(new Voltage("CPU VCore", 0));
   730                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   731                   v.Add(new Voltage("+5V", 5, 15, 7.5f));
   732                   v.Add(new Voltage("+12V", 6, 56, 10));
   733                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   734                   v.Add(new Voltage("VBAT", 8, 34, 34));
   735                   t.Add(new Temperature("CPU", 0));
   736                   t.Add(new Temperature("Motherboard", 2));
   737                   f.Add(new Fan("Chassis Fan", 0));
   738                   f.Add(new Fan("CPU Fan", 1));
   739                   f.Add(new Fan("Power Fan", 2));
   740                   break;
   741                 default:
   742                   v.Add(new Voltage("CPU VCore", 0));
   743                   v.Add(new Voltage("Voltage #2", 1, true));
   744                   v.Add(new Voltage("AVCC", 2, 34, 34));
   745                   v.Add(new Voltage("3VCC", 3, 34, 34));
   746                   v.Add(new Voltage("Voltage #5", 4, true));
   747                   v.Add(new Voltage("Voltage #6", 5, true));
   748                   v.Add(new Voltage("Voltage #7", 6, true));
   749                   v.Add(new Voltage("3VSB", 7, 34, 34));
   750                   v.Add(new Voltage("VBAT", 8, 34, 34));
   751                   t.Add(new Temperature("CPU", 0));
   752                   t.Add(new Temperature("Auxiliary", 1));
   753                   t.Add(new Temperature("System", 2));
   754                   f.Add(new Fan("System Fan", 0));
   755                   f.Add(new Fan("CPU Fan", 1));
   756                   f.Add(new Fan("Auxiliary Fan", 2));
   757                   f.Add(new Fan("CPU Fan #2", 3));
   758                   f.Add(new Fan("Auxiliary Fan #2", 4));
   759                   break;
   760               }
   761               break;
   762             case Manufacturer.ASUS:
   763               switch (model) {
   764                 case Model.P6T: // W83667HG
   765                 case Model.P6X58D_E: // W83667HG                 
   766                 case Model.Rampage_II_GENE: // W83667HG 
   767                   v.Add(new Voltage("CPU VCore", 0));
   768                   v.Add(new Voltage("+12V", 1, 11.5f, 1.91f));
   769                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   770                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   771                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   772                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   773                   v.Add(new Voltage("VBAT", 8, 34, 34));
   774                   t.Add(new Temperature("CPU", 0));
   775                   t.Add(new Temperature("Motherboard", 2));
   776                   f.Add(new Fan("Chassis Fan #1", 0));
   777                   f.Add(new Fan("CPU Fan", 1));
   778                   f.Add(new Fan("Power Fan", 2));
   779                   f.Add(new Fan("Chassis Fan #2", 3));
   780                   f.Add(new Fan("Chassis Fan #3", 4));
   781                   break;
   782                 case Model.Rampage_Extreme: // W83667HG 
   783                   v.Add(new Voltage("CPU VCore", 0));
   784                   v.Add(new Voltage("+12V", 1, 12, 2));
   785                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   786                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   787                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   788                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   789                   v.Add(new Voltage("VBAT", 8, 34, 34));
   790                   t.Add(new Temperature("CPU", 0));
   791                   t.Add(new Temperature("Motherboard", 2));
   792                   f.Add(new Fan("Chassis Fan #1", 0));
   793                   f.Add(new Fan("CPU Fan", 1));
   794                   f.Add(new Fan("Power Fan", 2));
   795                   f.Add(new Fan("Chassis Fan #2", 3));
   796                   f.Add(new Fan("Chassis Fan #3", 4));
   797                   break;
   798                 default:
   799                   v.Add(new Voltage("CPU VCore", 0));
   800                   v.Add(new Voltage("Voltage #2", 1, true));
   801                   v.Add(new Voltage("AVCC", 2, 34, 34));
   802                   v.Add(new Voltage("3VCC", 3, 34, 34));
   803                   v.Add(new Voltage("Voltage #5", 4, true));
   804                   v.Add(new Voltage("Voltage #6", 5, true));
   805                   v.Add(new Voltage("Voltage #7", 6, true));
   806                   v.Add(new Voltage("3VSB", 7, 34, 34));
   807                   v.Add(new Voltage("VBAT", 8, 34, 34));
   808                   t.Add(new Temperature("CPU", 0));
   809                   t.Add(new Temperature("Auxiliary", 1));
   810                   t.Add(new Temperature("System", 2));
   811                   f.Add(new Fan("System Fan", 0));
   812                   f.Add(new Fan("CPU Fan", 1));
   813                   f.Add(new Fan("Auxiliary Fan", 2));
   814                   f.Add(new Fan("CPU Fan #2", 3));
   815                   f.Add(new Fan("Auxiliary Fan #2", 4));
   816                   break;
   817               }
   818               break;
   819             default:
   820               v.Add(new Voltage("CPU VCore", 0));
   821               v.Add(new Voltage("Voltage #2", 1, true));
   822               v.Add(new Voltage("AVCC", 2, 34, 34));
   823               v.Add(new Voltage("3VCC", 3, 34, 34));
   824               v.Add(new Voltage("Voltage #5", 4, true));
   825               v.Add(new Voltage("Voltage #6", 5, true));
   826               v.Add(new Voltage("Voltage #7", 6, true));
   827               v.Add(new Voltage("3VSB", 7, 34, 34));
   828               v.Add(new Voltage("VBAT", 8, 34, 34));
   829               t.Add(new Temperature("CPU", 0));
   830               t.Add(new Temperature("Auxiliary", 1));
   831               t.Add(new Temperature("System", 2));
   832               f.Add(new Fan("System Fan", 0));
   833               f.Add(new Fan("CPU Fan", 1));
   834               f.Add(new Fan("Auxiliary Fan", 2));
   835               f.Add(new Fan("CPU Fan #2", 3));
   836               f.Add(new Fan("Auxiliary Fan #2", 4));
   837               break;
   838           } 
   839           break;
   840         case Chip.W83627HF: 
   841         case Chip.W83627THF: 
   842         case Chip.W83687THF:
   843           v.Add(new Voltage("CPU VCore", 0));
   844           v.Add(new Voltage("Voltage #2", 1, true));
   845           v.Add(new Voltage("Voltage #3", 2, true));
   846           v.Add(new Voltage("AVCC", 3, 34, 51));
   847           v.Add(new Voltage("Voltage #5", 4, true));
   848           v.Add(new Voltage("5VSB", 5, 34, 51));
   849           v.Add(new Voltage("VBAT", 6));
   850           t.Add(new Temperature("CPU", 0));
   851           t.Add(new Temperature("Auxiliary", 1));
   852           t.Add(new Temperature("System", 2));
   853           f.Add(new Fan("System Fan", 0));
   854           f.Add(new Fan("CPU Fan", 1));
   855           f.Add(new Fan("Auxiliary Fan", 2));
   856           break;
   857         case Chip.NCT6771F:
   858         case Chip.NCT6776F:
   859           switch (manufacturer) {
   860             case Manufacturer.ASUS:
   861               switch (model) {
   862                 case Model.P8P67: // NCT6776F
   863                 case Model.P8P67_EVO: // NCT6776F
   864                 case Model.P8P67_PRO: // NCT6776F
   865                   v.Add(new Voltage("CPU VCore", 0));
   866                   v.Add(new Voltage("+12V", 1, 11, 1));
   867                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   868                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   869                   v.Add(new Voltage("+5V", 4, 12, 3));
   870                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   871                   v.Add(new Voltage("VBAT", 8, 34, 34));
   872                   t.Add(new Temperature("CPU", 0));
   873                   t.Add(new Temperature("Auxiliary", 2));
   874                   t.Add(new Temperature("Motherboard", 3));
   875                   f.Add(new Fan("Chassis Fan #1", 0));
   876                   f.Add(new Fan("CPU Fan", 1));
   877                   f.Add(new Fan("Power Fan", 2));
   878                   f.Add(new Fan("Chassis Fan #2", 3));
   879                   c.Add(new Ctrl("Chassis Fan #2", 0));
   880                   c.Add(new Ctrl("CPU Fan", 1));
   881                   c.Add(new Ctrl("Chassis Fan #1", 2));
   882                   break;
   883                 case Model.P8P67_M_PRO: // NCT6776F
   884                   v.Add(new Voltage("CPU VCore", 0));
   885                   v.Add(new Voltage("+12V", 1, 11, 1));
   886                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   887                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   888                   v.Add(new Voltage("+5V", 4, 12, 3));
   889                   v.Add(new Voltage("Voltage #6", 5, true));
   890                   v.Add(new Voltage("Voltage #7", 6, true));
   891                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   892                   v.Add(new Voltage("VBAT", 8, 34, 34));
   893                   t.Add(new Temperature("CPU", 0));
   894                   t.Add(new Temperature("Motherboard", 3));
   895                   f.Add(new Fan("Chassis Fan #1", 0));
   896                   f.Add(new Fan("CPU Fan", 1));
   897                   f.Add(new Fan("Chassis Fan #2", 2));
   898                   f.Add(new Fan("Power Fan", 3));
   899                   f.Add(new Fan("Auxiliary Fan", 4));
   900                   break;
   901                 case Model.P8Z68_V_PRO: // NCT6776F
   902                   v.Add(new Voltage("CPU VCore", 0));
   903                   v.Add(new Voltage("+12V", 1, 11, 1));
   904                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   905                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   906                   v.Add(new Voltage("+5V", 4, 12, 3));
   907                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   908                   v.Add(new Voltage("VBAT", 8, 34, 34));
   909                   t.Add(new Temperature("CPU", 0));
   910                   t.Add(new Temperature("Auxiliary", 2));
   911                   t.Add(new Temperature("Motherboard", 3));
   912                   for (int i = 0; i < superIO.Fans.Length; i++)
   913                     f.Add(new Fan("Fan #" + (i + 1), i));
   914                   for (int i = 0; i < superIO.Controls.Length; i++)
   915                     c.Add(new Ctrl("Fan #" + (i + 1), i));
   916                   break;
   917                 case Model.P9X79: // NCT6776F
   918                   v.Add(new Voltage("CPU VCore", 0));
   919                   v.Add(new Voltage("+12V", 1, 11, 1));
   920                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   921                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   922                   v.Add(new Voltage("+5V", 4, 12, 3));
   923                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   924                   v.Add(new Voltage("VBAT", 8, 34, 34));
   925                   t.Add(new Temperature("CPU", 0));
   926                   t.Add(new Temperature("Motherboard", 3));
   927                   for (int i = 0; i < superIO.Fans.Length; i++)
   928                     f.Add(new Fan("Fan #" + (i + 1), i));
   929                   break;
   930                 default:
   931                   v.Add(new Voltage("CPU VCore", 0));
   932                   v.Add(new Voltage("Voltage #2", 1, true));
   933                   v.Add(new Voltage("AVCC", 2, 34, 34));
   934                   v.Add(new Voltage("3VCC", 3, 34, 34));
   935                   v.Add(new Voltage("Voltage #5", 4, true));
   936                   v.Add(new Voltage("Voltage #6", 5, true));
   937                   v.Add(new Voltage("Voltage #7", 6, true));
   938                   v.Add(new Voltage("3VSB", 7, 34, 34));
   939                   v.Add(new Voltage("VBAT", 8, 34, 34));
   940                   t.Add(new Temperature("CPU", 0));
   941                   t.Add(new Temperature("CPU", 1));
   942                   t.Add(new Temperature("Auxiliary", 2));
   943                   t.Add(new Temperature("System", 3));
   944                   for (int i = 0; i < superIO.Fans.Length; i++)
   945                     f.Add(new Fan("Fan #" + (i + 1), i));
   946                   break;
   947               }
   948               break;
   949             default:
   950               v.Add(new Voltage("CPU VCore", 0));
   951               v.Add(new Voltage("Voltage #2", 1, true));
   952               v.Add(new Voltage("AVCC", 2, 34, 34));
   953               v.Add(new Voltage("3VCC", 3, 34, 34));
   954               v.Add(new Voltage("Voltage #5", 4, true));
   955               v.Add(new Voltage("Voltage #6", 5, true));
   956               v.Add(new Voltage("Voltage #7", 6, true));
   957               v.Add(new Voltage("3VSB", 7, 34, 34));
   958               v.Add(new Voltage("VBAT", 8, 34, 34));
   959               t.Add(new Temperature("CPU", 0));
   960               t.Add(new Temperature("CPU", 1));
   961               t.Add(new Temperature("Auxiliary", 2));
   962               t.Add(new Temperature("System", 3));
   963               for (int i = 0; i < superIO.Fans.Length; i++)
   964                 f.Add(new Fan("Fan #" + (i + 1), i));
   965               break;
   966           }
   967           break;
   968         default:
   969           for (int i = 0; i < superIO.Voltages.Length; i++)
   970             v.Add(new Voltage("Voltage #" + (i + 1), i, true));
   971           for (int i = 0; i < superIO.Temperatures.Length; i++)
   972             t.Add(new Temperature("Temperature #" + (i + 1), i));
   973           for (int i = 0; i < superIO.Fans.Length; i++)
   974             f.Add(new Fan("Fan #" + (i + 1), i));
   975           for (int i = 0; i < superIO.Controls.Length; i++)
   976             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   977           break;
   978       }
   979 
   980       const string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
   981       foreach (Voltage voltage in v) 
   982         if (voltage.Index < superIO.Voltages.Length) {
   983           Sensor sensor = new Sensor(voltage.Name, voltage.Index, 
   984             voltage.Hidden, SensorType.Voltage, this, new [] {
   985             new ParameterDescription("Ri [kΩ]", "Input resistance.\n" + 
   986               formula, voltage.Ri),
   987             new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" + 
   988               formula, voltage.Rf),
   989             new ParameterDescription("Vf [V]", "Reference voltage.\n" + 
   990               formula, voltage.Vf)
   991             }, settings);
   992           voltages.Add(sensor);
   993       }
   994 
   995       foreach (Temperature temperature in t) 
   996         if (temperature.Index < superIO.Temperatures.Length) {
   997         Sensor sensor = new Sensor(temperature.Name, temperature.Index,
   998           SensorType.Temperature, this, new [] {
   999           new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
  1000         }, settings);
  1001         temperatures.Add(sensor);
  1002       }
  1003 
  1004       foreach (Fan fan in f)
  1005         if (fan.Index < superIO.Fans.Length) {
  1006           Sensor sensor = new Sensor(fan.Name, fan.Index, SensorType.Fan,
  1007             this, settings);
  1008           fans.Add(sensor);
  1009         }
  1010 
  1011       foreach (Ctrl ctrl in c) {
  1012         int index = ctrl.Index;
  1013         if (index < superIO.Controls.Length) {
  1014           Sensor sensor = new Sensor(ctrl.Name, index, SensorType.Control,
  1015             this, settings);
  1016           Control control = new Control(sensor, settings, 0, 100);
  1017           control.ControlModeChanged += (cc) => {
  1018             if (cc.ControlMode == ControlMode.Default) {
  1019               superIO.SetControl(index, null);
  1020             } else {
  1021               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
  1022             }
  1023           };
  1024           control.SoftwareControlValueChanged += (cc) => {
  1025             if (cc.ControlMode == ControlMode.Software) 
  1026               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
  1027           };
  1028           if (control.ControlMode == ControlMode.Software) 
  1029             superIO.SetControl(index, (byte)(control.SoftwareValue * 2.55));
  1030           sensor.Control = control;
  1031           controls.Add(sensor);
  1032         }
  1033       }
  1034     }
  1035 
  1036     public override HardwareType HardwareType {
  1037       get { return HardwareType.SuperIO; }
  1038     }
  1039 
  1040     public override IHardware Parent {
  1041       get { return mainboard; }
  1042     }
  1043 
  1044 
  1045     public override string GetReport() {
  1046       return superIO.GetReport();
  1047     }
  1048 
  1049     public override void Update() {
  1050       superIO.Update();
  1051 
  1052       foreach (Sensor sensor in voltages) {
  1053         float? value = readVoltage(sensor.Index);
  1054         if (value.HasValue) {
  1055           sensor.Value = value + (value - sensor.Parameters[2].Value) *
  1056             sensor.Parameters[0].Value / sensor.Parameters[1].Value;
  1057           ActivateSensor(sensor);
  1058         }
  1059       }
  1060 
  1061       foreach (Sensor sensor in temperatures) {
  1062         float? value = readTemperature(sensor.Index);
  1063         if (value.HasValue) {
  1064           sensor.Value = value + sensor.Parameters[0].Value;
  1065           ActivateSensor(sensor);
  1066         }
  1067       }
  1068 
  1069       foreach (Sensor sensor in fans) {
  1070         float? value = readFan(sensor.Index);
  1071         if (value.HasValue) {
  1072           sensor.Value = value;
  1073           if (value.Value > 0)
  1074             ActivateSensor(sensor);
  1075         }
  1076       }
  1077 
  1078       foreach (Sensor sensor in controls) {
  1079         float? value = readControl(sensor.Index);
  1080         if (value.HasValue) {
  1081           sensor.Value = value;
  1082           ActivateSensor(sensor);
  1083         }
  1084       }
  1085 
  1086       postUpdate();
  1087     }
  1088 
  1089     public override void Close() {
  1090       foreach (Sensor sensor in controls) {
  1091         // restore all controls back to default
  1092         superIO.SetControl(sensor.Index, null);
  1093       }
  1094       base.Close();
  1095     }
  1096 
  1097     private class Voltage {
  1098       public readonly string Name;
  1099       public readonly int Index;
  1100       public readonly float Ri;
  1101       public readonly float Rf;
  1102       public readonly float Vf;
  1103       public readonly bool Hidden;
  1104 
  1105       public Voltage(string name, int index) :
  1106         this(name, index, false) { }
  1107       
  1108       public Voltage(string name, int index, bool hidden) :
  1109         this(name, index, 0, 1, 0, hidden) { }
  1110       
  1111       public Voltage(string name, int index, float ri, float rf) :
  1112         this(name, index, ri, rf, 0, false) { }
  1113       
  1114       // float ri = 0, float rf = 1, float vf = 0, bool hidden = false) 
  1115       
  1116       public Voltage(string name, int index, 
  1117         float ri, float rf, float vf, bool hidden) 
  1118       {
  1119         this.Name = name;
  1120         this.Index = index;
  1121         this.Ri = ri;
  1122         this.Rf = rf;
  1123         this.Vf = vf;
  1124         this.Hidden = hidden;
  1125       }
  1126     }
  1127 
  1128     private class Temperature {
  1129       public readonly string Name;
  1130       public readonly int Index;
  1131 
  1132       public Temperature(string name, int index) {
  1133         this.Name = name;
  1134         this.Index = index;
  1135       }
  1136     }
  1137 
  1138     private class Fan {
  1139       public readonly string Name;
  1140       public readonly int Index;
  1141 
  1142       public Fan(string name, int index) {
  1143         this.Name = name;
  1144         this.Index = index;
  1145       }
  1146     }
  1147 
  1148     private class Ctrl {
  1149       public readonly string Name;
  1150       public readonly int Index;
  1151 
  1152       public Ctrl(string name, int index) {
  1153         this.Name = name;
  1154         this.Index = index;
  1155       }
  1156     }
  1157   }
  1158 }