Hardware/Mainboard/SuperIOHardware.cs
author moel.mich
Sun, 15 Jan 2012 14:05:52 +0000
changeset 332 19b1e150e7af
parent 323 3f2d9ebacf38
child 336 1966500884bc
permissions -rw-r--r--
Added a mainboard specific configuration for the ASUS P9X79 (detailed fan and control configuration still missing).
     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.IT8772E:
   434           switch (manufacturer) {
   435             case Manufacturer.ECS:
   436               switch (model) {
   437                 case Model.A890GXM_A: // IT8721F
   438                   v.Add(new Voltage("CPU VCore", 0));
   439                   v.Add(new Voltage("VDIMM", 1));
   440                   v.Add(new Voltage("NB Voltage", 2));
   441                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10));
   442                   // v.Add(new Voltage("VDIMM", 6, true));
   443                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   444                   v.Add(new Voltage("VBat", 8, 10, 10));
   445                   t.Add(new Temperature("CPU", 0));
   446                   t.Add(new Temperature("System", 1));
   447                   t.Add(new Temperature("Northbridge", 2));
   448                   f.Add(new Fan("CPU Fan", 0));
   449                   f.Add(new Fan("System Fan", 1));
   450                   f.Add(new Fan("Power Fan", 2));
   451                   break;
   452                 default:
   453                   v.Add(new Voltage("Voltage #1", 0, true));
   454                   v.Add(new Voltage("Voltage #2", 1, true));
   455                   v.Add(new Voltage("Voltage #3", 2, true));
   456                   v.Add(new Voltage("Analog +3.3V", 3, 10, 10, 0, true));
   457                   v.Add(new Voltage("Voltage #5", 4, true));
   458                   v.Add(new Voltage("Voltage #6", 5, true));
   459                   v.Add(new Voltage("Voltage #7", 6, true));
   460                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   461                   v.Add(new Voltage("VBat", 8, 10, 10));
   462                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   463                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   464                   for (int i = 0; i < superIO.Fans.Length; i++)
   465                     f.Add(new Fan("Fan #" + (i + 1), i));
   466                   break;
   467               }
   468               break;
   469             case Manufacturer.Gigabyte:
   470               switch (model) {
   471                 case Model.P67A_UD4_B3: // IT8728F
   472                   v.Add(new Voltage("+12V", 0, 100, 10));
   473                   v.Add(new Voltage("+5V", 1, 15, 10));
   474                   v.Add(new Voltage("Voltage #3", 2, true));
   475                   v.Add(new Voltage("Voltage #4", 3, true));
   476                   v.Add(new Voltage("Voltage #5", 4, true));
   477                   v.Add(new Voltage("CPU VCore", 5));
   478                   v.Add(new Voltage("DRAM", 6));
   479                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   480                   v.Add(new Voltage("VBat", 8, 10, 10));
   481                   t.Add(new Temperature("System", 0));
   482                   t.Add(new Temperature("CPU", 2));
   483                   f.Add(new Fan("CPU Fan", 0));
   484                   f.Add(new Fan("System Fan #2", 1));
   485                   f.Add(new Fan("Power Fan", 2));
   486                   f.Add(new Fan("System Fan #1", 3));
   487                   break;
   488                 case Model.H67A_UD3H_B3: // IT8728F
   489                   v.Add(new Voltage("VTT", 0));
   490                   v.Add(new Voltage("+5V", 1, 15, 10));
   491                   v.Add(new Voltage("+12V", 2, 68, 22));
   492                   v.Add(new Voltage("Voltage #4", 3, true));
   493                   v.Add(new Voltage("Voltage #5", 4, true));
   494                   v.Add(new Voltage("CPU VCore", 5));
   495                   v.Add(new Voltage("DRAM", 6));
   496                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   497                   v.Add(new Voltage("VBat", 8, 10, 10));
   498                   t.Add(new Temperature("System", 0));
   499                   t.Add(new Temperature("CPU", 2));
   500                   f.Add(new Fan("CPU Fan", 0));
   501                   f.Add(new Fan("System Fan #1", 1));
   502                   f.Add(new Fan("Power Fan", 2));
   503                   f.Add(new Fan("System Fan #2", 3));
   504                   break;
   505                 case Model.Z68X_UD7_B3: // IT8728F
   506                   v.Add(new Voltage("VTT", 0));
   507                   v.Add(new Voltage("+3.3V", 1, 13.3f, 20.5f));
   508                   v.Add(new Voltage("+12V", 2, 68, 22));
   509                   v.Add(new Voltage("+5V", 3, 14.3f, 20));
   510                   v.Add(new Voltage("CPU VCore", 5));
   511                   v.Add(new Voltage("DRAM", 6));
   512                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   513                   v.Add(new Voltage("VBat", 8, 10, 10));
   514                   t.Add(new Temperature("System", 0));
   515                   t.Add(new Temperature("CPU", 1));
   516                   t.Add(new Temperature("System 3", 2));
   517                   f.Add(new Fan("CPU Fan", 0));
   518                   f.Add(new Fan("Power Fan", 1));
   519                   f.Add(new Fan("System Fan #1", 2));
   520                   f.Add(new Fan("System Fan #2", 3));
   521                   f.Add(new Fan("System Fan #3", 4));
   522                   break;
   523                 default:
   524                   v.Add(new Voltage("Voltage #1", 0, true));
   525                   v.Add(new Voltage("Voltage #2", 1, true));
   526                   v.Add(new Voltage("Voltage #3", 2, true));
   527                   v.Add(new Voltage("Voltage #4", 3, true));
   528                   v.Add(new Voltage("Voltage #5", 4, true));
   529                   v.Add(new Voltage("Voltage #6", 5, true));
   530                   v.Add(new Voltage("Voltage #7", 6, true));
   531                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   532                   v.Add(new Voltage("VBat", 8, 10, 10));
   533                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   534                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   535                   for (int i = 0; i < superIO.Fans.Length; i++)
   536                     f.Add(new Fan("Fan #" + (i + 1), i));
   537                   break;
   538               }
   539               break;
   540             case Manufacturer.Shuttle:
   541               switch (model) {
   542                 case Model.FH67: // IT8772E 
   543                   v.Add(new Voltage("CPU VCore", 0));
   544                   v.Add(new Voltage("DRAM", 1));
   545                   v.Add(new Voltage("PCH VCCIO", 2));
   546                   v.Add(new Voltage("CPU VCCIO", 3));
   547                   v.Add(new Voltage("Graphic Voltage", 4));
   548                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10));
   549                   v.Add(new Voltage("VBat", 8, 10, 10));
   550                   t.Add(new Temperature("System", 0));
   551                   t.Add(new Temperature("CPU", 1));                  
   552                   f.Add(new Fan("Fan #1", 0));
   553                   f.Add(new Fan("CPU Fan", 1));
   554                   break;
   555                 default:
   556                   v.Add(new Voltage("Voltage #1", 0, true));
   557                   v.Add(new Voltage("Voltage #2", 1, true));
   558                   v.Add(new Voltage("Voltage #3", 2, true));
   559                   v.Add(new Voltage("Voltage #4", 3, true));
   560                   v.Add(new Voltage("Voltage #5", 4, true));
   561                   v.Add(new Voltage("Voltage #6", 5, true));
   562                   v.Add(new Voltage("Voltage #7", 6, true));
   563                   v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   564                   v.Add(new Voltage("VBat", 8, 10, 10));
   565                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   566                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   567                   for (int i = 0; i < superIO.Fans.Length; i++)
   568                     f.Add(new Fan("Fan #" + (i + 1), i));
   569                   break;
   570               }
   571               break;
   572             default:
   573               v.Add(new Voltage("Voltage #1", 0, true));
   574               v.Add(new Voltage("Voltage #2", 1, true));
   575               v.Add(new Voltage("Voltage #3", 2, true));
   576               v.Add(new Voltage("Voltage #4", 3, true));
   577               v.Add(new Voltage("Voltage #5", 4, true));
   578               v.Add(new Voltage("Voltage #6", 5, true));
   579               v.Add(new Voltage("Voltage #7", 6, true));
   580               v.Add(new Voltage("Standby +3.3V", 7, 10, 10, 0, true));
   581               v.Add(new Voltage("VBat", 8, 10, 10));
   582               for (int i = 0; i < superIO.Temperatures.Length; i++)
   583                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   584               for (int i = 0; i < superIO.Fans.Length; i++)
   585                 f.Add(new Fan("Fan #" + (i + 1), i));
   586               break;
   587           }
   588           break;
   589           
   590         case Chip.F71858:
   591           v.Add(new Voltage("VCC3V", 0, 150, 150));
   592           v.Add(new Voltage("VSB3V", 1, 150, 150));
   593           v.Add(new Voltage("Battery", 2, 150, 150));
   594           for (int i = 0; i < superIO.Temperatures.Length; i++)
   595             t.Add(new Temperature("Temperature #" + (i + 1), i));
   596           for (int i = 0; i < superIO.Fans.Length; i++)
   597             f.Add(new Fan("Fan #" + (i + 1), i));
   598           break;
   599         case Chip.F71862: 
   600         case Chip.F71869: 
   601         case Chip.F71882:
   602         case Chip.F71889AD: 
   603         case Chip.F71889ED: 
   604         case Chip.F71889F:
   605           switch (manufacturer) {
   606             case Manufacturer.EVGA:
   607               switch (model) {
   608                 case Model.X58_SLI_Classified: // F71882 
   609                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   610                   v.Add(new Voltage("CPU VCore", 1, 47, 100));
   611                   v.Add(new Voltage("DIMM", 2, 47, 100));
   612                   v.Add(new Voltage("CPU VTT", 3, 24, 100));
   613                   v.Add(new Voltage("IOH Vcore", 4, 24, 100));
   614                   v.Add(new Voltage("+5V", 5, 51, 12));
   615                   v.Add(new Voltage("+12V", 6, 56, 6.8f));
   616                   v.Add(new Voltage("3VSB", 7, 150, 150));
   617                   v.Add(new Voltage("VBat", 8, 150, 150));
   618                   t.Add(new Temperature("CPU", 0));
   619                   t.Add(new Temperature("VREG", 1));
   620                   t.Add(new Temperature("System", 2));
   621                   f.Add(new Fan("CPU Fan", 0));
   622                   f.Add(new Fan("Power Fan", 1));
   623                   f.Add(new Fan("Chassis Fan", 2));
   624                   break;
   625                 default:
   626                   v.Add(new Voltage("VCC3V", 0, 150, 150));
   627                   v.Add(new Voltage("CPU VCore", 1));
   628                   v.Add(new Voltage("Voltage #3", 2, true));
   629                   v.Add(new Voltage("Voltage #4", 3, true));
   630                   v.Add(new Voltage("Voltage #5", 4, true));
   631                   v.Add(new Voltage("Voltage #6", 5, true));
   632                   v.Add(new Voltage("Voltage #7", 6, true));
   633                   v.Add(new Voltage("VSB3V", 7, 150, 150));
   634                   v.Add(new Voltage("VBat", 8, 150, 150));
   635                   for (int i = 0; i < superIO.Temperatures.Length; i++)
   636                     t.Add(new Temperature("Temperature #" + (i + 1), i));
   637                   for (int i = 0; i < superIO.Fans.Length; i++)
   638                     f.Add(new Fan("Fan #" + (i + 1), i));
   639                   break;
   640               }
   641               break;
   642             default:
   643               v.Add(new Voltage("VCC3V", 0, 150, 150));
   644               v.Add(new Voltage("CPU VCore", 1));
   645               v.Add(new Voltage("Voltage #3", 2, true));
   646               v.Add(new Voltage("Voltage #4", 3, true));
   647               v.Add(new Voltage("Voltage #5", 4, true));
   648               v.Add(new Voltage("Voltage #6", 5, true));
   649               v.Add(new Voltage("Voltage #7", 6, true));
   650               v.Add(new Voltage("VSB3V", 7, 150, 150));
   651               v.Add(new Voltage("VBat", 8, 150, 150));
   652               for (int i = 0; i < superIO.Temperatures.Length; i++)
   653                 t.Add(new Temperature("Temperature #" + (i + 1), i));
   654               for (int i = 0; i < superIO.Fans.Length; i++)
   655                 f.Add(new Fan("Fan #" + (i + 1), i));
   656               break;
   657           }
   658           break;
   659 
   660         case Chip.W83627EHF:
   661           switch (manufacturer) {
   662             case Manufacturer.ASRock:
   663               switch (model) {
   664                 case Model.AOD790GX_128M: // W83627EHF
   665                   v.Add(new Voltage("CPU VCore", 0));
   666                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   667                   v.Add(new Voltage("+3.3V", 4, 10, 10));
   668                   v.Add(new Voltage("+5V", 5, 20, 10));
   669                   v.Add(new Voltage("+12V", 6, 28, 5));
   670                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   671                   v.Add(new Voltage("VBAT", 8, 34, 34));
   672                   t.Add(new Temperature("CPU", 0));
   673                   t.Add(new Temperature("Motherboard", 2));
   674                   f.Add(new Fan("CPU Fan", 0));
   675                   f.Add(new Fan("Chassis Fan", 1));                 
   676                   break;
   677                 default:
   678                   v.Add(new Voltage("CPU VCore", 0));
   679                   v.Add(new Voltage("Voltage #2", 1, true));
   680                   v.Add(new Voltage("AVCC", 2, 34, 34));
   681                   v.Add(new Voltage("3VCC", 3, 34, 34));
   682                   v.Add(new Voltage("Voltage #5", 4, true));
   683                   v.Add(new Voltage("Voltage #6", 5, true));
   684                   v.Add(new Voltage("Voltage #7", 6, true));
   685                   v.Add(new Voltage("3VSB", 7, 34, 34));
   686                   v.Add(new Voltage("VBAT", 8, 34, 34));
   687                   v.Add(new Voltage("Voltage #10", 9, true));
   688                   t.Add(new Temperature("CPU", 0));
   689                   t.Add(new Temperature("Auxiliary", 1));
   690                   t.Add(new Temperature("System", 2));
   691                   f.Add(new Fan("System Fan", 0));
   692                   f.Add(new Fan("CPU Fan", 1));
   693                   f.Add(new Fan("Auxiliary Fan", 2));
   694                   f.Add(new Fan("CPU Fan #2", 3));
   695                   f.Add(new Fan("Auxiliary Fan #2", 4));
   696                   break;
   697               } break;
   698             default:
   699               v.Add(new Voltage("CPU VCore", 0));
   700               v.Add(new Voltage("Voltage #2", 1, true));
   701               v.Add(new Voltage("AVCC", 2, 34, 34));
   702               v.Add(new Voltage("3VCC", 3, 34, 34));
   703               v.Add(new Voltage("Voltage #5", 4, true));
   704               v.Add(new Voltage("Voltage #6", 5, true));
   705               v.Add(new Voltage("Voltage #7", 6, true));
   706               v.Add(new Voltage("3VSB", 7, 34, 34));
   707               v.Add(new Voltage("VBAT", 8, 34, 34));
   708               v.Add(new Voltage("Voltage #10", 9, true));
   709               t.Add(new Temperature("CPU", 0));
   710               t.Add(new Temperature("Auxiliary", 1));
   711               t.Add(new Temperature("System", 2));
   712               f.Add(new Fan("System Fan", 0));
   713               f.Add(new Fan("CPU Fan", 1));
   714               f.Add(new Fan("Auxiliary Fan", 2));
   715               f.Add(new Fan("CPU Fan #2", 3));
   716               f.Add(new Fan("Auxiliary Fan #2", 4));
   717               break;
   718           }
   719           break;
   720         case Chip.W83627DHG: 
   721         case Chip.W83627DHGP:                      
   722         case Chip.W83667HG:
   723         case Chip.W83667HGB:
   724           switch (manufacturer) {
   725             case Manufacturer.ASRock:
   726               switch (model) {
   727                 case Model._880GMH_USB3: // W83627DHG-P
   728                   v.Add(new Voltage("CPU VCore", 0));
   729                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   730                   v.Add(new Voltage("+5V", 5, 15, 7.5f));
   731                   v.Add(new Voltage("+12V", 6, 56, 10));
   732                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   733                   v.Add(new Voltage("VBAT", 8, 34, 34));
   734                   t.Add(new Temperature("CPU", 0));
   735                   t.Add(new Temperature("Motherboard", 2));
   736                   f.Add(new Fan("Chassis Fan", 0));
   737                   f.Add(new Fan("CPU Fan", 1));
   738                   f.Add(new Fan("Power Fan", 2));
   739                   break;
   740                 default:
   741                   v.Add(new Voltage("CPU VCore", 0));
   742                   v.Add(new Voltage("Voltage #2", 1, true));
   743                   v.Add(new Voltage("AVCC", 2, 34, 34));
   744                   v.Add(new Voltage("3VCC", 3, 34, 34));
   745                   v.Add(new Voltage("Voltage #5", 4, true));
   746                   v.Add(new Voltage("Voltage #6", 5, true));
   747                   v.Add(new Voltage("Voltage #7", 6, true));
   748                   v.Add(new Voltage("3VSB", 7, 34, 34));
   749                   v.Add(new Voltage("VBAT", 8, 34, 34));
   750                   t.Add(new Temperature("CPU", 0));
   751                   t.Add(new Temperature("Auxiliary", 1));
   752                   t.Add(new Temperature("System", 2));
   753                   f.Add(new Fan("System Fan", 0));
   754                   f.Add(new Fan("CPU Fan", 1));
   755                   f.Add(new Fan("Auxiliary Fan", 2));
   756                   f.Add(new Fan("CPU Fan #2", 3));
   757                   f.Add(new Fan("Auxiliary Fan #2", 4));
   758                   break;
   759               }
   760               break;
   761             case Manufacturer.ASUS:
   762               switch (model) {
   763                 case Model.P6X58D_E: // W83667HG                 
   764                 case Model.Rampage_II_GENE: // W83667HG 
   765                   v.Add(new Voltage("CPU VCore", 0));
   766                   v.Add(new Voltage("+12V", 1, 11.5f, 1.91f));
   767                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   768                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   769                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   770                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   771                   v.Add(new Voltage("VBAT", 8, 34, 34));
   772                   t.Add(new Temperature("CPU", 0));
   773                   t.Add(new Temperature("Motherboard", 2));
   774                   f.Add(new Fan("Chassis Fan #1", 0));
   775                   f.Add(new Fan("CPU Fan", 1));
   776                   f.Add(new Fan("Power Fan", 2));
   777                   f.Add(new Fan("Chassis Fan #2", 3));
   778                   f.Add(new Fan("Chassis Fan #3", 4));
   779                   break;
   780                 case Model.Rampage_Extreme: // W83667HG 
   781                   v.Add(new Voltage("CPU VCore", 0));
   782                   v.Add(new Voltage("+12V", 1, 12, 2));
   783                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   784                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   785                   v.Add(new Voltage("+5V", 4, 15, 7.5f));
   786                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   787                   v.Add(new Voltage("VBAT", 8, 34, 34));
   788                   t.Add(new Temperature("CPU", 0));
   789                   t.Add(new Temperature("Motherboard", 2));
   790                   f.Add(new Fan("Chassis Fan #1", 0));
   791                   f.Add(new Fan("CPU Fan", 1));
   792                   f.Add(new Fan("Power Fan", 2));
   793                   f.Add(new Fan("Chassis Fan #2", 3));
   794                   f.Add(new Fan("Chassis Fan #3", 4));
   795                   break;
   796                 default:
   797                   v.Add(new Voltage("CPU VCore", 0));
   798                   v.Add(new Voltage("Voltage #2", 1, true));
   799                   v.Add(new Voltage("AVCC", 2, 34, 34));
   800                   v.Add(new Voltage("3VCC", 3, 34, 34));
   801                   v.Add(new Voltage("Voltage #5", 4, true));
   802                   v.Add(new Voltage("Voltage #6", 5, true));
   803                   v.Add(new Voltage("Voltage #7", 6, true));
   804                   v.Add(new Voltage("3VSB", 7, 34, 34));
   805                   v.Add(new Voltage("VBAT", 8, 34, 34));
   806                   t.Add(new Temperature("CPU", 0));
   807                   t.Add(new Temperature("Auxiliary", 1));
   808                   t.Add(new Temperature("System", 2));
   809                   f.Add(new Fan("System Fan", 0));
   810                   f.Add(new Fan("CPU Fan", 1));
   811                   f.Add(new Fan("Auxiliary Fan", 2));
   812                   f.Add(new Fan("CPU Fan #2", 3));
   813                   f.Add(new Fan("Auxiliary Fan #2", 4));
   814                   break;
   815               }
   816               break;
   817             default:
   818               v.Add(new Voltage("CPU VCore", 0));
   819               v.Add(new Voltage("Voltage #2", 1, true));
   820               v.Add(new Voltage("AVCC", 2, 34, 34));
   821               v.Add(new Voltage("3VCC", 3, 34, 34));
   822               v.Add(new Voltage("Voltage #5", 4, true));
   823               v.Add(new Voltage("Voltage #6", 5, true));
   824               v.Add(new Voltage("Voltage #7", 6, true));
   825               v.Add(new Voltage("3VSB", 7, 34, 34));
   826               v.Add(new Voltage("VBAT", 8, 34, 34));
   827               t.Add(new Temperature("CPU", 0));
   828               t.Add(new Temperature("Auxiliary", 1));
   829               t.Add(new Temperature("System", 2));
   830               f.Add(new Fan("System Fan", 0));
   831               f.Add(new Fan("CPU Fan", 1));
   832               f.Add(new Fan("Auxiliary Fan", 2));
   833               f.Add(new Fan("CPU Fan #2", 3));
   834               f.Add(new Fan("Auxiliary Fan #2", 4));
   835               break;
   836           } 
   837           break;
   838         case Chip.W83627HF: 
   839         case Chip.W83627THF: 
   840         case Chip.W83687THF:
   841           v.Add(new Voltage("CPU VCore", 0));
   842           v.Add(new Voltage("Voltage #2", 1, true));
   843           v.Add(new Voltage("Voltage #3", 2, true));
   844           v.Add(new Voltage("AVCC", 3, 34, 51));
   845           v.Add(new Voltage("Voltage #5", 4, true));
   846           v.Add(new Voltage("5VSB", 5, 34, 51));
   847           v.Add(new Voltage("VBAT", 6));
   848           t.Add(new Temperature("CPU", 0));
   849           t.Add(new Temperature("Auxiliary", 1));
   850           t.Add(new Temperature("System", 2));
   851           f.Add(new Fan("System Fan", 0));
   852           f.Add(new Fan("CPU Fan", 1));
   853           f.Add(new Fan("Auxiliary Fan", 2));
   854           break;
   855         case Chip.NCT6771F:
   856         case Chip.NCT6776F:
   857           switch (manufacturer) {
   858             case Manufacturer.ASUS:
   859               switch (model) {
   860                 case Model.P8P67: // NCT6776F
   861                 case Model.P8P67_EVO: // NCT6776F
   862                 case Model.P8P67_PRO: // NCT6776F
   863                   v.Add(new Voltage("CPU VCore", 0));
   864                   v.Add(new Voltage("+12V", 1, 11, 1));
   865                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   866                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   867                   v.Add(new Voltage("+5V", 4, 12, 3));
   868                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   869                   v.Add(new Voltage("VBAT", 8, 34, 34));
   870                   t.Add(new Temperature("CPU", 0));
   871                   t.Add(new Temperature("Auxiliary", 2));
   872                   t.Add(new Temperature("Motherboard", 3));
   873                   f.Add(new Fan("Chassis Fan #1", 0));
   874                   f.Add(new Fan("CPU Fan", 1));
   875                   f.Add(new Fan("Power Fan", 2));
   876                   f.Add(new Fan("Chassis Fan #2", 3));
   877                   c.Add(new Ctrl("Chassis Fan #2", 0));
   878                   c.Add(new Ctrl("CPU Fan", 1));
   879                   c.Add(new Ctrl("Chassis Fan #1", 2));
   880                   break;
   881                 case Model.P8P67_M_PRO: // NCT6776F
   882                   v.Add(new Voltage("CPU VCore", 0));
   883                   v.Add(new Voltage("+12V", 1, 11, 1));
   884                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   885                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   886                   v.Add(new Voltage("+5V", 4, 12, 3));
   887                   v.Add(new Voltage("Voltage #6", 5, true));
   888                   v.Add(new Voltage("Voltage #7", 6, true));
   889                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   890                   v.Add(new Voltage("VBAT", 8, 34, 34));
   891                   t.Add(new Temperature("CPU", 0));
   892                   t.Add(new Temperature("Motherboard", 3));
   893                   f.Add(new Fan("Chassis Fan #1", 0));
   894                   f.Add(new Fan("CPU Fan", 1));
   895                   f.Add(new Fan("Chassis Fan #2", 2));
   896                   f.Add(new Fan("Power Fan", 3));
   897                   f.Add(new Fan("Auxiliary Fan", 4));
   898                   break;
   899                 case Model.P9X79: // NCT6776F
   900                   v.Add(new Voltage("CPU VCore", 0));
   901                   v.Add(new Voltage("+12V", 1, 11, 1));
   902                   v.Add(new Voltage("Analog +3.3V", 2, 34, 34));
   903                   v.Add(new Voltage("+3.3V", 3, 34, 34));
   904                   v.Add(new Voltage("+5V", 4, 12, 3));
   905                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34));
   906                   v.Add(new Voltage("VBAT", 8, 34, 34));
   907                   t.Add(new Temperature("CPU", 0));
   908                   t.Add(new Temperature("Motherboard", 3));
   909                   for (int i = 0; i < superIO.Fans.Length; i++)
   910                     f.Add(new Fan("Fan #" + (i + 1), i));
   911                   break;
   912                 default:
   913                   v.Add(new Voltage("CPU VCore", 0));
   914                   v.Add(new Voltage("Voltage #2", 1, true));
   915                   v.Add(new Voltage("AVCC", 2, 34, 34));
   916                   v.Add(new Voltage("3VCC", 3, 34, 34));
   917                   v.Add(new Voltage("Voltage #5", 4, true));
   918                   v.Add(new Voltage("Voltage #6", 5, true));
   919                   v.Add(new Voltage("Voltage #7", 6, true));
   920                   v.Add(new Voltage("3VSB", 7, 34, 34));
   921                   v.Add(new Voltage("VBAT", 8, 34, 34));
   922                   t.Add(new Temperature("CPU", 0));
   923                   t.Add(new Temperature("CPU", 1));
   924                   t.Add(new Temperature("Auxiliary", 2));
   925                   t.Add(new Temperature("System", 3));
   926                   for (int i = 0; i < superIO.Fans.Length; i++)
   927                     f.Add(new Fan("Fan #" + (i + 1), i));
   928                   break;
   929               }
   930               break;
   931             default:
   932               v.Add(new Voltage("CPU VCore", 0));
   933               v.Add(new Voltage("Voltage #2", 1, true));
   934               v.Add(new Voltage("AVCC", 2, 34, 34));
   935               v.Add(new Voltage("3VCC", 3, 34, 34));
   936               v.Add(new Voltage("Voltage #5", 4, true));
   937               v.Add(new Voltage("Voltage #6", 5, true));
   938               v.Add(new Voltage("Voltage #7", 6, true));
   939               v.Add(new Voltage("3VSB", 7, 34, 34));
   940               v.Add(new Voltage("VBAT", 8, 34, 34));
   941               t.Add(new Temperature("CPU", 0));
   942               t.Add(new Temperature("CPU", 1));
   943               t.Add(new Temperature("Auxiliary", 2));
   944               t.Add(new Temperature("System", 3));
   945               for (int i = 0; i < superIO.Fans.Length; i++)
   946                 f.Add(new Fan("Fan #" + (i + 1), i));
   947               break;
   948           }
   949           break;
   950         default:
   951           for (int i = 0; i < superIO.Voltages.Length; i++)
   952             v.Add(new Voltage("Voltage #" + (i + 1), i, true));
   953           for (int i = 0; i < superIO.Temperatures.Length; i++)
   954             t.Add(new Temperature("Temperature #" + (i + 1), i));
   955           for (int i = 0; i < superIO.Fans.Length; i++)
   956             f.Add(new Fan("Fan #" + (i + 1), i));
   957           for (int i = 0; i < superIO.Controls.Length; i++)
   958             c.Add(new Ctrl("Fan Control #" + (i + 1), i));
   959           break;
   960       }
   961 
   962       const string formula = "Voltage = value + (value - Vf) * Ri / Rf.";
   963       foreach (Voltage voltage in v) 
   964         if (voltage.Index < superIO.Voltages.Length) {
   965           Sensor sensor = new Sensor(voltage.Name, voltage.Index, 
   966             voltage.Hidden, SensorType.Voltage, this, new [] {
   967             new ParameterDescription("Ri [kΩ]", "Input resistance.\n" + 
   968               formula, voltage.Ri),
   969             new ParameterDescription("Rf [kΩ]", "Reference resistance.\n" + 
   970               formula, voltage.Rf),
   971             new ParameterDescription("Vf [V]", "Reference voltage.\n" + 
   972               formula, voltage.Vf)
   973             }, settings);
   974           voltages.Add(sensor);
   975       }
   976 
   977       foreach (Temperature temperature in t) 
   978         if (temperature.Index < superIO.Temperatures.Length) {
   979         Sensor sensor = new Sensor(temperature.Name, temperature.Index,
   980           SensorType.Temperature, this, new [] {
   981           new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
   982         }, settings);
   983         temperatures.Add(sensor);
   984       }
   985 
   986       foreach (Fan fan in f)
   987         if (fan.Index < superIO.Fans.Length) {
   988           Sensor sensor = new Sensor(fan.Name, fan.Index, SensorType.Fan,
   989             this, settings);
   990           fans.Add(sensor);
   991         }
   992 
   993       foreach (Ctrl ctrl in c) {
   994         int index = ctrl.Index;
   995         if (index < superIO.Controls.Length) {
   996           Sensor sensor = new Sensor(ctrl.Name, index, SensorType.Control,
   997             this, settings);
   998           Control control = new Control(sensor, settings, 0, 100);
   999           control.ControlModeChanged += (cc) => {
  1000             if (cc.ControlMode == ControlMode.Default) {
  1001               superIO.SetControl(index, null);
  1002             } else {
  1003               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
  1004             }
  1005           };
  1006           control.SoftwareControlValueChanged += (cc) => {
  1007             if (cc.ControlMode == ControlMode.Software) 
  1008               superIO.SetControl(index, (byte)(cc.SoftwareValue * 2.55));
  1009           };
  1010           if (control.ControlMode == ControlMode.Software) 
  1011             superIO.SetControl(index, (byte)(control.SoftwareValue * 2.55));
  1012           sensor.Control = control;
  1013           controls.Add(sensor);
  1014         }
  1015       }
  1016     }
  1017 
  1018     public override HardwareType HardwareType {
  1019       get { return HardwareType.SuperIO; }
  1020     }
  1021 
  1022     public override IHardware Parent {
  1023       get { return mainboard; }
  1024     }
  1025 
  1026 
  1027     public override string GetReport() {
  1028       return superIO.GetReport();
  1029     }
  1030 
  1031     public override void Update() {
  1032       superIO.Update();
  1033 
  1034       foreach (Sensor sensor in voltages) {
  1035         float? value = readVoltage(sensor.Index);
  1036         if (value.HasValue) {
  1037           sensor.Value = value + (value - sensor.Parameters[2].Value) *
  1038             sensor.Parameters[0].Value / sensor.Parameters[1].Value;
  1039           ActivateSensor(sensor);
  1040         }
  1041       }
  1042 
  1043       foreach (Sensor sensor in temperatures) {
  1044         float? value = readTemperature(sensor.Index);
  1045         if (value.HasValue) {
  1046           sensor.Value = value + sensor.Parameters[0].Value;
  1047           ActivateSensor(sensor);
  1048         }
  1049       }
  1050 
  1051       foreach (Sensor sensor in fans) {
  1052         float? value = readFan(sensor.Index);
  1053         if (value.HasValue) {
  1054           sensor.Value = value;
  1055           if (value.Value > 0)
  1056             ActivateSensor(sensor);
  1057         }
  1058       }
  1059 
  1060       foreach (Sensor sensor in controls) {
  1061         float? value = readControl(sensor.Index);
  1062         if (value.HasValue) {
  1063           sensor.Value = value;
  1064           ActivateSensor(sensor);
  1065         }
  1066       }
  1067 
  1068       postUpdate();
  1069     }
  1070 
  1071     public override void Close() {
  1072       foreach (Sensor sensor in controls) {
  1073         // restore all controls back to default
  1074         superIO.SetControl(sensor.Index, null);
  1075       }
  1076       base.Close();
  1077     }
  1078 
  1079     private class Voltage {
  1080       public readonly string Name;
  1081       public readonly int Index;
  1082       public readonly float Ri;
  1083       public readonly float Rf;
  1084       public readonly float Vf;
  1085       public readonly bool Hidden;
  1086 
  1087       public Voltage(string name, int index) :
  1088         this(name, index, false) { }
  1089       
  1090       public Voltage(string name, int index, bool hidden) :
  1091         this(name, index, 0, 1, 0, hidden) { }
  1092       
  1093       public Voltage(string name, int index, float ri, float rf) :
  1094         this(name, index, ri, rf, 0, false) { }
  1095       
  1096       // float ri = 0, float rf = 1, float vf = 0, bool hidden = false) 
  1097       
  1098       public Voltage(string name, int index, 
  1099         float ri, float rf, float vf, bool hidden) 
  1100       {
  1101         this.Name = name;
  1102         this.Index = index;
  1103         this.Ri = ri;
  1104         this.Rf = rf;
  1105         this.Vf = vf;
  1106         this.Hidden = hidden;
  1107       }
  1108     }
  1109 
  1110     private class Temperature {
  1111       public readonly string Name;
  1112       public readonly int Index;
  1113 
  1114       public Temperature(string name, int index) {
  1115         this.Name = name;
  1116         this.Index = index;
  1117       }
  1118     }
  1119 
  1120     private class Fan {
  1121       public readonly string Name;
  1122       public readonly int Index;
  1123 
  1124       public Fan(string name, int index) {
  1125         this.Name = name;
  1126         this.Index = index;
  1127       }
  1128     }
  1129 
  1130     private class Ctrl {
  1131       public readonly string Name;
  1132       public readonly int Index;
  1133 
  1134       public Ctrl(string name, int index) {
  1135         this.Name = name;
  1136         this.Index = index;
  1137       }
  1138     }
  1139   }
  1140 }