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